Java Spring 3 - 为 NoSuchRequestHandlingMethodException 创建 ExceptionHandler
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3230358/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring 3 - Create ExceptionHandler for NoSuchRequestHandlingMethodException
提问by sgsweb
Using Spring 3, I like to create an exception handler using the ExceptionHandlerannotation that will handle "no page found (404)"requests. I am using the following code to do this. But when I point to a URL that does not exist, the default exception handler defined by Spring is being invoked.
使用 Spring 3,我喜欢使用ExceptionHandler注释创建一个异常处理程序,该注释将处理“未找到页面(404)”请求。我正在使用以下代码来执行此操作。但是当我指向一个不存在的 URL 时,就会调用 Spring 定义的默认异常处理程序。
It might be that I'm handling the NoSuchRequestHandlingMethodExceptionexception. If it is, then what exception should I be registering?
可能是我正在处理NoSuchRequestHandlingMethodException异常。如果是,那么我应该注册什么例外?
Will you please take a look at the following code and see what I'm doing wrong?
请你看看下面的代码,看看我做错了什么?
NOTE: If I change the exception in the @ExceptionHandlerto NullPointerExceptionand create a RequestMappingto throw null pointer, that will work.
注意:如果我将@ExceptionHandler 中的异常更改为NullPointerException并创建一个RequestMapping以抛出空指针,那将起作用。
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class GeneralHandler {
private final Log logger = LogFactory.getLog(getClass());
@ExceptionHandler(NoSuchRequestHandlingMethodException.class)
public ModelAndView handleException (NoSuchRequestHandlingMethodException ex) {
ModelAndView mav = new ModelAndView();
logger.error("Exception found: " + ex);
return mav;
}
}
采纳答案by skaffman
@ExceptionHandler
-annotated methods are invoked when a @RequestMapping
method on that same class throws an exception. So when you added the mapping which threw the NullPointerException
, that worked, since the mapped method and exception handler were together in the same class.
@ExceptionHandler
-annotated 方法@RequestMapping
在同一个类上的方法抛出异常时被调用。因此,当您添加抛出 的映射时NullPointerException
,它起作用了,因为映射的方法和异常处理程序在同一个类中。
When no mapping is found, Spring has no way of associating the NoSuchRequestHandlingMethodException
with your @ExceptionHandler
, because it didn't get as far as matching the request to a handler method. This isn't mentioned explicitly in the docs, but is the behaviour I've observed.
当未找到映射时,Spring 无法将NoSuchRequestHandlingMethodException
与您的 相关联@ExceptionHandler
,因为它没有将请求与处理程序方法相匹配。这在文档中没有明确提到,而是我观察到的行为。
If you want to handle this exception specially, you're going to have to use the more general HandlerExceptionResolver
approach, rather than the more specialised @ExceptionHandler
technique.
如果你想特别处理这个异常,你将不得不使用更通用的HandlerExceptionResolver
方法,而不是更专业的@ExceptionHandler
技术。
回答by lisak
回答by Janning
In Spring 3.2 you can use @ContollerAdviceto have an ExceptionHandler for all your Controllers like this:
在 Spring 3.2 中,您可以使用@ContollerAdvice为所有控制器设置一个 ExceptionHandler,如下所示:
@ControllerAdvice
public class GeneralHandler {
@ExceptionHandler
public ModelAndView handleException (NoSuchRequestHandlingMethodException ex) {
ModelAndView mav = new ModelAndView();
...
return mav;
}
}
You can even add more annotations to return serialized json
您甚至可以添加更多注释以返回序列化的 json
@ExceptionHandler
@ResponseBody
@ResponseStatus(HttpStatus.BAD_REQUEST)
public RestError resolveBindingException ( MethodArgumentNotValidException methodArgumentNotValidException, Locale locale )
{
BindingResult bindingResult = methodArgumentNotValidException.getBindingResult();
return getRestError(bindingResult, locale);
}