반응형

모든 Controller(메소드)의 동작이 끝나고 로그를 처리하기 위해 SPRING AOP@after를 사용하여 기록을 하고 있었습니다.
작업 도중 파일 업로드를 위한 multipart의 타입의 전송의 경우 request의 값이 null값으로 처리되어 값을 받아 올 수 없었고 처리한 방법은 아래와 같이 2가지정도가 있었습니다.

  1. aop부분에서 형변환을 처리하여 값을 변경하였습니다.

  2. Interceptor에서 request의 타입을 체크하여 RequestContextHolder의 속성값을 변경하였습니다.

 

after어노테이션에서 형변환 방식

@After("execution(public * egovframework.*.*.*.*(..))")
public void logWrite(JoinPoint joinPoint) throws Throwable {
    final String methodName = joinPoint.getSignature().getName();
    ServletRequestAttributes attribute = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes());
    HttpServletRequest request = attribute.getRequest();

    // 멀티 파트 체크 **************
    if (request.getContentType() != null && request.getContentType().toLowerCase().contains("multipart/form-data")) {
        MultiReadAndCopyHttpServletRequest copyReq = new MultiReadAndCopyHttpServletRequest(request); //Request복사
        CommonsMultipartResolver cmResolver = new CommonsMultipartResolver();  //형식변환준비
        MultipartHttpServletRequest req = cmResolver.resolveMultipart(copyReq); //변환
        request = req;
    }
    // 멀티 파트 체크 **************

    (...) //이후 로그처리

첫번째 해결방식으로 reqeust의 값이 null인지 체크후 multipart/form-data인지 확인 후 일치한다면, requestMultipartHttpServletReqeust로 형변환처리하였습니다.

해당 방법으로 해결은 가능하지만 AOP의 양이 많아지거나 처리로직이 많아지면 가독성면이나 이후 유지보수 측면에서 좋지 않을것으로 판단하여 다른방법을 찾아보았고 Interceptor에서 처리하는 방법을 확인하였습니다.

 

 

Interceptor 추가하기

두번째 처리방법으로 Interceptor를 추가하고 instanceof를 통해 타입을 체크 후 변경해주도록 하였습니다.

 

MultipartHandlerInterceptor.java

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

/**
 * form태그 encType이 "multi/part"로 넘어갈경우 request set변경처리
 * @author srok
 *
 */
public class MultipartHandlerInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (request instanceof MultipartHttpServletRequest) {
            RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request));
        }
        return true;
    }
}

 

 

dispatcher-servlet.xml

Interceptor 정보 추가

<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/*.do" />
        <bean class="프로젝트 경로.MultipartHandlerInterceptor" />
    </mvc:interceptor>
</mvc:interceptors>

실 적용은 두번째 방식을 적용하였습니다.

 

 

 

두번째 처리방식 참조 URL

참조 : https://hhjeong.tistory.com/74

반응형