天天看點

SpringMVC架構Consoller層傳回格式和@ResponseBody注解的使用

最近自己從零開始搭建工程的時候,發現前端調用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是我定義的一個傳回結果對象。如下圖:

SpringMVC架構Consoller層傳回格式和@ResponseBody注解的使用

後倆就稍微修改了一下,在接口加上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:

SpringMVC架構Consoller層傳回格式和@ResponseBody注解的使用

繼續閱讀