2015-05-19 59 views
1

我試圖接管一個基本的春天引導RESTful服務的404未找到處理器控制的最簡單的方法計算出如由Spring提供的示例:春天開機 - 以404控制未找到

https://spring.io/guides/gs/rest-service/

而不是使其返回默認的JSON輸出:

{ 
    "timestamp":1432047177086, 
    "status":404, 
    "error":"Not Found", 
    "exception":"org.springframework.web.servlet.NoHandlerFoundException", 
    "message":"No handler found for GET /aaa, ..." 
} 

我想提供我自己的JSON輸出。

通過採取DispatcherServlet的控制和使用DispatcherServlet#setThrowExceptionIfNoHandlerFound(true),我能夠讓它拋出一個異常,在404的情況下,但我不能處理該異常通過@ExceptionHandler,就像我會爲一個MissingServletRequestParameterException。任何想法爲什麼?

還是有更好的方法比拋出和處理NoHandlerFoundException?

+0

五月是[this](http:// stackoverflow。com/questions/21061638/spring-mvc-how-to-return-custom-404-errorpages)將會對你有所幫助。 –

回答

0

簡而言之,NoHandlerFoundException是從容器中拋出的,而不是從容器中的應用程序拋出。因此,您的Container無法瞭解您的@ExceptionHandler,因爲這是Spring功能,而不是容器中的任何內容。您要的是HandlerExceptionResolver。我有同樣的問題,因爲你,看看我的解決方案在那裏:How to intercept "global" 404s on embedded Tomcats in spring-boot

0

按照Spring documentation appendix A.有一個叫spring.mvc.throw-exception-if-no-handler-found布爾屬性,它可以用來啓用拋NoHandlerFoundException。然後你可以創建異常處理程序。

@RestControllerAdvice 
class MyExceptionHandler { 

    private static final Logger log = LoggerFactory.getLogger(MyExceptionHandler.class); 

    @ResponseStatus(HttpStatus.NOT_FOUND) 
    @ExceptionHandler(NoHandlerFoundException.class) 
    public String handleNoHandlerFoundException(NoHandlerFoundException ex) { 
     log.error("404 situation detected.",ex); 
     return "Specified path not found on this server"; 
    } 
} 

@ExceptionHandler本身沒有@ControllerAdvice(或@RestControllerAdvice)不能使用,因爲它只能綁定到其控制器。

1

它工作得很好。

當您使用SpringBoot它不處理(404未找到)明確它使用WebMvc錯誤響應。如果你的Spring Boot應該處理這個異常,那麼你應該在Spring Boot中做一些破解。對於404 Exception類是NoHandlerFoundException,如果你想處理您@RestControllerAdvice類異常時,您必須在您的應用類中添加@EnableWebMvc註釋並設置setThrowExceptionIfNoHandlerFound(真); DispatcherServlet中的。請參考代碼

@SpringBootApplication 
@EnableWebMvc 
public class Application { 
    @Autowired 
    private DispatcherServlet servlet; 

    public static void main(String[] args) throws FileNotFoundException, IOException { 
     SpringApplication.run(Application.class, args); 
    } 

    @Bean 
    public CommandLineRunner getCommandLineRunner(ApplicationContext context) { 
     servlet.setThrowExceptionIfNoHandlerFound(true); 
     return args -> {}; 
    } 
} 

在這之後,你可以處理NoHandlerException@RestControllerAdvice

@RestControllerAdvice 
public class AppException { 

    @ExceptionHandler(value={NoHandlerFoundException.class}) 
    @ResponseStatus(code=HttpStatus.BAD_REQUEST) 
    public ApiError badRequest(Exception e, HttpServletRequest request, HttpServletResponse response) { 
     e.printStackTrace(); 
     return new ApiError(400, HttpStatus.BAD_REQUEST.getReasonPhrase()); 
    } 
} 

我創建ApiError中的類返回自定義錯誤響應

public class ApiError { 
    private int code; 
    private String message; 
    public ApiError(int code, String message) { 
     this.code = code; 
     this.message = message; 
    } 
    public ApiError() { 
    } 
    //getter & setter methods... 
} 
+0

添加@EnableWebMvc應該完全關閉Spring Boot的Spring MVC自動配置 - 因此所有的spring.mvc。*配置屬性都將被忽略。請參閱參考文檔https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-web-applications.html#boot-features-spring-mvc-auto-configuration。 –