개발하는 삶

[Spring] 스프링과 서블릿, 바인딩 본문

Spring

[Spring] 스프링과 서블릿, 바인딩

삶_ 2022. 8. 24. 16:26




스프링프로젝트 vs 서블릿 프로젝트 차이


스프링 프로젝트 기준

  • webapp : js, html, css 넣는곡
  • WEB-INF : jsp 넣는곳. 보안구역.
    • 원래 여기는 못들어가는 곳인데 스프링 컨트롤러가 빈으로 설정해서 가게해줌


서블릿 프로젝트 기준

  • 컨트롤러가 없기 때문에 WEB-INF 안에다 넣으면 인식이 안됨.
  • WEB-INF 밖에다 jsp 등 넣기!



포워딩 기능


서블릿 포워드 기능

  • 하나의 서블릿에서 다른 서블릿이나 JSP와 연동하는 방법


redirect를 이용한 포워딩

  • redirect 방법은 서블릿의 요청이 클라이언트의 웹브라우저를 다시 거쳐 요청되는 방식
  • HttpServletResponse 객체의 sendRedirect() 메서드를 이용
package sec01.ex01;

@WebServlet("/first")
public class FirstServlet extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		System.out.println("/first doget 실행");
		System.out.println(request.getParameter("a"));
		
		// 이 메서드를 이용해 다른 서블릿인 second로 재요청함
		response.sendRedirect("second");
	}
}
package sec01.ex01;

@WebServlet("/second")
public class SecondServlet extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		System.out.println("/second doget 실행");
		System.out.println(request.getParameter("a"));
		
		out.println("주소창을 확인해보세요.");	
	}
}





바인딩

  • 서블릿에서 다른 서블릿/jsp 등으로 대량의 데이터를 공유, 전달 시 사용하는 기능
  • 두개를 하나로 묶는다는 의미
  • HttpServletRequest, HttpSession, ServletContent 등에서 쓰임
  • 메서드
    • setAttribute(String name, Object obj) : 데이터를 각 객체에 바인딩함
    • getAttribute(String name) : 각 객체에 바인딩된 데이터를 name으로 가져옴
    • removeAttribute(String name) : 각 객체에 바인딩된 데이터를 name으로 제거함




HttpServletRequest를 이용한 dispatch 포워딩 시 바인딩

  • 대용량 관리일수록 redirect보다는 dispatch 사용하기!
package sec04.ex01;

@WebServlet("/first4")
public class FirstServlet extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");

		// 요청한 request 객체에 address 이름의 값으로 "서울시" 를 넣어줌
		request.setAttribute("address", "서울시");
		// 다른 서블릿을 호출
		// redirect 방식 포워드 과정은 서블릿에서 바인딩한 데이터를 다른 서블릿으로 전송할 수 없다 (null 뜸)
		// get 방식으로 전송은 가능하나, 데이터의 용량이 커지면 커질수록 효율적이지 않은 방법
  		//response.sendRedirect("second4");
		RequestDispatcher dispatch = request.getRequestDispatcher("second4");
		dispatch.forward(request, response);
		
		System.out.println("/first4 doget 실행");
		
	}
}
package sec04.ex01;

@WebServlet("/second4")
public class SecondServlet extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		
		System.out.println("/second4 doget 실행");
		// 전달된 요청에서 아래 메서드를 이용해, address의 값을 가져옴
		String address = (String) request.getAttribute("address");
		out.println("<html><body>");
		out.println("주소:"+address);
		out.println("<br>");
		out.println("redirect를 이용한 바인딩 실습");
		out.println("</body></html>");
		
	}
}



ServletContext

  • 각 context(웹 어플리케이션)마다 한개의 ServletContext 객체 생성
  • 톰캣 실행 후, 웹 어플리케이션 내 공통자원을 미리 바인딩해서 서블릿들이 공유함


ServletContext 의 바인딩 기능

  • cset 실행 → cget 실행 시 객체가 전달됨
  • cset 이 선행이 되어야 cget 이 뜸!
package sec05.ex01;

