HandlerInterceptorAdapter,JSON编码和后处理响应 [英] HandlerInterceptorAdapter, JSON encoding and post processing of response

查看:1920
本文介绍了HandlerInterceptorAdapter,JSON编码和后处理响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个如下构建的Spring控制器:

I had a Spring controller built like follows:

@RequestMapping(value = "/rest/funf/{datatype}", method = RequestMethod.GET)
public ModelAndView getFunfData(@PathVariable("datatype") String dataType,
        WebRequest request) throws HttpException {

我还有一个 HandlerInterceptorAdapter 执行前处理和后处理(根据策略修改返回的模型)。后处理处理程序的签名如下:

I also had a HandlerInterceptorAdapter that performed pre and post-processing (modifying the returned model according to a policy). The signature for the post-process handler is the following

@Override
public void postHandle(HttpServletRequest request,
        HttpServletResponse response, Object handler,
        ModelAndView modelAndView) throws Exception {

它实际上有效好。 REST API返回了一个结构不合理的JSON有效负载,但至少拦截器(策略执行点)能够从模型中匿名(剥离用户个人数据)并替换它。

It actually worked well. The REST API returned a not-well-structured JSON payload but at least the interceptor (a Policy Enforcement Point) was able to anonymise (strip user personal data) from the model and replaced it.

关键在于,使用旧设计,我能够在将响应发送到输出之前检索响应,修改并将其重新注入 ModelAndView 实例。无需为了简洁而发布代码。

The point is that with the old design I was able to retrieve response before it was sent to the output, modify and reinject it into the ModelAndView instance. No need to post code for brevity.

现在我发现了一个可以帮助我的新设计克服了响应结构中的缺陷。

Now I discovered a new design that helps me overcome a flaw in the response structure.

当我有返回新的ModelAndView(jacksonView_instance,data,dataToConvertToJson)它的结构类似于

{
    "data": {
        "myAttr1":"myVal1"
     }
}

当接收程序想要转换时,这是不好的有效负载到JSON。所以我找到了

which is bad when the receiving program wants to convert the payload to JSON. So I found

@RequestMapping(value = "/rest/funf/{datatype}", method = RequestMethod.GET, produces = { "application/json" })
    public @ResponseBody
    Object[] getFunfData(@PathVariable("datatype") String dataType,
            WebRequest request) throws HttpException {

这个简化的代码有点而且最重要的是使得响应结构良好,如

This simplified code a little and most importantly made the response well structured, like

{
    "myAttr1":"myVal1"
}

REST设计合约完全可以,但是

That is perfectly OK with REST design contract, but

现在,HandlerInterceptor将无法再检索模型,从而无法检索我从API返回的对象(它是 FUNF 相关的API,用于处理移动设备上记录的个人数据,甚至是敏感的。)

Now the HandlerInterceptor won't be able any more to retrieve the model and thus the object I return from my API (it's a FUNF-related API that handles personal data, even sensitive, recorded on mobile devices).

因此,如果我需要匿名记录我不能在国际刑警组织中做到这一点像之前的eptor

So if I need to anonymise records I can't do it in the interceptor like before

我知道我可以杀死拦截器并执行策略执行API,但这不是一个很好的设计,即使是在 preHandle 中执行授权的PEP和 postHandle 目前是一个自动实例化的Spring对象。在处理多个API时复制和粘贴API中的代码是一个坏主意,并且在中期可能会更改/扩展PEP实现。

I am conscious I can kill the interceptor and perform policy enforcement right in the API, but this is not a great design, even since the PEP that performs authorization in the preHandle and obligation enforcement in the postHandle is currently a Spring object automagically instantiated. Copying and pasting code in the API is a bad idea when dealing with multiple APIs and the possibility in the middle-term to change/extend the PEP implementation.

无论如何,让我们在很好地解释了上下文之后提出了一个直接的问题

Anyway, let's formulate a straight question after having explained the context well

给定一个通用的Spring MVC API返回由内容协商者处理的对象

Given a generic Spring MVC API that returns an object to be handled by a content negotiator

@RequestMapping(value = "/path/{variable}", method = RequestMethod.GET)
public @ResponseBody Object api() {

我怎么能拦截在外部类中返回对象以对其执行修改? (例如,用要返回给客户的新对象实例替换)

how can I intercept that returned object in an external class to perform modifications to it? (e.g. replace with a new object instance to be returned to client)

推荐答案

看起来这是可能在Spring MVC中。我刚看到调试会话中的代码。

Looks like this is not possible in Spring MVC. I have just seen the code in a debug session.

当你使用 ModelAndView 时,Spring MVC将MaV存储在一个直到 postHandle 的变量,然后写在响应正文中。

When you use ModelAndView, Spring MVC stores the MaV in a variable that lives till postHandle and then is written in response body.

相反,当你使用<$ c时$ c> @ResponseBody 并返回值,该值在调用周期中直接处理,使用 MessageConverter 写入响应。

Instead, when you use @ResponseBody and return value that value is handled directly in the invocation cycle, using a MessageConverter to be written to the response.

由于响应是单向网络流,因此拦截它是为时已晚。

Since the response is a one-way network stream, it's too late for intercepting it.

解决方案应该是基于与处理程序不同的方法,如AOP 拦截器直接应用于控制器方法。

The solution should be based on a different approach than the handlers, like AOP interceptors applied directly to controller methods.

这篇关于HandlerInterceptorAdapter,JSON编码和后处理响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