10

When I use spring3 @Controller like this:

@RequestMapping("/userCenter")

@Controller
public class LoginCtrl {
    @RequestMapping("/loginPage")
    public String login(HttpServletRequest request,HttpServletResponse response,Model model) throws Exception { 
        return "userCenter/loginPage";
    }
}

It is ok, I get the the loginPage.jsp right content in browser.

but when I change @Controller to @RestController

the localhost:8080//userCenter/loginPage return a page with the string "userCenter/loginPage"

So,how could I use @RestController to get jsp pages like @Controller?

Benjamin
  • 1,816
  • 13
  • 21
blackcatIan
  • 275
  • 1
  • 3
  • 9

6 Answers6

13

You shouldn't. A @RestController is not meant to return view names through a String return type/value. It's meant to return something that will be written to the response body directly.

More concretely (in the general configuration case), Spring MVC configures its return value handlers in RequestMappingHandlerAdapter#getDefaultReturnValueHandlers(). If you look at that implementation, the handler for String view names, ViewNameMethodReturnValueHandler, is registered after the handler for @RestController (really @ResponseBody), RequestResponseBodyMethodProcessor.

If you really have to, you can declare your method to have a return type of View or ModelAndView (the handlers for these, ViewMethodReturnValueHandler and ModelAndViewMethodReturnValueHandler, are registered before RequestResponseBodyMethodProcessor) and return the appropriate object, with an identifying view name.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • 1
    Someone who does not know about why spring introduced `@RestController` – sura2k Nov 17 '16 at 17:05
  • Assume you want only develop web service. it should not return any of views. let's say you going to expose that service for andorid, ios, web or any consumer. Any one can use that service using only API call. that will be the reason to introduce @RestController by spring. – Kapila Ranasinghe Mar 12 '17 at 14:10
  • I aggree that `@RestController` is not meant for classic web applications, but imho text/html is also a valid result content-type for a REST webservice and a View could be helpful for generating the output. We have different representations for a single resource in our app: json, xml or html depending on the `Accept` http-header. – fishbone Nov 05 '19 at 07:49
  • @fishbone I'm not trying to argue that. The way Spring MVC is written, the `String` view name that's returned by a method in a `@RestController` annotated controller would be interpreted as the content of the response rather than a view name. I'll edit my answer to make that more clear. – Sotirios Delimanolis Nov 05 '19 at 13:59
10

Actually, a @RestController can also return view:

  1. Set the controller method's return type to be ModelAndView

  2. Set your view path like this:

    ModelAndView mav = new ModelAndView("userCenter/loginPage");

  3. return mav;

You get the correct JSO page view content.

aboger
  • 2,214
  • 6
  • 33
  • 47
blackcatIan
  • 275
  • 1
  • 3
  • 9
  • 2
    Yes you *can* do it this way, but you shouldn't. What you're missing here is a fundamental understanding of what a REST API should and should not be doing. – IcedDante Jan 26 '15 at 05:45
  • 2
    suppose that you need to produce pdf on your rest api, the way spring handle pdf generation is through views, and not message converters (to use response body), so i believe there are some special cases where you need to mix both. (and yes, a rest api should only work with json or xml and the client should be responsible for rendering the pdf with the data provided, but again, there are some special use cases where reports should be produced by the server, even in a rest enviroment). – lepi Aug 17 '15 at 21:35
  • 1
    Check the source of `@RestController`. It is just a shortcut (instead of having both `@Controller` and `@ResponseBody`) and gives you a better readability, nothing more. – sura2k Nov 17 '16 at 17:11
1

@RestController configures @ResponseBody for every body automatically, it means it is designed to write everything on the output and not to return views. If you want to return a view, configure another class with @Controller and return that view accordingly.

aboger
  • 2,214
  • 6
  • 33
  • 47
Amit_Hora
  • 716
  • 1
  • 8
  • 27
0

Check the API docs for @RestController it is annotated with @ResponseBody itself, which indicates that method return value should be bound to the web response body. The configured view objects will never come into play, so it cannot map to any view. My question is why you want to use the RestController anyway, its not meant to map to any views?

varun
  • 684
  • 1
  • 11
  • 30
0

Could still be useful with @RestController for creating redirect fallback to you REST Api

@GetMapping("/**")
public ModelAndView Default()
{
    ModelAndView mav = new ModelAndView("redirect:/actuator/health");
    return mav;
}
0

@RestController actually returns the HTTP response as JSON or XML only.

  1. @RestController is internally annotated with @ResponseBody.
  2. @ResponseBody annotation tells a controller that the object returned is automatically serialized into JSON and passed back into the HttpResponse object.

But if you want to return as JSP, you can use ModelAndView like below.

example:

@RestController
public class HomeController {

   @RequestMapping("/")
   public ModelAndView getHome() {
       ModelAndView mav = new ModelAndView("home.jsp");
       return mav;
  }
}
veryreverie
  • 2,871
  • 2
  • 13
  • 26
Indhuja
  • 82
  • 6