Using @RequestBody and forwarding to another endpoint throws an exception. Drain closed

My Java spring REST API controller looks like this:

public void signup(@RequestBody RequestBody requestBody) throws IOException, ServletException {

I get this exception:

Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: Could not read document: Stream closed; nested exception is java.io.IOException: Stream closed

This is because I want to pass the request body to the RequestBody class (which opens the request input stream and terminates it), and also redirects / redirects it to another endpoint.

Actual controller:

    @RequestMapping(value = "/signup", method = RequestMethod.POST)
    public void signup(@RequestBody CustomUserDetails user, HttpServletRequest request, HttpServletResponse response) {

        String userName = user.getUsername();
        logger.debug("User signup attempt with username: " + userName);

        try{
            if(customUserDetailsService.exists(userName))
            {
                logger.debug("Duplicate username " + userName);
userName + " already exists");
                String newUrl = "login";
                RequestDispatcher view = request.getRequestDispatcher(newUrl);
                view.forward(request, response);
            } else {
                customUserDetailsService.save(user);
                authenticateUserAndSetSession(user, response);
            }
        } catch(Exception ex) {

        }
    }

How can I do it?

+6
source share
6 answers

body - , . . - , , . :

Spring "HandlerMethodArgumentResolver" ?

, :

public void signup(@RequestBody RequestBody requestBody)

, RequestBody , . , String.

public void signup(@RequestBody String requestBody)

REST- api, , String. , , , , JSON.

+3

ExceptionHandler, :

@RequestMapping(value = "/signup", method = RequestMethod.POST)
public void signup(@RequestBody CustomUserDetails user, HttpServletResponse response) {

    String userName = user.getUsername();
    logger.debug("User signup attempt with username: " + userName);

    //try{
    if (customUserDetailsService.exists(userName)) {
        logger.debug("Duplicate username " + userName);
        throw new SignupException(userName + " already exists");
    } else {
        customUserDetailsService.save(user);
        authenticateUserAndSetSession(user, response);
    }
    /*} catch(Exception ex) {

    }*/
}

ExceptionHandler :

@ExceptionHandler(SignupException.class)
public String duplicateName() {
    return "login";
}

RegistrationException :

public class SignupException extends RuntimeException {
    public SignupException(String message) {
        super(message);
    }

    public SignupException() {
    }
}
+5

@RequestBody RequestBody requestBody HttpServletRequest request.

. , forward .

, . :

  • spring
+3

, URL- RequestBody, , Spring 3.2 .

,

request.setAttribute("user",user),
return "forward:/login";
+2

consumes = { "application/json" }, = { "application/json" }

+1
  • RequestBody - . , messageconversion .
  • RequestBody . .
  • It is impossible to get RequestBodyin RestController, so you cannot judge whether it is good or bad.
  • If you need to use a new controller / endpoint for processing. Then I think the best approach is to get CustomUserDetailsboth @RequestBodyin the controller and then process it. Then call the nested method or service for the rest of the process, instead of changing your mind about forwarding to another controller. Then return the response from the controller.
+1
source

Source: https://habr.com/ru/post/1017093/


All Articles