Spring, Java 개발자 입니다

Spring/Filter

HTTP Request와 Response 그리고 Filter 처리 과정

HttpServletRequest 와 HttpServletResponse 를 통해서 여러가지 작업을 처리할 수 있다는 것을 알고는 있지만 실제로 간단한 필터처리를 제외하고는 사용해 본적이 없었다. 그러던 중 모든 사용자의 request와 response 를 분석해 기록을 해달라는 요구사항이 들어왔고 이 기회를 통해서 내가 헷갈렸던 부분과 필터의 처리 과정에 대해서 다시한 번 정리 해보려고 한다. (Filter 처리 후 Spring Context 영역 내에서 일어나는 것은 다루지 않을 예정) 우선 Client 의 Request 가 들어오면 어떤 방식으로 Response 를 만들어 전달하는지에 대한 부분부터 살펴봐야 한다. Client 가 Server 로 Request 를 보내면 Spring 영역으로 들어가..

Spring/스프링 인터셉터

스프링 인터셉터 ①

스프링 인터셉터: 서블릿 필터와 같이 웹과 관련된 공통사항을 처리하는 방법 (Spring MVC가 제공하는 기능이고 서블릿 필터보다 훨씬 더 많은 기능들을 제공한다) 스프링 인터셉터 기본 흐름 HTTP 요청 -> WAS -> 필터 -> 서블릿 -> 스프링 인터셉터 -> 컨트롤러 로그인 사용자일 경우 HTTP 요청 -> WAS -> 필터 -> 서블릿 -> 스프링 인터셉터 -> 컨트롤러 비 로그인 사용자 HTTP 요청 -> WAS -> 필터 -> 서블릿 -> 스프링 인터셉터(적절하지 않은 요청이라 판단, 컨트롤러 호출 X) 스프링 인터셉터는 아래와 같이 3개로 구성이 된다. public interface HandlerInterceptor { default boolean preHandle(HttpServlet..

Spring/Dispatcher servlet

요청 매핑 핸들러 어댑터 구조 RequestMappingHandlerAdapter

Spring MVC의 구조 우선 HTTP 요청이 오게되면 핸들러와 핸들러 어댑터를 통해서 컨트롤러를 호출한다. 스프링은 이미 필요한 핸들러 매핑과 핸들러 어댑터를 대부분 구현해 두었기 때문에 개발자가 직접 핸들러 매핑과 핸들러 어댑터를 만드는 일은 거의 없다. 1. DispatcherServlet이 핸들러를 조회해서 핸들러를 매핑한다. HandlerMapping을 순서대로 실행해서 핸들러를 찾는다 2. 핸들러를 처리할 수 있는 핸들러 어댑터를 조회한다. 3. 핸들러 어댑터를 통해서 실제 컨트롤러를 호출한다. 디스패처서블릿이 조회한 핸들러 어댑터를 실행하면서 핸들러 정보도 같이 넘겨주고 그 결과를 반환한다. 애노테이션 기반의 컨트롤러, @RequestMapping 을 처리하는 핸들러 어댑터인 Request..

Spring

Spring 컨트롤러 매핑 정리

@RestController VS @Controller 일반석으로 @Contorller 애노테이션을 사용해서 매핑하게 되면 반환 값을 String 으로 했을 때 반환 값 자체를 뷰 이름으로 인식한다. 그래서 뷰를 착고 뷰가 렌더링 되게 되는데 @RestController를 사용해서 반환 값을 String 으로 하게 되면 HTTP 메세지 바디에 반환 String 값을 바디에 바로 입력을 한다. 따라서 실행 결과로 String 메세지를 받을 수 있다. PathVariable을 이용한 GetMapping @GetMapping("/경로/{id}") public String usingPathvariableGetMapping(@PathVariable("id") int id){ //(@PathVariable int ..

Spring

스프링 RequestMapping 어노테이션

MVC 패턴을 사용하기 위해서 여러가지 복잡한 과정들을 거친다. 컨트롤러를 이용해 모델에 데이터를 담아서 뷰로 전달하는 일련의 과정은 여러가지 방식으로 구현될 수 있다. 어떤 프레임워크를 사용하고 어떤 방식으로 사용할지에 따라서 다르게 구현할 수 있지만 현재 스프링 프레임워크를 사용하는 실무에서는 99.9% @RequestMapping 방식의 컨트롤러를 사용한다. @RequestMapping 은 애노테이션 기반의 컨트롤러를 지원하는 핸들러 매핑과 어댑터이다. (RequestMappingHandlerMapping, RequestMappingHandlerAdapter) @Controller: 스프링이 자동으로 스프링 빈에 등록한다. (내부에 @Component 애노테이션이 존재) 스프링 MVC에서 애노테이션..

Spring

엔티티의 DTO 변환시 페이징의 한계 처리

query를 날릴 때 distinct 사용시 페이징 처리를 할 수 없다는 단점이 있다. 대신 개 빠름. 그럼 페이징 처리를 하기 위해선 어떤 방식으로 해결 할 수 있을까? 우선 Order 라는 클래스가 아래와 같이 정의 되었다고 할 때 class Order{ private Long orderId; private Member member; private Delivery delivery; private List items; } Order 페이징 처리정보를 받아오기 위해선 distinct를 사용해서 아래와 같이 query를 날리면 된다. public List findAllOrders() { return em.createQuery( "select distinct o from Order o" + " join fe..

Spring

쿼리 방식 선택 권장 순서

프로젝트시 매번 쿼리를 날릴 때 어떤 방식으로 쿼리를 작성해야지 좀 더 효율적으로 할 수 있을 지 고민했는데 아래와 같은 기준으로 정해서 사용하면 될 것 같다. 1. 엔티티 Dto 변환 (요거는 내 생각에 권장아니고 무조건 필수임) -> 엔티티를 외부에 노출 안하는게 좋은 코드작성 2. 필요하면 페치 조인으로 성능 최적화(대부분의 성능 이슈가 해결이 된다고 함) -> 엔티티 매니저에서 creatQuery를 통해서 직접 작성 List tests = entityManager.createQuery("select t from Test t" +" join fetch t.friend fr " +" join fetch t.family fa", Test.class) .getResultList(); 3. 직접 Dto로 ..

Spring

API 결과 형식

List 형식으로 반환 할 때 유연성 있게 class를 통해서 반환하자 class로 감싸서 반환하는것이 좀더 질 좋은 코드 @GetMapping("경로") public Result test(){ List findTests = testService.findTests(); List collect = findTests.stream() .map(t -> new TestDto(t.getName())); .collect(Collectores.toList()); return new Result(collect); } @Data @AllArgsConstructor static class Result{ private T data; }

Spring

API 데이터 수정 형식

@PostMapping을 이용해서 수정해도 괜찮지만 @PutMapping을 이용해서 만들자 @PutMappint("update/{id}") public void UpdateResponse( @PathVariable("id") Long id, @RequestBody @Valid Test test){ //내용 부분 } url에 수정할 데이터의 key 값인 id를 받아오고 수정 내용을 json 형식으로 받아오는 이런 방식을 사용해서 데이터를 수정한다.

Spring

Loging 로깅

실무 프로젝트를 진행할 경우 운영 시스템에서 System.out.print() 와 같은 시스템 콘솔을 사용해서 출력하지 않고 별도의 로깅 라이브러리를 사용해서 로그를 출력해야 한다. 스프링 부트 라이브러리를 사용하면 스프링 부트 로깅 라이브러리 spring-boot-starter-logging 가 함께 포함이 된다. 스프링 부트 로깅 라이브러리는 SLF4J, Logback의 라이브러리를 사용한다. 테스트 로그가 출력되는 포맷을 확인한다. 시간, 로그 레벨, 프로세스 ID, 쓰레드 명, 클래스 명, 로그 메세지 로그 레벨 설정을 변경해서 출력 할 수 있다. Level : trace > debug > info > warn > error