There was a request to write directly to HttpServletResponse, so I investigated how to do it.
Just define HttpServletResponse as an argument of Controller and write to it.
HelloController.java
@Controller
public class HelloController {
@RequestMapping(value="/", method=RequestMethod.GET)
public void hello(HttpServletResponse response) throws Exception {
response.getWriter().write("hogehoge");
}
}
The return value is a String. If you write directly to the response, null will be returned.
HelloController.java
@Controller
public class HelloController {
@RequestMapping(value="/{param}", method=RequestMethod.GET)
public String hello(HttpServletResponse response, @PathVariable String param) throws Exception {
if(Objects.equals("param", param)){
response.getWriter().write("hogehoge");
return null;
}
return "hello";
}
}
There was a report that an error log appeared when I returned null. When I checked the log, I went looking for JSP but couldn't find it.
So when I checked the source code, it looked like the following.
HelloController.java
@Controller
public class HelloController {
@Inject
HttpServletResponse response
@RequestMapping(value="/{param}", method=RequestMethod.GET)
public String hello(@PathVariable String param) throws Exception {
if(Objects.equals("param", param)){
response.getWriter().write("hogehoge");
return null;
}
return "hello";
}
}
Certainly, when implemented like this, it seemed to look for a JSP and get an error. That is, the render process of View is being executed. By the way, I thought that HttpServletResponse can be injected, but it's not the main story, so it's through.
When I check the DispatcherServlet, I am running the HandlerAdapter to get the ModelAndView. At this time, if the return value is null, render processing by View will not be executed. If you are writing the Response directly, this behavior is expected. (DoDispatch, processDispatchResult, etc.)
Looking at the processing of RequestMappingHandlerAdapter, null is returned when isRequestHandled of ModelAndViewContainer becomes true. (GetModelAndView etc.)
There are various conditions, but in this case, it is a condition that HttpServletResponse is in the argument of the Controller method and the return value from Controller is null. The source where the error occurred uses the HttpServletResponse defined in the field, so the return value of the HandlerAdapter did not become null.
If you follow the process from applyDefaultViewName of DispatcherServlet, you can see that the requested URL is applied as the View name.
Let's add HttpServletResponse as an argument. If you can't do that, let's set the return type of Controller to ModelAndView as follows.
HelloController.java
@Controller
public class HelloController {
@Inject
HttpServletResponse response
@RequestMapping(value="/{param}", method=RequestMethod.GET)
public ModelAndView hello(@PathVariable String param) throws Exception {
if(Objects.equals("param", param)){
response.getWriter().write("hogehoge");
return null;
}
return new ModelAndView("hello");
}
}
You can see why this works by reading ModelAndViewMethodReturnValueHandler.
Recommended Posts