【问题标题】:How to intercept HttpEntity from json response [duplicate]如何从json响应中拦截HttpEntity [重复]
【发布时间】:2013-08-14 07:19:37
【问题描述】:

我正在使用 Spring 设置,使用 json 映射转换器将 POJO 类作为 json 发送回客户端。

例如:

@RequestMapping
@ResponseBody
public User getUser() {
    User user = getUser();
    return user;
}

这将返回例如像给客户的东西:

{ 'username': 'My username', 'lastname': 'My lastname' }

我想拦截我的所有控制器操作以将 json 包装成如下内容:

{
  'status': 200,
  'data': { 'username': 'My username', 'lastname': 'My lastname' }
}

最好的方法是什么?

【问题讨论】:

  • 为什么? HTTP 状态将是 HTTP 响应的一部分。

标签: json spring rest spring-mvc


【解决方案1】:

很简单,你可以像这样创建地图

@RequestMapping(value = "/user")
@ResponseBody
public Map<String, Object> getUser(){
    User user = new User();
    Map<String, Object> map = new HashMap<String, Object>();
    map.put("status", 200);
    map.put("data", user);
    return map;
}

一般使用,可以创建一个POJO

    public static class ResutInfo{
    private int status;
    private Object data;

   //get set}

然后编写控制器方法

@RequestMapping(value = "/user")
@ResponseBody
public ResutInfo getUser2(){
    User user = new User();
    ResutInfo resutInfo = new ResutInfo();
    resutInfo.setStatus(200);
    resutInfo.setData(user);
    return resutInfo;
}

【讨论】:

  • 是的,这会起作用,但是我必须在每个控制器中都这样做。我正在寻找更复杂的实现,例如拦截响应?
  • 我试过HandlerInterceptorAdapter.postHandler()。但它不起作用。因为您无法通过控制器方法获得 Object 返回。我认为你应该尝试使用 AspectJ 来处理结果。
【解决方案2】:

我通过扩展MappingJackson2HttpMessageConverter为您的问题找到可能的解决方案

public class MyMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter {
    @Override
    protected void writeInternal(Object object, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
        //outputMessage.getHeaders().add("code", DigestUtils.md5Hex(object.toString()));
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("status", 200);
        map.put("data", object);
        super.writeInternal(map, outputMessage);    //To change body of overridden methods use File | Settings | File Templates.
    }
}

然后将你自己的 conventer bean 添加到 spring-mvc 配置文件中

<mvc:annotation-driven>
    <mvc:message-converters register-defaults="true">
        <bean class="com.xxx.utils.MyMappingJackson2HttpMessageConverter">
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>
<mvc:default-servlet-handler/>

此方法适用于每个 @ResponseBody 处理程序方法。

注意它改变了默认的 Spring 动作,你应该考虑一下。

【讨论】:

  • 感谢拉里,这似乎是拦截写入(或更好地转换)响应和添加内容的最佳方式。 /M
  • 虽然这可以为响应添加一些内容,但问题是我无法再获得实际响应。因此也无法根据响应的原始状态设置状态。
【解决方案3】:
You can also do something like this

<mvc:annotation-driven>  <!-- this is added for validations to work -->
    <mvc:message-converters register-defaults="true">
        <ref bean="jsonMessageConverter"/>
    </mvc:message-converters>
    </mvc:annotation-driven>

<bean id="jsonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
         <property name="objectMapper" ref="YourDtoWrapper"/> 
</bean>

<bean id="YourDtoWrapper" class="com.YourDtoWrapper"/>

inside your YourDtoWrapper class you can do something like this


public void writeValue(JsonGenerator jgen, Object value) throws IOException, JsonGenerationException, JsonMappingException {

        SomeDTO<Object> someDto = new SomeDTO<Object>("SUCCESS");//you can use an enum here
        someDto.setDto(value);//here dto is a property of someDTO

        super.writeValue(jgen, SomeDTO.getAsMap(someDto));
    }

this will give u result some thing like this

{
serviceResult: "SUCCESS"
context: null
dto: {
id: 1
firstName: "test"
lastName: "admin"
email: "admin@test.com"
phone: 1234
userName: "admin"
password: null
createdBy: "admin"
createdDate: null
statusId: 1
statusName: "ACTIVE"
organisationId: 1
organisationName: "test"
userTypeId: 1
userTypeName: "ADMIN"
roleIds: [0]
}
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-06
    • 2022-07-12
    • 2014-06-27
    • 2013-06-18
    • 2012-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多