개발하는 삶
[Spring] 스프링과 서블릿, 바인딩 본문
스프링프로젝트 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 |