最近自己从零开始搭建工程的时候,发现前端调用conroller层接口,不加@ResponseBody,报404错误,调不到,只有加上@ResponseBody才能正常调用成功。
@ResponseBody官网是这样解释的:
Mapping the response body with the @ResponseBody annotation
The @ResponseBody annotation is similar to @RequestBody. This annotation can be put on a method
and indicates that the return type should be written straight to the HTTP response body (and not placed
in a Model, or interpreted as a view name). For example:
@RequestMapping(value = "/something", method = RequestMethod.PUT)
@ResponseBody
public String helloWorld() {
return "Hello World";
}
The above example will result in the text Hello World being written to the HTTP response stream.
As with @RequestBody, Spring converts the returned object to a response body by using an
HttpMessageConverter. For more information on these converters, see the previous section and
Message Converters.
也就是说,将返回的数据要给到前端显示必须要先转换为HTTP协议的返回格式,使用@ResponseBody注解就可以减少自己去写这个转换的方法了,简而言之,注解起到了一个@ResponseBody消息转换器的作用。
这就解释了不加@ResponseBody调不成功的原因。而有的项目是不加@ResponseBody 前端也是能调用成功的;后来百度了一下 配置一下 org.springframework.web.servlet.view.ContentNegotiatingViewResolver 就可以了。如果不配置 ContentNegotiatingViewResolver 那controller里面方法就需要加上 @ResponseBody了。
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="viewResolvers">
<list>
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- <property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/> -->
</bean>
</list>
</property>
<property name="defaultViews">
<list>
<bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView" />
</list>
</property>
</bean>
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="favorParameter" value="true"/>
<property name="parameterName" value="format"/>
<property name="ignoreAcceptHeader" value="false"/>
<property name="mediaTypes">
<value>
json=application/json
xml=application/xml
html=text/html
</value>
</property>
<property name="defaultContentType" value="text/html"/>
</bean>
将不加@ResponseBody的接口的使用记录一下:
一开始将返回类型设置成一个对象,
@RequestMapping("/logout")
// @ResponseBody
public Resp logout(@ModelAttribute("clientIpAddress") String clientIpAddress,
String userId)
{
Resp res = new Resp();
try {
HttpSession session = request.getSession();
session.invalidate();
} catch (Exception e) {
e.printStackTrace();
}
return res;
}
但是在返现返回前台时候发现多了一层该对象的名字resp是我定义的一个返回结果对象。如下图:
后俩就稍微修改了一下,在接口加上ModelMap, 如果不熟悉ModelMap可以去了解一下。
@RequestMapping("/logout")
// @ResponseBody
public String logout(@ModelAttribute("clientIpAddress") String clientIpAddress,
String userId, ModelMap modelMap)
{
Resp res = new Resp();
try {
HttpSession session = request.getSession();
session.invalidate();
modelMap.put("retCode","0");
} catch (Exception e) {
e.printStackTrace();
modelMap.put("retCode","1");
modelMap.put("errorMsg", e.getStackTrace());
}
return "list";
}
这样在前端接收的就是返回的一个个key-value: