
1. 프로젝트 만들기



- view 확인하기

3. context path 삭제하기




4. index.jsp 파일 삭제하기
- 바로 접근이 가능하기 때문에 MVC 파일의 강제가 안됨
스프링의 template 폴더와 동일함

- 요청을 톰캣이 받음
→ 전송되는 정보를 파싱해서 request 객체를 만들어서 dispathcerServlet에 전달해줌
package com.example.myapp; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; // http://localhost:8080/*.do 로 요청 @WebServlet("*.do") // 해당 주소를 무조건 연결 public class DispatcherServlet extends HttpServlet { // servlet이 됨 : 외부와 통신이 가능 @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { service(request, response); } }
package com.example.myapp; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; // http://localhost:8080/*.do 로 요청 @WebServlet("*.do") // 해당 주소를 무조건 연결 public class DispatcherServlet extends HttpServlet { // servlet이 됨 : 외부와 통신이 가능 @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println(request.getRequestURI()); } }

5. BoardController 만들기
- dispatherServlet에서 분기가 가능
package com.example.myapp; // 책임을 분리 public class BoardController { public void save(){ System.out.println("글쓰기"); } public void findAll(){ System.out.println("글목록보기"); } }
6. DispatcherServlet 만들기
package com.example.myapp; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; // http://localhost:8080/*.do 로 요청 @WebServlet("*.do") // 해당 주소를 무조건 연결 public class DispatcherServlet extends HttpServlet { // servlet이 됨 : 외부와 통신이 가능 @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println(request.getRequestURI()); String action = request.getRequestURI() .replace("/", "") .split(".")[0]; } }
- switch case문으로 분기하기
package com.example.myapp; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; // http://localhost:8080/*.do 로 요청 @WebServlet("*.do") // 해당 주소를 무조건 연결 public class DispatcherServlet extends HttpServlet { // servlet이 됨 : 외부와 통신이 가능 @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println(request.getRequestURI()); String action = request.getRequestURI() .replace("/", "") .split(".")[0]; BoardController bc = new BoardController(); switch (action) { case "save": bc.save(); break; case "findAll": bc.findAll(); break; default: response.getWriter().println("404 Not Found"); } } }

- “.”을 인식하지 못함 → \\ 추가하기!
package com.example.myapp; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; // http://localhost:8080/*.do 로 요청 @WebServlet("*.do") // 해당 주소를 무조건 연결 public class DispatcherServlet extends HttpServlet { // servlet이 됨 : 외부와 통신이 가능 @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println(request.getRequestURI()); String action = request.getRequestURI() .replace("/", "") .split("\\.")[0]; BoardController bc = new BoardController(); switch (action) { case "save": bc.save(); break; case "findAll": bc.findAll(); break; default: response.getWriter().println("404 Not Found"); } } }
7. 컨트롤러에서 분기처리해서 글자 반환하기
package com.example.myapp.controller; // 책임을 분리 public class BoardController { public String save(){ return "<h1>board write</h1>"; } public String findAll(){ return "<h1>board list</h1>"; } }
package com.example.myapp; import com.example.myapp.controller.BoardController; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; // http://localhost:8080/*.do 로 요청 @WebServlet("*.do") public class DispatcherServlet extends HttpServlet { @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println(request.getRequestURI()); String action = request.getRequestURI() .replace("/", "") .split("\\.")[0]; BoardController bc = new BoardController(); String result; switch (action) { case "save": result = bc.save(); response.getWriter().println(result); // 변수 result를 출력 break; case "findAll": result = bc.findAll(); response.getWriter().println(result); // 변수 result를 출력 break; default: response.getWriter().println("404 Not Found"); } } }


8. 어노테이션 만들어서 사용하기
package com.example.myapp; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface RequestMapping { String value(); // default "/" }
- 어노테이션에서 value는 키워드, 생략 가능
- method로 분리
- 어노테이션을 보고 호출 → reflextion
package com.example.myapp.controller; import com.example.myapp.RequestMapping; // 책임을 분리 public class BoardController { @RequestMapping("/save") // 키워드가 value(키 값 생략)라 가능함 public String save(){ return "<h1>board write</h1>"; } public String findAll(){ return "<h1>board list</h1>"; } public String findById(){ return "<h1>board one</h1>"; } }
package com.example.myapp; import com.example.myapp.controller.BoardController; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.Method; // http://localhost:8080/*.do 로 요청 @WebServlet("*.do") public class DispatcherServlet extends HttpServlet { private String getAction(String uri){ return uri //.replace("/", "") .split("\\.")[0]; } @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String action = getAction(request.getRequestURI()); BoardController bc = new BoardController(); Method[] methods = bc.getClass().getDeclaredMethods(); for(Method mt : methods){ Annotation anno = mt.getDeclaredAnnotation(RequestMapping.class); if(anno instanceof RequestMapping) { RequestMapping rm = (RequestMapping) anno; if (rm.value().equals(action)) { try { String result = (String) mt.invoke(bc); response.getWriter().println(result); break; } catch (Exception e) { throw new RuntimeException(); } } } } } }


package com.example.myapp.controller; import com.example.myapp.RequestMapping; // 책임을 분리 public class BoardController { @RequestMapping("/save") // 키워드가 value(키 값 생략)라 가능함 public String save(){ return "<h1>board write</h1>"; } @RequestMapping("/findAll") public String findAll(){ return "<h1>board list</h1>"; } @RequestMapping("/findById") public String findById(){ return "<h1>board one</h1>"; } }


- 컨트롤러가 하나 더 생기면 못 찾음
- 컨트롤러도 어노테이션으로 new해서 관리하고 있어야 함 → 스프링의 IoC 컨테이너가 필요함
Share article