Web/MVC

    [Servlet 구현하기] Controller Scanner와 JSON View

    지난 시간에 어노테이션 기반의 MVC 프레임워크를 만들어 보았습니다. 아직은 개선할 점이 있었습니다. 컨트롤러 어노테이션 스캔 역할 분리 JSON view 지원 프레임워크에서 기본으로 어노테이션 핸들러 지원하기 위의 개선점들을 해결하기 전에, 생각해봐야할 점이 있었습니다. MVC 프레임워크 패키지가 아닌 APP (어플리케이션) 패키지에서 지원하는 핸들러와 어댑터를 추가해주고 있었습니다. 저희가 스프링 MVC를 사용할때 어노테이션 매핑을 따로 추가해주지 않아도 기본으로 지원하는 것 처럼, 개발자는 어노테이션 매핑에 대한 추가설정 없이 기본적으로 제공받도록 구현하고 싶었습니다. 그래서 MVC 프레임워크 패키지에 DefaultApplicationInitializer를 만들어주었습니다. package nexts..

    [Servlet 구현하기] 어노테이션 기반 MVC 프레임워크 구현

    톰캣 코드 저장소 : https://github.com/dongho108/jwp-dashboard-http/tree/step234 어노테이션기반 MVC 프레임워크 코드 저장소 : https://github.com/dongho108/jwp-dashboard-mvc/tree/step1 지난 시간에는 서블릿 컨테이너인 톰캣을 구현해보았습니다. 구현했던 톰캣 기능 요청당 쓰레드 생성 (쓰레드관리) 커넥션관리 서버소켓 생성 HttpRequest, HttpResponse 변환 컨트롤러 찾기 컨트롤러 실행 그래서 4~6번은 아래와 같은 구조가 만들어졌습니다. 위와 같은 구조에는 문제점이 있었습니다. Request에 맞는 Controller를 찾아주는 메서드와 클래스가 전혀 다른 곳에 있는 패키지를 의존하고 있습니다...

    EP9. PRG (Post/Redirect/Get) 패턴

    상품등록과 같은 POST 요청을 보내고 나서 Redirect 처리를 안해주면 새로고침 시 POST 요청이 또 나갈 수 있다. 왜냐하면 새로고침은 마지막 요청을 다시 보내기 때문이다. 이 문제를 어떻게 해결할까? 상품 저장 후에 뷰 템플릿으로 이동하는 것이 아니라, 상품 상세 화면으로 리다이렉트를 호출해주면 된다. @PostMapping("/add") public String addItemV5(Item item) { itemRepository.save(item); return "redirect:/basic/items/" + item.getId(); } 이렇게, POST 요청 후에 Redirect로 GET 요청을 보내는 것이 PRG 패턴이다. 하지만 위 코드에서도 문제가 있다. URL을 인코딩 하지 않고 사..

    EP8. Thymeleaf 타임리프

    타임리프 글을 리뉴얼 했습니다. 아래 내용들이 당연히 포함되어있고 더 자세한 설명과 예시가 있습니다~ 바로 아래링크 누르셔서 보시면 됩니다! 2021.07.26 - [Web/MVC2] - EP1. 타임리프 Thymeleaf EP1. 타임리프 Thymeleaf toc링크기능이 추가가 안되어있어서 필요한 부분은 Ctrl+F 로 찾아서 보시면 됩니다~ 목차 타임리프 사용 선언 텍스트 - text, utext - Escape HTML 엔티티 springEL 표현식 지역변수 선언 기본 객체들 - 편의 ksabs.tistory.com 타임리프 사용선언 속성변경 대부분의 HTML 속성을 th:xxx 로 변경할 수 있다. 변수 표현식 10000 모델에 포함된 값이나, 타임리프 변수로 선언한 값을 조회할 수 있다. 프로..

    EP7. HTTP 응답 데이터 처리

    HTTP 응답 데이터를 만드는 방법에는 세가지가 있다. 정적 리소스 뷰 템블릿 사용 HTTP 메세지 사용 정적리소스 웹 브라우저에 정적인 HTML, CSS, JS를 제공할 때는 정적 리소스를 사용한다. 스프링부트 상에서는 src/main/resources/static 위치에 해당하는 부분이다. URL경로 상에서 /index.html /basic/hello-form 으로 접근하면 정적리소스 (src/main/resources/static)에서 해당 경로를 읽는다./p> (참고로 static/index.html 은 자동으로 웰컴페이지로 등록이 된다.) 뷰 템플릿 사용 웹 브라우저에 동적인 HTML 을 제공할 때 뷰 템플릿을 사용한다. 스프링 부트 상에서는 src/main/resources/templates/..

    EP6. HTTP 요청 데이터 처리

    Http 헤더 꺼내기 docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-annarguments Web on Servlet Stack Spring Web MVC is the original web framework built on the Servlet API and has been included in the Spring Framework from the very beginning. The formal name, “Spring Web MVC,” comes from the name of its source module (spring-webmvc), but it is more com docs.spring.io 위 주소에서 Cont..

    EP5. Spring MVC 기본 기능 (요청 매핑)

    Spring MVC 기본기능 method 별 매핑 @GetMapping @PostMapping @PutMapping @DeleteMapping @PatchMapping PathVariable /** * PathVariable 사용 * 변수명이 같으면 생략 가능 * * @PathVariable("userId") String userId -> @PathVariable userId * /mapping/userA */ @GetMapping("/mapping/{userId}") public String mappingPath(@PathVariable("userId") String data) { log.info("mappingPaht userId = {}", data); return "ok"; } 변수 이름을 dat..

    EP4. 스프링 MVC 구조

    Spring MVC 전체 구조 처음 HTTP 요청이 들어오면 URL에 매핑된 핸들러(컨트롤러)를 조회한다. Dispatcher Servlet은 처음 Http 요청이 들어오는 곳을 한곳으로 통일하고 여기서 핸들러(컨트롤러)를 분배하기 위해서 존재한다. 그리고 해당 핸들러가 지원하는 방식이 무엇인지 핸들러 어댑터 목록에서 조회한다. 최근 실무에서는 99.9퍼센트 애노테이션 기반의 핸들러(컨트롤러)를 사용하지만, 스프링은 기존 프레임워크 구조를 깨지않고 계속 발전해왔기 때문에 기존에 지원하던 핸들러들도 지원해야했다. 그래서 핸들러 어댑터 목록을 조회하는 것이 필요하다. Dispatcher Servlet 입장에서는 조회한 핸들러 어댑터만 호출하면 핸들러 어댑터에서 알아서 핸들러를 찾아 호출하고 핸들러 어댑터는 ..

    EP4. MVC 패턴

    MVC패턴이 등장하기 이전에는 하나의 서블릿이나 JSP에서 비즈니스 로직과 뷰 렌더링까지 모두 처리했다. 서블릿패턴에서 로직과 렌더링 package hello.servlet.web.servlet; import hello.servlet.domain.member.Member; import hello.servlet.domain.member.MemberRepository; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.htt..

    EP3. 서블릿객체만을 이용해 HTTP 응답 메시지 작성하기

    상태코드 헤더세팅 - content - cookie - redirect 상태코드 response.setStatus(HttpServletResponse.SC_OK); 헤더세팅 response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); response.setHeader("Pragma", "no-cache"); response.setHeader("my-header", "hello"); 헤더 세팅시 편의 메서드 content private void content(HttpServletResponse response) { //Content-Type: text/plain;charset=utf-8 //Content-Length: 2 //res..