공부내용의 목차 정리
1. front servlet의 기능
2. DistpacherServlet 정의 및 사용
3. Default Servlet 정의 및 사용
4. ProductList , ProductDetail을 클래스로 만들어서 인터페이스 controller를 만들어 implements 함으로써 하나의 컨트롤러가 두개의 클래스를 관리할 수 있도록 한다.
5. front servlet에서 if else 사용하지 않고 properties 사용하기
6. 서블릿이 로드하는 작업을 요청할 때마다 할 필요가 없기때문에 미리 로드할 수 있도록 코드를 수정하기
1. front servlet
클라이언트에 요청을 받으면 각각의 서블릿이 받아서 service -> dao -> 데이터베이스로 전달하는 과정을 거쳤었다.
이렇게 서블릿을 각각 나눠서 사용하면 장점은 역할의 분담이 가능한 점이다
front servlet은 이전에 여러 서블릿이 각각의 서블릿이 기능을 가졌던 것을 front servlet 서블릿 한개가 모두 처리한다. if else 구문을 통해 각각 할일을 지정한다. 문제점은 너무 한곳에 많이 할일을 모아두면 무거워진다.
해결방법으로 일반 클래스로 각각 서블릿이 하는 일을 대신하게 끔 한다.
- DistpacherServlet 서블릿 하나 두고 요청을 받는데 일반 클래스에게 역할을 위임한다.
- pojo는 순수한 자바오브젝트이다. 어디서든 사용하는 클래스이다.
2. DistpacherServlet
DistpacherServlet 을 우선 만들어 보도록 하겠다.
public class DistpacherServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void service(HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response) throws ServletException, IOException {
//url에 /a라고 하면 getservletPath에 전달된다.
String servletPath = request.getServletPath();
response.setContentType("text/html;charset = uft-8");
PrintWriter out = response.getWriter();
//요청 url값이 /a 이면
out.print("<h1>dispatcher servlet : + "+ servletPath +"</h1>");
}
}
web.xml
<!-- 실습 first servlet -->
<!-- DispacherServlet 을 만들고 /로 설정하여 뒤로 오는 것들을 모든 요청을 이곳에서 처리할 수 있게 한다. -->
<servlet>
<description></description>
<display-name>DispacherServlet</display-name>
<servlet-name>DispacherServlet</servlet-name>
<servlet-class>com.my.control.DispacherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DispacherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
web.xml 을 보면 요청된url이 dispacher 이라고하면 servlet -name 을 찾아서 servlet-class로 이동한다.
위에서 보면 url -pattern 에 /로만 변경을 하였는데 /로 바꾸게 되면 / 다음요청들은 모두 dispacher에서 처리가 된다.
3. Default Servlet
아파치 톰켓이 설치되어 있는 곳에 web.xml을 보면 Default Servlet이 있는 것을 볼 수 있다.
- 톰켓에 내장되 있는 서비스이다. 모든 web application 에서 사용할 수 있다.
- Static 리소스에 사용 -> html, css, js , img의 정적파일들을 처리할 수 있다.
web.xml
<!-- 정적파일처리를 담당하는 default 서블릿 , 톰켓에 내장되어 있다. -->
<servlet-mapping>
<servlet-name>default</servlet-name> <!-- 톰켓에서 web.xml에서 가져옴 -->
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name> <!-- 톰켓에서 web.xml에서 가져옴 -->
<url-pattern>/css/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name> <!-- 톰켓에서 web.xml에서 가져옴 -->
<url-pattern>/js/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name> <!-- 톰켓에서 web.xml에서 가져옴 -->
<url-pattern>/images/*</url-pattern>
</servlet-mapping>
위와 같이 web.xml에 추가하게 되면 url창에 입력할 때 /signup.html 이라고 입력한다면 해당 페[이지로 이동하게 되고 /login.html 로 입력한다면 해당 페이지로 이동하게 된다. 어떤 것이 오더라도 url창에서 선언한 것을 요청처리한다.
4. ProductList , ProductDetail을 클래스로 만들어서 인터페이스 controller를 만들어 implements 함으로써 하나의 컨트롤러가 두개의 클래스를 관리할 수 있도록 한다.
1) 인터페이스 Controller 생성하기
public interface Controller {
public String execute(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException;
}
2) implements 하는 두개의 클래스 생성 하기 ( ProductList , ProductDetail)
ProductList
public class ProductList implements Controller {
@Override
public String execute(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
return null;
}
}
ProductDetail
public class ProductDetail implements Controller {
@Override
public String execute(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
return null;
}
}
DistpacherServlet
public class DispacherServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void service(HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response) throws ServletException, IOException {
//url에 /a라고 하면 getservletPath에 전달된다.
String servletPath = request.getServletPath();
Controller control = null;
//1. productlist 요청시
if("/productlist".equals(servletPath)) {
control = new ProductList();
// 2. productdetail 요청시
}else if("/productdetail".equals(servletPath)){
control = new ProductDetail();
}
//execute 메서드 호출
control.execute(request, response);
response.setContentType("text/html;charset = uft-8");
PrintWriter out = response.getWriter();
//요청 url값이 /a 이면
out.print("<h1>dispatcher servlet : + "+ servletPath +"</h1>");
}
}
servletPath 가 productlist 와 같으면 ProductList 클래스를 사용하고
servletPath 가 productdetail와 같으면 productdetail 클래스를 사용한다.
control.execute(request, response); => 인터페이스 controller에 execute 메서드 오버라이딩하여 호출한다.
안에 값을 넣어보도록 하겠다.
productlist
package com.my.control;
public class ProductList implements Controller {
@Override
public String execute(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
ProductService service = new ProductService();
String path = "";
try {
//비즈니스로직 호출
List<Product> list = service.findAll();
//응답할 결과 요청 속성에 설정
request.setAttribute("list", list);
path = "productlistresult.jsp";
} catch (FindException e) {
e.printStackTrace();
request.setAttribute("msg", e.getMessage());
path = "failresult.jsp";
}
return path;
}
}
productdetail
package com.my.control;
public class ProductDetail implements Controller {
@Override
public String execute(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
ProductService service = new ProductService();
String path = "";
String prodNo = request.getParameter("prodNo");
try {
Product p = service.findByNo(prodNo);
request.setAttribute("p", p);
path = "productdetailresult.jsp";
} catch (FindException e) {
e.printStackTrace();
request.setAttribute("msg", e.getMessage());
path = "failresult.jsp";
}
RequestDispatcher rd = request.getRequestDispatcher(path);
rd.forward(request, response);
return path;
}
}
DispacherServlet
public class DispacherServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void service(HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response) throws ServletException, IOException {
//url에 /a라고 하면 getservletPath에 전달된다.
String servletPath = request.getServletPath();
Controller control = null;
//1. productlist 요청시
if("/productlist".equals(servletPath)) {
control = new ProductList();
// 2. productdetail 요청시
}else if("/productdetail".equals(servletPath)){
control = new ProductDetail();
}
//오바라이딩된 execute 메서드 호출, path에 대입
String path = control.execute(request, response);
//path 가 null 이거나 공백일때가 있을 수 있음
if(path == null || path.equals("")) {
}else {
//VIEWER로 이동
RequestDispatcher rd = request.getRequestDispatcher(path);
rd.forward(request, response);;
}
}
}
Controller
package com.my.control;
public interface Controller {
// String 타입으로 선언한 이유 : 이동할 jsp 로 forword하기 위해서
public String execute(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException;
}
5. first servlet에서 if else 사용하지 않고 properties 사용
config 파일에 control.properties 생성
#control.properties
/productlist = com.my.control.ProductList
/productdetail = com.my.control.ProductDetail
DispacherServlet
//if else 를 대신하여 properties 를 이용해보자
// 1. control.properties 파일 실제경로 찾기
ServletContext sc = this.getServletContext();
String controlConfigPath = sc.getRealPath("config\\control.properties");
Properties env = new Properties ();
env.load(new FileInputStream(controlConfigPath));
String controlClassName = env.getProperty(servletPath);
try {
Class clazz = Class.forName(controlClassName);
Object obj = clazz.newInstance();
Controller control = (Controller)obj;
String path = control.execute(request, response);
//오바라이딩된 execute 메서드 호출, path에 대입
//잘들어왔는지 확인해보기 - 만약에 없다고 하면 클래스의 리턴 값이 있는지 확인하기
System.out.println(" path 값이 들어왔나요?" + path);
//path 가 null 이거나 공백일때가 있을 수 있음
if(path == null || path.equals("")) {
}else {
//VIEWER로 이동
RequestDispatcher rd = request.getRequestDispatcher(path);
rd.forward(request, response);;
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
6. 서블릿이 로드하는 작업을 요청할 때마다 할 필요가 없기때문에 미리 로드할 수 있도록 코드를 수정
init() 메서드를 사용하여 서블릿호출시 자동호출될 수 있도록 한다.
package com.my.control;
public class DispacherServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private Properties env;
//로드하는 작업을 요청할 때 마다 할 필요가 있을까? :=> 한번만 미리 로드해 둔다.
@Override //서블릿호출시 자동호출됨
public void init() throws ServletException{
super.init();
// 1. control.properties 파일 실제경로 찾기
ServletContext sc = this.getServletContext();
// properties 파일을 읽음
String controlConfigPath = sc.getRealPath("config\\control.properties");
env = new Properties ();
//해당 프로퍼티파일에 이름과 값이 프로퍼티화되어 로드한다..
try {
env.load(new FileInputStream(controlConfigPath));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
protected void service(HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response) throws ServletException, IOException {
//url에 /a라고 하면 getservletPath에 전달된다.
String servletPath = request.getServletPath();
// servletPath 프로퍼티 가져온다 , 최종해당하는 이름이 controlClassName
String controlClassName = env.getProperty(servletPath);
try {
Class clazz = Class.forName(controlClassName);
Object obj = clazz.newInstance();
Controller control = (Controller)obj;
//오바라이딩된 execute 메서드 호출, path에 대입
String path = control.execute(request, response);
//잘들어왔는지 확인해보기 - 만약에 없다고 하면 클래스의 리턴 값이 있는지 확인하기
System.out.println(" path 값이 들어왔나요?" + path);
//path 가 null 이거나 공백일때가 있을 수 있음
if(path == null || path.equals("")) {
}else {
//VIEWER로 이동
RequestDispatcher rd = request.getRequestDispatcher(path);
rd.forward(request, response);;
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
'sevlet' 카테고리의 다른 글
[22.01.04] JSP EL 태그와 JSTL (0) | 2022.01.04 |
---|---|
JSP 흐름도& 실습 (0) | 2021.12.06 |
getAttribute & setAttribute 실습 (0) | 2021.12.03 |
서블릿 request , response 실습 (0) | 2021.12.02 |