복붙노트

[SPRING] MaxUploadSizeExceededException은 Spring에서 예외 처리 메소드를 호출하지 않습니다.

SPRING

MaxUploadSizeExceededException은 Spring에서 예외 처리 메소드를 호출하지 않습니다.

스프링 3.2.0을 사용하고 있습니다. 이 답변에 따르면 HandlerExceptionResolver 인터페이스를 구현하는 주석 처리 된 컨트롤러에서 동일한 메서드를 사용합니다.

public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception) {

    Map<String, Object> model = new HashMap<String, Object>(0);

    if (exception instanceof MaxUploadSizeExceededException) {
        model.put("msg", exception.toString());
        model.put("status", "-1");
    } else {
        model.put("msg", "Unexpected error : " + exception.toString());
        model.put("status", "-1");
    }

    return new ModelAndView("admin_side/ProductImage");
}

Spring 설정은 다음을 포함한다 :

<bean id="filterMultipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize">
        <value>10000</value>
    </property>
</bean>

파일 크기가 초과되면 이전 메소드가 호출되어야하며 자동으로 예외를 처리해야하지만 전혀 발생하지 않습니다. 예외가 발생해도 resolveException () 메서드는 호출되지 않습니다. 이 예외를 처리하는 방법은 무엇입니까? 내가 놓친 게 있니?

여기에서도 같은 것을 지정합니다. 나는 왜 그것이 내 경우에는 효과가 있는지 모르겠습니다.

@ControllerAdvice를 사용하여 다음 접근법을 시도했지만 작동하지 않았습니다.

package exceptionhandler;

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

@ControllerAdvice
public final class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {

    @ExceptionHandler(value = {MaxUploadSizeExceededException.class})
    protected ResponseEntity<Object> handleConflict(RuntimeException ex, WebRequest request) {
        String bodyOfResponse = "This should be application specific";
        return handleExceptionInternal(ex, bodyOfResponse, new HttpHeaders(), HttpStatus.CONFLICT, request);
    }
}

나는 또한 장황한 - Exception을 넣으려고했다.

@ExceptionHandler(value={Exception.class})

ResponseEntity () 메서드는 어떤 경우에도 호출되지 않습니다.

가능하다면 일반적으로 컨트롤러 기본 (컨트롤러 수준)마다이 예외를 처리하려고합니다. 이를 위해 @ExceptionHandler 어노테이션이 적용된 하나의 메소드는 응용 프로그램에 파일 업로드를 처리하는 웹 페이지가 몇 개 밖에 없으므로 전체 컨트롤러가 아닌 특정 컨트롤러에서만 활성화되어야합니다. 이 예외가 발생하면 현재 페이지에 사용자에게 친숙한 오류 메시지를 표시하고 web.xml 파일에 구성된 오류 페이지로 리디렉션하지 않기를 원합니다. 이것이 실현 가능하지 않다면, 방금 표현한 사용자 정의 요구 사항없이이 예외를 처리해야합니다.

어느 접근법도 나를 위해 일하지 않았습니다. 찾을 수있는이 예외를 처리하는 것에 대한 자세한 것은 없습니다. XML 파일 또는 다른 곳에서 추가 구성이 필요합니까?

예외가 throw 된 후 가져 오는 것은 다음 스냅 샷에서 볼 수 있습니다.

