최근에 김영한 선생님의 인프런 강의를 정말 많이 돌려보는것 같다. 너무 이해가 잘 되게 설명해주셔서 김영한 선생님이 출시한 모든 강의를 구매하였다 (내 지갑은 텅텅 비어버렸지만...) 오늘은 spring mvc 의 기본 개념 구조를 정리해보았다.
스프링에서도 Servlet을 만들 수 있다. @WebServlet 어노테이션을 통해 만들어주면된다.
@WebServlet(name = "helloServlet", urlPatterns = "/hello")
public class HelloServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse
response){
}
}
Web Servlet은 해당 구조로 웹 요청과 응답을 받는다. HttpServletRequest에서 parameter및 headear등을 볼 수 있는 요청 관련 객체이다. HttpServletResponse에서 Header를 Set해서 보낼수 있고 message body를 포함해서 보낸다.
패키지 설계시 controller, service, repository 부를 나눈다. view 에 데이터를 본래때는 model 객체를 사용한다. 하지만 실제 개발 환경에서 해당 구조에 한계가 있어 Spring은 추가적인 구조로 보완을 한다.
해당 구조처럼 Controller 로직이 request시 바로 controller에 보내면 공용 처리가 어렵다는 단점이 있다. 이를 보완하기 위해 나온 구조가 Front Controller이다. 스프링 웹 MVC에서는 DIspacherServlet이 이 역할을 한다.
URL 매핑 이후에 view render를 위해 해당 view 파일을 찾는 과정에서 쓸데없이 반복되는 부분이나 확장자가 있다. 해당 반복을 줄이기위해 나온 개념이 viewResolver이다.
// 1. 핸들러 조회
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null) {
noHandlerFound(processedRequest, response);
return;
}
//2.핸들러 어댑터 조회-핸들러를 처리할 수 있는 어댑터
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// 3. 핸들러 어댑터 실행 -> 4. 핸들러 어댑터를 통해 핸들러 실행 -> 5. ModelAndView 반환
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
private void processDispatchResult(HttpServletRequest request,
HttpServletResponse response, HandlerExecutionChain mappedHandler, ModelAndView
mv, Exception exception) throws Exception {
// 뷰 렌더링 호출
render(mv, request, response);
}
protected void render(ModelAndView mv, HttpServletRequest request,
HttpServletResponse response) throws Exception {
View view;
String viewName = mv.getViewName(); //6. 뷰 리졸버를 통해서 뷰 찾기,7.View 반환
view = resolveViewName(viewName, mv.getModelInternal(), locale, request);
// 8. 뷰 렌더링
view.render(mv.getModelInternal(), request, response);
}
동작 순서
@GetMapping("/new-form")
public String newForm() {
return "new-form";
}
@PostMapping("/save")
public String save(
@RequestParam("username") String username,
@RequestParam("age") int age,
Model model) {
Member member = new Member(username, age);
memberRepository.save(member);
model.addAttribute("member", member);
return "save-result";
}
@GetMapping
public String members(Model model) {
List<Member> members = memberRepository.findAll();
model.addAttribute("members", members);
return "members";
}
@GetMapping("/mapping/users/{userId}/orders/{orderId}")
public String mappingPath(@PathVariable String userId, @PathVariable Long
orderId) {
log.info("mappingPath userId={}, orderId={}", userId, orderId);
return "ok";
}
@S1f4j 어노테이션으로 쉽게 사용 가능
log.trace("trace log={}", name);
log.debug("debug log={}", name);
log.info(" info log={}", name);
log.warn(" warn log={}", name);
log.error("error log={}", name);
로그 사용시 장점
@RequestMapping("/headers")
public String headers(HttpServletRequest request,
headerMap,
String cookie
HttpServletResponse response,
HttpMethod httpMethod,
Locale locale,
@RequestHeader MultiValueMap<String, String>
@RequestHeader("host") String host,
@CookieValue(value = "myCookie", required = false)
){
}
log.info("request={}", request);
log.info("response={}", response);
log.info("httpMethod={}", httpMethod);
log.info("locale={}", locale);
log.info("headerMap={}", headerMap);
log.info("header host={}", host);
log.info("myCookie={}", cookie);
return "ok";
}
// default value 지정, 필수 요청 지정
@RequestParam(required = true, defaultValue = "guest")
// Map 형태로 받기
@RequestParam Map<String, Object> paramMap
// 요청 파라미터 객체 형태로 받기, Model Attribute 생략 가능
@ModelAttribute HelloData helloData
// 메시지 바디 정보를 직접 조회
@RequestBody String messageBody
// 메시지 바디 정보 직접 반환, String으로 반환시에도 view 조회 안함
@ResponseBody
// message body에 담긴 정보를 객체 형식으로 변환
@RequestBody HelloData data
// ResponseBody를 이용해 객체 형식으로 반환하면 json형식으로 변환되어 응답됨
@ResponseStatus(HttpStatus.OK)
@ResponseBody
@GetMapping("/response-body-json-v2")
public HelloData responseBodyJsonV2() {
HelloData helloData = new HelloData();
helloData.setUsername("userA");
helloData.setAge(20);
return helloData;
}
HTTP 요청 데이터 읽기
HTTP 응답 데이터 생성
[Spring] redirect시 Controller에 데이터 넘기기, RedirectAttribute 활용하기 (0) | 2022.05.16 |
---|---|
[Algorithm] 자바 문자열 함수 정리 및 알고리즘 전략 정리 (0) | 2022.05.13 |
[React] React.JS 빠르게 기초 개념 정리 및 이해하기 (0) | 2022.05.12 |
[Spring] 스프링 프레임 워크 기초 정리, 핵심만 정리 (0) | 2022.05.06 |
[Angular.js] 소수점 반올림하는 방법 (0) | 2022.05.06 |