Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
317 views
in Technique[技术] by (71.8m points)

java - How to rethrow exception as @ResponseStatus-annotated exception in Spring @ExceptionHandler?

I have made exception, that I'm throwing always when I want a 404 page:

@ResponseStatus( value = HttpStatus.NOT_FOUND )
public class PageNotFoundException extends RuntimeException {

I want to create controller-wide @ExceptionHandler that will re-throw ArticleNotFoundException(which causes error 500) as my 404 exception:

@ExceptionHandler( value=ArticleNotFoundException.class )
public void handleArticleNotFound() {
    throw new PageNotFoundException();
}

But it doesn't work - I still have error 500 and Spring logs:

ExceptionHandlerExceptionResolver - Failed to invoke @ExceptionHandler method: ...

Note that I translate code to html so response cannot be empty or simple String like with ResponseEntity. web.xml entry:

<error-page>
    <location>/resources/error-pages/404.html</location>
    <error-code>404</error-code>
</error-page>

FINAL SOLUTION FROM ANSWER COMMENTS

It's not a full re-throw, but at least it uses web.xml error page mapping like my PageNotFoundException

    @ExceptionHandler( value = ArticleNotFoundException.class )
    public void handle( HttpServletResponse response) throws IOException {
        response.sendError( HttpServletResponse.SC_NOT_FOUND );

    }
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Instead of throwing an exception try this:

@ExceptionHandler( value=ArticleNotFoundException.class )
public ResponseEntity<String> handleArticleNotFound() {
    return new ResponseEntity<String>(HttpStatus.NOT_FOUND);
}

This will basically return a Spring object that gets converted into a 404 by your controller.

You can pass it a different HttpStatus if you want to return different HTTP status messages to your front-end.

If you are deadset on doing this with annotations, just annotate that controller method with @ResponseStatus and don't throw an exception.

Basically if you annotate a method with @ExceptionHandler I'm 90% sure that Spring expects that method to consume that exception and not throw another one. By throwing a different exception, Spring thinks that the exception wasn't handled and that your exception handler failed, hence the message in your logs

EDIT:

To get it to return to a specific page try

return new ResponseEntity<String>(location/of/your/page.html, HttpStatus.NOT_FOUND);

EDIT 2: You should be able to do this:

@ExceptionHandler( value=ArticleNotFoundException.class )
public ResponseEntity<String> handleArticleNotFound(HttpServletResponse response) {
    response.sendRedirect(location/of/your/page);
    return new ResponseEntity<String>(HttpStatus.NOT_FOUND);
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...