How to use spring redirect if controller method returns ResponseEntity

41,723

Solution 1

Spring controller method return values are just sugar when you want the output from the controller to be post processed by Spring machinery. If I have correctly understood what you are doing, you have only 2 possibilities:

  • send an error response with code 500 and message "Cannot save file " + fileName
  • redirect to /member/uploadImage in the same application context.

As Spring provides more goodies for redirect than for SendError, my advice would be to have you method return a string:

@RequestMapping(value = { "/member/uploadExternalImage",
            "/member/uploadExternalImage" }, method = RequestMethod.GET)
    public String handleFileUpload(@RequestParam String url, @RequestParam String fileName,
            RedirectAttributes redirectAttributes, HttpServletResponse resp) {
        ...
        //return new ResponseEntity("Cannot save file " + fileName, HttpStatus.INTERNAL_SERVER_ERROR);
        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
            "Cannot save file " + fileName); // explicitely put error message in request
        return null;  // return null to inform Spring that response has already be processed
        ...
        return "redirect:/member/uploadImage";
    }

Solution 2

If you don't explicity need to return a ResponseEntity you can redeclare your method like:

public String handleFileUpload(@RequestParam String url,@RequestParam String fileName, RedirectAttributes redirectAttributes) {
    return "Cannot save file " + fileName;
    ...
    return "redirect:/member/uploadImage";
}

But if you need to use ResponseEntity, then it seems you can add a redirect to ResponseEntity as described here.

HttpHeaders headers = new HttpHeaders();
headers.add("Location", "/member/uploadImage");    
return new ResponseEntity<String>(headers,HttpStatus.FOUND);

Solution 3

This could be done using the @ExceptionHandler annotation.

  @RequestMapping(value = { "/member/uploadExternalImage", "/member/uploadExternalImage" }, method = RequestMethod.GET)
public String handleFileUpload(@RequestParam String url, @RequestParam String fileName,
        RedirectAttributes redirectAttributes) throws FileUploadException {
    ...
    throw new FileUploadException("Cannot save file " + fileName);
    ...
    return "redirect:/member/uploadImage";
}

@ExceptionHandler(FileUploadException.class)
ResponseEntity<String> handleFileUploadError(final FileUploadException e) {
  return new ResponseEntity(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}

In order for Spring to handle the error in your @ExceptionHandler method, it's required that you have the org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver exception resolver enabled. However, if you haven't specified any custom exception resolvers it will be enabled by default.

Share:
41,723

Related videos on Youtube

gstackoverflow
Author by

gstackoverflow

Updated on July 09, 2022

Comments

  • gstackoverflow
    gstackoverflow almost 2 years

    I want to write something like this:

    @RequestMapping(value = { "/member/uploadExternalImage",
                "/member/uploadExternalImage" }, method = RequestMethod.GET)
        public ResponseEntity<String> handleFileUpload(@RequestParam String url,@RequestParam String fileName, RedirectAttributes redirectAttributes) {
            ...
            return new ResponseEntity("Cannot save file " + fileName, HttpStatus.INTERNAL_SERVER_ERROR);
            ...
            return "redirect:/member/uploadImage";
        }
    

    expected behaviour - redirect to the controller:

    @RequestMapping(value = { "/member/createCompany/uploadImage",
                "/member/uploadImage" })
        @ResponseBody
        public ResponseEntity<String> handleFileUpload(@Validated MultipartFileWrapper file,
                BindingResult result, Principal principal
    

    But I cannot write it because "redirect:/member/uploadImage" is String but should be ResponseEntity

    How can I resolve my problem?

    • Jordi Castilla
      Jordi Castilla over 8 years
      declaring public String handleFileUpload(@RequestParam String url,@RequestParam String fileName, RedirectAttributes redirectAttributes) does not allow you to redirect?
    • gstackoverflow
      gstackoverflow over 8 years
      @Jordi Castilla I need return http code
    • Jordi Castilla
      Jordi Castilla over 8 years
      check my answer and linked one... think it will do the work for you
  • gstackoverflow
    gstackoverflow over 8 years
    Which meaning of HttpStatus.FOUND in your second case ?
  • Jordi Castilla
    Jordi Castilla over 8 years
    is another value of the class HttpStatus code 302 (found), like when you return HttpStatus.INTERNAL_SERVER_ERROR is a code 500 (Internal ServerError)
  • gstackoverflow
    gstackoverflow over 8 years
    I need server redirect.
  • gstackoverflow
    gstackoverflow over 8 years
  • Jordi Castilla
    Jordi Castilla over 8 years
    I can bet it can be adapted to local redirect, check second option of this and also this Spring forums posts,