메시지, 국제화
·
Spring
메시지 악덕 기획자가 화면에 보이는 문구가 마음에 들지 않는다고, 상품명이라는 단어를 모두 상품이름으로 고쳐달라고 하면 어떻게 해야할까? 여러 화면에 보이는 상품명, 가격, 수량 등, label 에 있는 단어를 변경하려면 다음 화면들을 다 찾아가면서 모두 변경해야 한다. 화면 수가 적으면 문제가 되지 않지만 화면이 수십개 이상이라면 수십개의 파일을 모두 고쳐야 한다. 왜냐하면 해당 HTML 파일에 메시지가 하드코딩 되어 있기 때문이다. 이런 다양한 메시지를 한 곳에서 관리하도록 하는 기능을 메시지 기능이라 한다. 국제화 메시지에서 한 발 더 나가보자. 메시지에서 설명한 메시지 파일( messages.properties )을 각 나라별로 별도로 관리하면 서비스를 국제화 할 수 있다. 예를 들어서 다음과 같..
주요 annotation
·
Spring
Thymeleaf
·
Spring
Thymeleaf란? '템플릿 엔진'의 일종. html 태그에 속성을 추가해 페이지에 동적으로 값을 추가하거나 처리할 수 있다. 특징 서버 사이드 HTML 렌더링(SSR) : 타임리프는 백엔드 서버에서 HTML을 동적으로 렌더링하는 용도로 사용된다. 사용법은 SSR이 다 비슷하기에 학습하기에도 어렵지 않고, 페이지가 어느정도 정적이고 빠른 생산성이 필요한 경우 백엔드 개발자가 개발해야하는 일이 생기는데 이 경우 타임리프는 좋은 선택지이다. 네츄럴 템플릿 :타임리프는 순수한 HTML을 최대한 유지하려는 특징이 있다. 이게 JSP와의 큰 차이점으로 타임리프로 작성한 파일은 확장자도 .HTML이고 웹 브라우저에서 직접 파일을 열어도 내용을 확인할 수 있다. 물론, 이 경우 동적인 결과 렌더링은 되지 않지만 H..
상품관리 서비스(1)
·
Spring
Spring으로 상품을 관리할 수 있는 서비스를 만들어보자 -상품 도메인 모델- 1.상품 ID 2.상품명 3.가격 -상품 관리 기능- 1.상품 목록 2.상품 상세 3.상품 등록 4.상품 수정 요구사항이 정리되고 디자이너, 웹 퍼블리셔, 백엔드 개발자가 업무를 나누어 진행한다. 디자이너: 요구사항에 맞도록 디자인하고, 디자인 결과물을 웹 퍼블리셔에게 넘겨준다. 웹 퍼블리셔: 다자이너에서 받은 디자인을 기반으로 HTML, CSS를 만들어 개발자에게 제공한다. 백엔드 개발자: 디자이너, 웹 퍼블리셔를 통해서 HTML 화면이 나오기 전까지 시스템을 설계하고, 핵심 비즈니스 모델을 개발한다. 이후 HTML이 나오면 이 HTML을 뷰 템플릿으로 변환해서 동적으로 화면을 그리고, 또 웹 화면의 흐름을 제어한다. Re..
ArgumentResolver & ReturnValueHandler
·
Spring
ArgumentResolver 애노테이션 기반의 컨트롤러는 매우 다양한 파라미터를 사용할 수 있다. HttpServletRequest , Model 은 물론이고, @RequestParam , @ModelAttribute 같은 애노테이션 그리고 @RequestBody , HttpEntity 같은 HTTP 메시지를 처리하는 부분까지 매우 큰 유연함을 보여준다. 이렇게 파라미터를 유연하게 처리할 수 있는 이유가 바로 ArgumentResolver 덕분이다. 애노테이션 기반 컨트롤러를 처리하는 RequestMappingHandlerAdapter 는 바로 이 ArgumentResolver 를 호출해서 컨트롤러(핸들러)가 필요로 하는 다양한 파라미터의 값(객체)을 생성한다. 그리고 이렇게 파리미터의 값이 모두 준비..
요청 매핑
·
Spring
@RequestMapping 은 URL 경로를 템플릿화 할 수 있는데, @PathVariable 을 사용하면 매칭 되는 부분을 편리하게 조회할 수 있다. @PathVariable 의 이름과 파라미터 이름이 같으면 생략할 수 있다. 주소에서 userId를 매핑할 수 있다. @GetMapping("mapping/{userId}") public String mappingPath(@PathVariable("userId") String data){ log.info("mappingPath userId={}", data); return "ok"; } 다중 사용도 가능하다. @GetMapping("/mapping/users/{userId}/orders/{orderId}") public String mappingPath..
스프링 MVC
·
Spring
직접만든 MVC와 스프링 MVC 비교 스프링 MVC 구조 FrontController -> DispatcherServlet handlerMappingMap -> HandlerMapping MyHandlerAdapter -> HandlerAdapter ModelView -> ModelAndView viewResolver -> ViewResolver MyView -> View 동작 순서 1. 핸들러 조회: 핸들러 매핑을 통해 요청 URL에 매핑된 핸들러(컨트롤러)를 조회한다. 2. 핸들러 어댑터 조회: 핸들러를 실행할 수 있는 핸들러 어댑터를 조회한다. 3. 핸들러 어댑터 실행: 핸들러 어댑터를 실행한다. 서블릿이 호출되면 HttpServlet 이 제공하는 serivce() 가 호출된다. 스프링 MVC는 D..
FrontControllerServlet
·
Spring
http://localhost:8080/front-controller/v5/v3/members/new-form 주소가 들어오면 handlerMappingMap.put("/front-controller/v5/v3/members/new-form", new MemberFormControllerV3()); Object handler = getHandler(request); MemberFromControllerV3가 반환된다. MyHandlerAdapter adapter = getHandlerAdapter(handler); private MyHandlerAdapter getHandlerAdapter(Object handler) { for (MyHandlerAdapter adapter : handlerAdapter..
HandlerAdapter
·
Spring
Controller 인터페이스를 구현한 Controller가 실행되려면 HandlerMapping, HandlerAdapter 두 가지가 필요하다. HandlerMapping Handler Mapping에서 특정 Controller를 찾을 수 있어야 함 HandlerAdapter Handler Mapping을 통해 찾은 Handler를 실행할 수 있는 Handler Adapter가 필요 -과정- 1. 클라이언트의 HTTP 요청 2. 요청 URI 매핑 정보로 FrontController 조회 3. Handler Mapping 정보에서 Handler조회 4. Handler Mapping 정보에서 찾은 Handler를 처리할 수 있는 Handler Adapter를 Handler Adapter목록에서 조회 My..
Model 추가
·
Spring
서블릿 종속성 제거 컨트롤러 입장에서 HttpServletRequest, HttpServletResponse이 꼭 필요할까? 요청 파라미터 정보는 자바의 Map으로 대신 넘기도록 하면 지금 구조에서는 컨트롤러가 서블릿 기술을 몰라도 동작할 수 있다. 그리고 request 객체를 Model로 사용하는 대신에 별도의 Model 객체를 만들어서 반환하면 된다. 우리가 구현하는 컨트롤러가 서블릿 기술을 전혀 사용하지 않도록 변경해보자. 이렇게 하면 구현 코드도 매우 단순해지고, 테스트 코드 작성이 쉽다. 뷰 이름 중복 제거 컨트롤러에서 지정하는 뷰 이름에 중복이 있는 것을 확인할 수 있다. 컨트롤러는 뷰의 논리 이름을 반환하고, 실제 물리 위치의 이름은 프론트 컨트롤러에서 처리하도록 단순화 하자. 이렇게 해두면..
View 분리
·
Spring
모든 컨트롤러에서 뷰로 이동하는 부분에 중복이 있고, 깔끔하지 않다. String viewPath = "/WEB-INF/views/new-form.jsp"; RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath); dispatcher.forward(request, response); 이 부분을 깔끔하게 분리하기 위해 별도로 뷰를 처리하는 객체를 만들자. http://localhost:8080/front-controller/v2/members/new-form 위의 주소가 들어오면 아래의 서블릿이 호출이 된다. @WebServlet(name = "FrontControllerServletV2", urlPatterns = "/front-con..