java - Spring Ajax - @ResponseBody - 返回空响应

标签 java ajax spring spring-mvc jackson

在我的 spring webapp 中,我有一个响应 json 的 ajax servlet(使用 jackson):

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:util="http://www.springframework.org/schema/util" xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">

    <context:component-scan base-package="com.myapp.ajax" />

    <util:list id="messageConvertersList">
        <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
            <property name="supportedMediaTypes">
                <list>
                    <value>application/json;charset=UTF-8</value>
                </list>
            </property>
        </bean>
    </util:list>

    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
        <property name="messageConverters" ref="messageConvertersList" />
    </bean>
    <bean id="handlerMapping" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" />

    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**" />
            <bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
                <property name="paramName" value="lang" />
            </bean>
        </mvc:interceptor>
    </mvc:interceptors>

    <bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver" />

    <bean id="handlerExceptionResolver" class="com.myapp.ajax.AjaxExceptionHandlerResolver">
        <property name="exceptionHandler">
            <bean class="com.myapp.ajax.AjaxExceptionHandler" />
        </property>
        <property name="messageConverters" ref="messageConvertersList" />
    </bean>

我有以下 ajax 服务:

@RequestMapping(value = "getLoggedUser")
@ResponseBody
public DtoUser getLoggedUser() {
    return authenticationService.getLoggedUser();
}

当用户登录时,它返回如下内容:

{ userName : "jojo", email : "john.doe@email.com", firstName : "John", lastName : "Doe" }

当用户未登录时,预期的行为是返回

null

但它返回一个空响应,这不是一个有效的 JSON 响应(并且还有一个错误的 Content-type header )

为什么会这样?
我是否有获得预期行为的解决方案?

最佳答案

When the user is not logged in, the expected behavior is to return null

这是我预期的行为,因为在 Java 和 Javascript/JSON 中,null 是一个有效值,它与无、空或错误/异常的含义不同。

我希望 Spring 回答空响应而不是专门处理它。 在这种情况下,null (Java) 的预期转换将为 null (JSON)
我预期的转换表:

Java Exception => HTTP Error Code
null => null
empty map / object => {}
void => no response


Why is this happening ?

对于 Spring,返回 null 的 Controller 意味着“无响应”而不是“值为 null 的响应”。此规则适用于所有 Controller 方法,包括带有 @ResponseBody 注释的方法。
这允许手动写入响应,而无需稍后在响应中附加任何内容:

if (mySpecialCase) {
    Writer writer = response.getWriter();
    writer.write("my custom response");
    return null;
} else {
     return myObject;
}

因此,当返回 null 时,Spring 不向响应写入任何内容,Content-type header 和正文也不写入。

Do I have solutions to obtain the expected behaviour ?

我做了以下肮脏的 hack:在我的 ajax 路径上添加一个过滤器,当没有提交响应时将 null 写入响应。

public class AjaxEmptyResponseFilter implements Filter {

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        chain.doFilter(request, response);
        if (!response.isCommitted()) {
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json");
            Writer writer = response.getWriter();
            writer.write("null");
            writer.close();
            response.flushBuffer();
        }
    }

}

此解决方案以相同的方式处理回答 null 的方法和不回答任何内容 (void) 的方法。

关于java - Spring Ajax - @ResponseBody - 返回空响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14708827/

相关文章:

java - OSGi/Eclipse RCP 环境中的 Resteasy 客户端

javascript - 在选择特定单选按钮选择时动态更新 html 页面上的图像

ajax - 我正在寻找支持协作的基于 Web 的文本编辑器

java - 如何在一次测试中启动2个Spring Boot应用程序?

java - Alfresco openCMIS 连接到主文件夹

Java:如何在显示页面时发送POST请求?

java - http get 返回 403

java - 如何获取 View 的宽度和高度

javascript - ajax函数的问题

eclipse - JUnit 测试用例在 eclipse 中通过,但在 Maven 构建中失败