NutzCN Logo
问答 filter里面获取request里的body里的内容后,接口就获取不到参数了。
发布于 262天前 作者 ganchaoyang 245 次浏览 复制 上一个帖子 下一个帖子
标签:

我在filter里面通过如下代码获取request里的body里的内容后,接口就获取不到参数了。

try {
            payload = Json.toJson(Json.fromJson(Streams.utf8r(request.getInputStream())));
        } catch (IOException e) {
            e.printStackTrace();
            return new UTF8JsonView(JsonFormat.compact()).setData(Result.doError(106,"failed to get the request body."));
        }

下面是接口的部分代码

    @At("/sendshortmsg")
    @AdaptBy(type=JsonAdaptor.class)
    @Filters(@By(type = ApiFilter.class))
    public Object sendShortMessage(NutMap map){
7 回复

因为request.getInputStream()只能读取一次

这个有什么比较好的解决办法么?

办法总是有的,晚点写个demo给你看看

好的,谢谢。

public class MyJsonAdaptor extends JsonAdaptor {

    public Object getReferObject(    ServletContext sc,
                            HttpServletRequest req,
                            HttpServletResponse resp, String[] pathArgs) {
        Object obj = request.getAttribute("_my_json_object"); // 在Filter里面设置同名的对象
        if (obj != null)
            return obj;
        return super.getReferObject(sc, req, resp, pathArgs);
    }
}

我刚也找到了一种解决办法:
先定义一个类包含一个body域用于存储request.getInputStream()的内容,继承自HttpServletRequestWrapper,并且覆盖它的getInputStream()方法。

public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper{

    private final byte[] body;

    public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        body = Streams.readBytes(request.getInputStream());
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        final ByteArrayInputStream bais = new ByteArrayInputStream(body);
        return new ServletInputStream() {
            @Override
            public int read() throws IOException {
                return bais.read();
            }
        };
    }
}

然后在filter里面替换掉actionContext里面的request

try {
            requestWrapper = new BodyReaderHttpServletRequestWrapper(request);
            actionContext.setRequest((HttpServletRequest) requestWrapper);
            payload = Json.toJson(Json.fromJson(Streams.utf8r(requestWrapper.getInputStream())));
        } catch (IOException e) {
            e.printStackTrace();
            return new UTF8JsonView(JsonFormat.compact()).setData(Result.doError(106,"failed to get the request body."));
        }

嗯, 这种办法耗内存多一些

添加回复
请先登陆
回到顶部