@WebServlet("/cset")
public class SetServletContext extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		System.out.println("/cset doGet 실행");

		ServletContext context = getServletContext();
		List member = new ArrayList();
		member.add("이순신");
		member.add(30);
		context.setAttribute("member", member);
		
		out.print("<html><body>");
		out.print("이순신과 30 설정");
		out.print("</body></html>");
		
	}
}
package sec05.ex01;

@WebServlet("/cget")
public class GetServletContext extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		System.out.println("/cset doGet 실행");

		ServletContext context = getServletContext();
		List member = (ArrayList)context.getAttribute("member");
		String name = (String) member.get(0);
		int age = (Integer)member.get(1);
		context.setAttribute("member", member);
		
		out.print("<html><body>");
		out.print(name+"<br>");
		out.print(age+"<br>");
		out.print("</body></html>");
		
	}
}





ServletContext의 매개변수 설정기능

package sec05.ex02;

@WebServlet("/initMenu")
public class ContextParamServlet extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		
        // ServletContext 객체를 가져옴
		ServletContext context = getServletContext();
        // web.xml의 <param-name> 태그의 이름으로, <param-value> 태그의 값들을 가져옴
		String menu_member = context.getInitParameter("menu_member");
		String menu_order = context.getInitParameter("menu_order");
		String menu_goods = context.getInitParameter("menu_goods");
		
		out.print("<html><body>");
		out.print("<table border=1 cellspacing=0><tr>메뉴 이름</tr>");
		out.print("<tr><td>"+menu_member+"</td></tr>");
		out.print("<tr><td>"+menu_order+"</td></tr>");
		out.print("<tr><td>"+menu_goods+"</td></tr>");
		out.print("<tr></table></body></html>");
	}

}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
  <display-name>pro08</display-name>
  <context-param>
  	<param-name>menu_member</param-name>
  	<param-value>회원등록 회원조회 회원수정</param-value>
  </context-param>
  <context-param>
  	<param-name>menu_order</param-name>
  	<param-value>회원등록 회원조회 회원수정</param-value>
  </context-param>
  <context-param>
  	<param-name>menu_goods</param-name>
  	<param-value>회원등록 회원조회 회원수정</param-value>
  </context-param>
</web-app>





@WebServlet

  • name : 서블릿 이름
  • urlPatterns : 서블릿 요청시 사용하는 매핑이름. 두가지 이상 설정 가능.



@WebServlet 애너테이션을 이용한 서블릿 설정

  • 두가지 url 매핑해도 되고, 접속하면 둘다 같은 결과값이 나옴



web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
  <display-name>pro08</display-name>
  <servlet>
  	<servlet-name>sinit</servlet-name>
  	<servlet-class>sec06.ex01.initParamServlet</servlet-class>
  	<init-param>
  		<param-name>email</param-name>
  		<param-value>ghdrlf@naver.com</param-value>
  	</init-param>
  	<init-param>
  		<param-name>tel</param-name>
  		<param-value>010-1234-5678</param-value>
  	</init-param>
  </servlet>
  
  <servlet-mapping>
  	<servlet-name>sinit</servlet-name>
  	<url-pattern>/first</url-pattern>
  </servlet-mapping>
  
</web-app>


InitParamServlet.java

package sec06.ex01;

@WebServlet(name="InitParamServlet",
		urlPatterns = { 
				"/sInit", 
				"/sInit2"
		}, 
		initParams = { 
				@WebInitParam(name = "email", value = "admin@jweb.com"), 
				@WebInitParam(name = "tel", value = "010-1111-2222")
		})a
public class InitParamServlet extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		
		String email = getInitParameter("email");
		String tel = getInitParameter("tel");
		
		out.print("<html><body>");
		out.print("<table><tr>");
		out.print("<td>email: </td>"+email+"</td></tr>");
		out.print("<tr><td>휴대전화: </td><td>"+tel+"</td>");
		out.print("</tr></table></body></html>");
	}
}


결과값



