Java SpringMVC返回JSON和异常处理

Java SpringMVC返回JSON和异常处理,java,json,spring,spring-mvc,exception-handling,Java,Json,Spring,Spring Mvc,Exception Handling,我将SpringMVC与控制器一起使用,我的问题是如何返回JSON响应,这与@ResponseBody对象不同,后者被返回并转换为要返回的JSON 为了进一步说明,我有一个名为“UserDetails”的对象,它有两个名为“name”、“emailAddress”的字段 现在返回的json如下所示 {name:“TheUsersName”, 电子邮件地址:“abc@abc123.com“} 在返回(所有控制器中所有方法中的所有json)之前,是否有任何方法可以修改json,其中将添加一个“sta

我将SpringMVC与控制器一起使用,我的问题是如何返回JSON响应,这与@ResponseBody对象不同,后者被返回并转换为要返回的JSON

为了进一步说明,我有一个名为“UserDetails”的对象,它有两个名为“name”、“emailAddress”的字段

现在返回的json如下所示

{name:“TheUsersName”, 电子邮件地址:“abc@abc123.com“}

在返回(所有控制器中所有方法中的所有json)之前,是否有任何方法可以修改json,其中将添加一个“status”字段,其他json数据将位于json中的“data”键下


还有,当java服务器从某处抛出异常时,如何将json返回到前端,json应该有“status:false”和异常名称(至少是status部分)

Yes。而是返回模型和视图

public ModelMap getUserDetails() {
    UserDetails userDetails; // get this object from somewhere
    ModelMap map = new ModelMap()(;
    map.addAttribute("data", userDetails);
    map.addAttribute("success", true);
    return map;
}

要添加异常,您可以使用键和success=false以相同的方式进行添加。

创建一个响应类:

public class Response<T> {
    T data;
    boolean status = true;

    public Response(T d) { data = d; }
}
对于例外情况,您需要返回如下对象:

public class BadStatus {
    String errorMessage;
    boolean status = false;

    public BadStatus(String msg) { errorMessage = msg; }
}

@ExceptionHandler(Exception.class)
public BadStatus handleException(Exception ex, HttpServletRequest request) {
  return new BadStatus(ex.getMessage());
}
另一种解决方案(与spring 3.1配合使用),其侵入性较小

在spring配置中:

<bean id="jacksonConverter"     class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />
<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="mypackage.MyMessageConverter"
            p:delegate-ref="jacksonConverter">
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

其想法是提供您自己的HttpMessageConverter,委托给提供的jackson转换器

public class MyMessageConverter implements HttpMessageConverter<Object> {
// setters and delegating overrides ommitted for brevity
@Override
    public void write(Object t, MediaType contentType, HttpOutputMessage outputMessage) throws IOException,
            HttpMessageNotWritableException {
// t is whatever your @ResponseBody annotated methods return
        MyPojoWrapper response = new MyPojoWrapper(t);

        delegate.write(response, contentType, outputMessage);
    }
}
公共类MyMessageConverter实现HttpMessageConverter{
//设定者和授权覆盖为简洁起见
@凌驾
public void write(对象t、MediaType contentType、HttpOutputMessage outputMessage)引发IOException,
HttpMessageWritableException{
//t是@ResponseBody注释方法返回的值
MyPojoWrapper响应=新的MyPojoWrapper(t);
write(响应、内容类型、输出消息);
}
}
通过这种方式,您的所有POJO都使用您在那里提供的其他json进行包装

对于例外情况,ericacm提出的解决方案是最简单的方法(记住用@ResponseBy注释'BadStatus'返回类型)


警告:json序列化的BadStatus也会通过MyMessageConverter,因此您需要在重写的“write”方法中测试对象类型,或者让MyPojoWrapper处理该类型。

我看不到这里添加了什么值
ModelAndView
。为什么不直接返回
ModelMap
?我不确定我为什么要使用ModelAndView,但是你给了我使用map(HashMap)的想法,它工作起来很有魅力,并给了我想要的输出。然而,在失败的情况下,我如何做同样的事情?但是,对于所有控制器和控制器中的所有函数,有没有办法将其集中化?@skaffman你说得对。大脑也会从返回的视图中放屁@milindaD ModelMap不需要键,但没有太大不同。它实现了映射。有关更详细的答案,请参阅此线程:可能相关:
<bean id="jacksonConverter"     class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />
<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="mypackage.MyMessageConverter"
            p:delegate-ref="jacksonConverter">
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>
public class MyMessageConverter implements HttpMessageConverter<Object> {
// setters and delegating overrides ommitted for brevity
@Override
    public void write(Object t, MediaType contentType, HttpOutputMessage outputMessage) throws IOException,
            HttpMessageNotWritableException {
// t is whatever your @ResponseBody annotated methods return
        MyPojoWrapper response = new MyPojoWrapper(t);

        delegate.write(response, contentType, outputMessage);
    }
}