해결법

  1. ==============================

    1.게시 된 스택 추적에 따라 요청이 디스패처 서블릿에 도달하기 전에 MaxUploadSizeExceeded 예외가 발생합니다. 따라서 예외가 발생하면 대상 컨트롤러가 아직 결정되지 않았으므로 예외 처리기가 호출되지 않습니다.

    게시 된 스택 추적에 따라 요청이 디스패처 서블릿에 도달하기 전에 MaxUploadSizeExceeded 예외가 발생합니다. 따라서 예외가 발생하면 대상 컨트롤러가 아직 결정되지 않았으므로 예외 처리기가 호출되지 않습니다.

    stacktrace를 보면 multipart-request의 모든 매개 변수와 "큰"업로드 데이터 매개 변수를 가져 오는 HiddenHttpMethodFilter에 예외가 발생하는 것을 볼 수 있습니다.

    컨트롤러가 multipart-upload를 처리하는 데 HiddenHttpMethodFilter가 필요합니까? 그렇지 않은 경우 업로드 처리 컨트롤러에서이 필터를 제외하십시오.

  2. ==============================

    2.다음과 같이 CommonsMultipartResolver Lazily 속성을 true로 구성 할 수 있습니다.

    다음과 같이 CommonsMultipartResolver Lazily 속성을 true로 구성 할 수 있습니다.

    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="resolveLazily" value="true"/>
    </bean>
    
  3. ==============================

    3.Dirk Lachowski가 게시 한 답변에서 HiddenHttpMethodFilter의 multipart-upload에 사용되는 페이지 중 일부를 제외했습니다.

    Dirk Lachowski가 게시 한 답변에서 HiddenHttpMethodFilter의 multipart-upload에 사용되는 페이지 중 일부를 제외했습니다.

    HiddenHttpMethodFilter는 원래 / *와 같은 URL 패턴을가집니다. 따라서 이러한 페이지를 별도의 디렉토리 / 폴더에서 이동하고 / xxx / *와 같은 다른 URL을 지정하는 것은 지루했습니다. 이 문제를 피하기 위해, 나는 자신의 클래스에서 OncePerRequestFilter를 상속 받았으며, 현재 페이지에서 사용자 친화적 인 오류 메시지를 표시하는 것으로 예상되는대로 작동 한 multipart-upload에 사용 된 이러한 페이지를 제외 시켰습니다.

    package filter;
    
    import java.io.IOException;
    import java.util.Locale;
    import javax.servlet.FilterChain;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletRequestWrapper;
    import javax.servlet.http.HttpServletResponse;
    import org.springframework.util.Assert;
    import org.springframework.util.StringUtils;
    import org.springframework.web.filter.OncePerRequestFilter;
    
    public final class HiddenHttpMethodFilter extends OncePerRequestFilter {
    
        /**
         * Default method parameter: <code>_method</code>
         */
        public static final String DEFAULT_METHOD_PARAM = "_method";
    
        private String methodParam = DEFAULT_METHOD_PARAM;
    
        /**
         * Set the parameter name to look for HTTP methods.
         *
         * @see #DEFAULT_METHOD_PARAM
         */
        public void setMethodParam(String methodParam) {
            Assert.hasText(methodParam, "'methodParam' must not be empty");
            this.methodParam = methodParam;
        }
    
        private boolean excludePages(String page) {
            //Specifically, in my case, this many pages so far have been excluded from processing avoiding the MaxUploadSizeExceededException in this filter. One could use a RegExp or something else as per requirements.
            if (page.equalsIgnoreCase("Category.htm") || page.equalsIgnoreCase("SubCategory.htm") || page.equalsIgnoreCase("ProductImage.htm") || page.equalsIgnoreCase("Banner.htm") || page.equalsIgnoreCase("Brand.htm")) {
                return false;
            }
            return true;
        }
    
        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
    
            String servletPath = request.getServletPath();
    
            if (excludePages(servletPath.substring(servletPath.lastIndexOf("/") + 1, servletPath.length()))) {
                String paramValue = request.getParameter(this.methodParam);
                //The MaxUploadSizeExceededException was being thrown at the preceding line.
                if ("POST".equals(request.getMethod()) && StringUtils.hasLength(paramValue)) {
                    String method = paramValue.toUpperCase(Locale.ENGLISH);
                    HttpServletRequest wrapper = new filter.HiddenHttpMethodFilter.HttpMethodRequestWrapper(request, method);
                    filterChain.doFilter(wrapper, response);
                } else {
                    filterChain.doFilter(request, response);
                }
            } else {
                filterChain.doFilter(request, response);
            }
        }
    
        /**
         * Simple {@link HttpServletRequest} wrapper that returns the supplied
         * method for {@link HttpServletRequest#getMethod()}.
         */
        private static class HttpMethodRequestWrapper extends HttpServletRequestWrapper {
    
            private final String method;
    
            public HttpMethodRequestWrapper(HttpServletRequest request, String method) {
                super(request);
                this.method = method;
            }
    
            @Override
            public String getMethod() {
                return this.method;
            }
        }
    }
    

    그리고 web.xml 파일에서 다음과 같이 org.springframework.web.filter.HiddenHttpMethodFilter 대신이 필터 filter.HiddenHttpMethodFilter가 지정되었습니다.

    <filter>
        <filter-name>multipartFilter</filter-name>
        <filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>multipartFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    <filter>
        <filter-name>httpMethodFilter</filter-name>
        <filter-class>filter.HiddenHttpMethodFilter</filter-class>
        <!--<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> This was removed replacing with the preceding one-->
    </filter>
    <filter-mapping>
        <filter-name>httpMethodFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    

    나는 여전히 org.springframework.web.filter.HiddenHttpMethodFilter와 함께 문제의 예외를 처리하는 공정한 방법이 될 수 있어야한다.

  4. ==============================

    4.주석이 달린 메서드는 ModelAndView 또는 String의 반환 형식 만 허용하므로 @ExcpetionHandler가 작동하지 않습니다. 자세한 내용은이 게시를 참조하십시오.

    주석이 달린 메서드는 ModelAndView 또는 String의 반환 형식 만 허용하므로 @ExcpetionHandler가 작동하지 않습니다. 자세한 내용은이 게시를 참조하십시오.

  5. ==============================

    5.내 솔루션 : 먼저 HandlerExceptionResolver를 구현하는 클래스 용 Bean을 정의한다.

    내 솔루션 : 먼저 HandlerExceptionResolver를 구현하는 클래스 용 Bean을 정의한다.

     <bean id="classForBeanException" class="XXXX.path.To.classForBeanException" />
    
  6. ==============================

    6.예외를 처리하는 ControllerAdvice에서 this.It과 같은 코드를 사용할 수 있습니다. 이것은 나를 위해 일했습니다. 이것은 봄 4.0+

    예외를 처리하는 ControllerAdvice에서 this.It과 같은 코드를 사용할 수 있습니다. 이것은 나를 위해 일했습니다. 이것은 봄 4.0+

    @ExceptionHandler(Exception.class)
    public @ResponseBody BaseResponse onException(Exception e, HttpServletResponse response) {
        response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
    
        BaseResponse resp = new BaseResponse();
        if(e instanceof MaxUploadSizeExceededException){
            resp.setCode(FileUploadFailed.SIZE_EXCEED);
            resp.setMessage("Maximum upload size exceeded");
        }
        return resp;
    }
    
  7. from https://stackoverflow.com/questions/14298265/maxuploadsizeexceededexception-doesnt-invoke-the-exception-handling-method-in-s by cc-by-sa and MIT license