load-on-startup 기능 사용하기

  • 서블릿은 최초 요청시 init() 사용하고, 이 최초요청에 대해 실행시간이 길어짐
  • 이런 단점을 보완하기 위한 기능

 

  • 톰캣 컨테이너가 실행되면서 미리 서블릿을 실행합니다
  • 지정한 숫자가 0보다 크면, 톰캣 컨테이너가 실행되면서 서블릿이 초기화됨
  • 지정한 숫자는 우선순위를 의미함. 작은숫자부터 먼저 초기화됨

 

 

애너테이션 이용하기

  • 클래스 이름과 다르게 매핑 설정




LoadAppConfig.java

package sec06.ex02;

// loadOnStartup = 우선순위 (1이라는건 가장 첫번째의 우선순위라는 뜻)
@WebServlet(name = "loadConfig", urlPatterns = { "/loadConfig" },
loadOnStartup = 1)
public class LoadAppConfig extends HttpServlet {

	// 변수로 선언
	private ServletContext context;
	
	@Override
	public void init(ServletConfig config) throws ServletException {
		System.out.println("LoadAppConfig의 init 메서드 호출");
		// init() 메서드에서 먼저 ServletContext 객체를 얻어놓음
		context = config.getServletContext();
		
		// getInitParameter() 메서드로 web.xml의 메뉴정보를 읽어들임
		String menu_member = context.getInitParameter("menu_member");
		String menu_order = context.getInitParameter("menu_order");
		String menu_goods = context.getInitParameter("menu_goods");
		
		// 메뉴 정보를 ServletContext 객체에 바인딩함
		context.setAttribute("menu_member", menu_member);
		context.setAttribute("menu_order", menu_order);
		context.setAttribute("menu_goods", menu_goods);
	}

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		
		// 이미 받아온 ServletContext 객체 변수를 사용
		// 브라우저에서 요청시, ServletContext 객체의 바인딩된 메뉴항목을 가져옴
		String menu_member = (String) context.getInitParameter("menu_member");
		String menu_order = (String) context.getInitParameter("menu_order");
		String menu_goods = (String) context.getInitParameter("menu_goods");
		
		context.setAttribute("menu_member", menu_member);
		context.setAttribute("menu_order", menu_order);
		context.setAttribute("menu_goods", menu_goods);
		
		out.print("<html><body>");
		out.print("<table border=1 cellspacing=0><tr>메뉴 이름</tr>");
		out.print("<tr><td>"+menu_member+"</td></tr>");
		out.print("<tr><td>"+menu_order+"</td></tr>");
		out.print("<tr><td>"+menu_goods+"</td></tr>");
		out.print("</table></html></body>");
		out.close();
		
	}
}



web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app .....p.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
  <display-name>pro08</display-name>

  <context-param>
  	<param-name>menu_member</param-name>
  	<param-value>회원등록 회원조회 회원수정</param-value>
  </context-param>
  <context-param>
  	<param-name>menu_order</param-name>
  	<param-value>회원등록 회원조회 회원수정</param-value>
  </context-param>
  <context-param>
  	<param-name>menu_goods</param-name>
  	<param-value>회원등록 회원조회 회원수정</param-value>
  </context-param>
  
  <servlet>
  	<servlet-name>sinit</servlet-name>
  	<servlet-class>sec06.ex01.initParamServlet</servlet-class>
  	<init-param>
  		<param-name>email</param-name>
  		<param-value>ghdrlf@naver.com</param-value>
  	</init-param>
  	<init-param>
  		<param-name>tel</param-name>
  		<param-value>010-1234-5678</param-value>
  	</init-param>
  </servlet>
  
  <servlet-mapping>
  	<servlet-name>sinit</servlet-name>
  	<url-pattern>/first</url-pattern>
  </servlet-mapping>
  
</web-app>


결과값








'Spring' 카테고리의 다른 글

[Spring] 스코프, 필터  (0) 2022.08.29
[Spring] 쿠키, 세션, ajax  (0) 2022.08.25
[Spring] servlet  (0) 2022.08.18
[Spring] 로그인, 스프링 시큐리티  (0) 2022.08.18
[Spring] HTTP 요청/응답  (0) 2022.07.23