14

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()は呼び出されません。


一般に、可能であれば、コントローラー ベース (コントローラー レベル) ごとにこの例外を処理したいと考えています。このため、1 つの@ExceptionHandler注釈付きメソッドは、アプリケーション全体に対してグローバルではなく、その特定のコントローラーに対してのみアクティブにする必要があります。これは、私のアプリケーションにはファイルのアップロードを処理する Web ページがいくつかしかないためです。この例外が発生した場合、現在のページにわかりやすいエラー メッセージを表示し、ファイルで構成されたエラー ページにリダイレクトしないようにしweb.xmlます。これが実現可能ではない場合でも、この例外は、今述べたカスタム要件なしでとにかく処理する必要があります。

どちらのアプローチも私にとってはうまくいきませんでした。私が見つけたこの例外の処理については、これ以上何もありません。XML ファイルなどのどこかに追加の構成が必要ですか?


例外がスローされた後に得られるものは、次のスナップショットで見ることができます。

ここに画像の説明を入力

4

7 に答える 7

3

次のように、CommonsMultipartResolver の resolveLazily プロパティを true に設定できます。

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="resolveLazily" value="true"/>
</bean>
于 2013-08-21T09:14:11.993 に答える
2

Dirk Lachowski によって投稿された回答から、マルチパート アップロードに使用されるページの一部を除外しましたHiddenHttpMethodFilter

HiddenHttpMethodFilterはもともと のような URL パターンを与えられていました/*。そのため、これらのページを別のディレクトリ/フォルダに移動して、 のように別の URL パターンを指定するのは面倒でした/xxx/*。これを回避するために、私はOncePerRequestFilter独自のクラスで継承し、マルチパート アップロードに使用されるこれらのページを除外しました。これらのページは、現在のページにユーザー フレンドリーなエラー メッセージを表示して期待どおりに機能しました。

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ファイルでは、このフィルター -filter.HiddenHttpMethodFilterが次の代わりに指定されましorg.springframework.web.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

于 2013-04-10T12:08:33.557 に答える
1

私が覚えていることから、これらの注釈付きメソッドは ModelAndView または String の戻り型のみを許可するため、あなたの @ExcpetionHandler は機能していません。詳細については、この投稿を参照してください。

于 2013-04-05T19:46:58.373 に答える
1

My solution :First define bean for class that implements HandlerExceptionResolver .

 <bean id="classForBeanException" class="XXXX.path.To.classForBeanException" />
于 2013-04-08T09:50:42.137 に答える