当前位置: 首页 > 知识库问答 >
问题:

Spring启动应用程序过滤器响应正文

柯浩壤
2023-03-14

我正在开发一个Spring启动应用程序。我想通过请求正文字段“Id”修改请求的响应。

我已经实现了下面的代码,但是在实现的时候输出的仍然只是名字。任何关于实施以下内容的建议都会有所帮助:

下面是请求体:

{
"id" : "123"
}

作为响应,我想将该字段附加到响应id(来自请求正文的字段名)。响应体:

{
"name" : "foo123"  //name + id from request
}

MyCustomFilter:

public class TestFilter implements Filter {


    @Override
    public void doFilter(
            ServletRequest request,
            ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
       HttpServletResponse res = (HttpServletResponse) response;
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    final PrintStream ps = new PrintStream(baos);
    MultiReadHttpServletRequest wrapper = new MultiReadHttpServletRequest((HttpServletRequest) request);

    MyRequestWrapper req = new MyRequestWrapper(wrapper);
    String userId = req.getId();

    chain.doFilter(wrapper, new HttpServletResponseWrapper(res) {
        @Override
        public ServletOutputStream getOutputStream() throws IOException {
            return new DelegatingServletOutputStream(new TeeOutputStream(super.getOutputStream(), ps)
            );
        }

        @Override
        public PrintWriter getWriter() throws IOException {
            return new PrintWriter(new DelegatingServletOutputStream(new TeeOutputStream(super.getOutputStream(), ps))
            );
        }
    });

    String responseBody = baos.toString();

    ObjectMapper mapper = new ObjectMapper();
    JsonNode node = mapper.readTree(responseBody);
    String name = node.get("name").astext();

    ((ObjectNode) node1).put("name", name + userId);

    chain.doFilter(wrapper, res);
}

我的请求包装:

public class MyRequestWrapper extends HttpServletRequestWrapper {
    private ServletInputStream input;

    public MyRequestWrapper(ServletRequest request) {
        super((HttpServletRequest)request);
    }

    public String getId() throws IOException {
        if (input == null) {
            try {
                JSONObject jsonObject = new JSONObject(IOUtils.toString(super.getInputStream()));
                String userId = jsonObject.getString("id");

                userId = userId.replaceAll("\\D+","");
                return userId;
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}

MultiReadHttpServletRequest.java

公共类MultiReadHttpServletRequest扩展HttpServletRequest Wrapper{

private byte[] body;

public MultiReadHttpServletRequest(HttpServletRequest request) {
    super(request);
    try {
        body = IOUtils.toByteArray(request.getInputStream());
    } catch (IOException ex) {
        body = new byte[0];
    }
}

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

@Override
public ServletInputStream getInputStream() throws IOException {
    return new ServletInputStream() {
        ByteArrayInputStream wrapperStream = new ByteArrayInputStream(body);

        @Override
        public boolean isFinished() {
            return false;
        }

        @Override
        public boolean isReady() {
            return false;
        }

        @Override
        public void setReadListener(ReadListener readListener) {

        }

        @Override
        public int read() throws IOException {
            return wrapperStream.read();
        }
    };
}

}

感谢任何建议。TIA。Nte:更新后,我无法将更新的响应视为输出。我仍然只能看到名称,但没有附加到它的ID。

共有1个答案

宋育
2023-03-14

我在您自己的ServletRequest实现中看到的一个问题是,您调用了< code > super . getinputstream()而不是< code > request . getinputstream()。您自己的请求默认为空,这就是您得到超时异常的原因。您必须将呼叫委托给实际的请求:

public class MyRequestWrapper extends HttpServletRequestWrapper {
    private ServletInputStream input;

    public MyRequestWrapper(ServletRequest request) {
        super((HttpServletRequest)request);
    }

    public String getId() throws IOException {
        if (input == null) {
            try {
                JSONObject jsonObject = new JSONObject(IOUtils.toString(/*DELETEGATE TO ACTUAL REQUEST*/request.getInputStream()));
                String userId = jsonObject.getString("id");

                userId = userId.replaceAll("\\D+","");
                return userId;
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}
 类似资料:
  • 我是spring的初学者,希望这样做示例项目…我有一个数据库,我想连接到它…我使用了像AutoWired和service这样的注释。但有个问题我解决不了 Controller包中的RegisterationController具有我要调用的服务: 第一个包中的DataManagement类: 第一包中的StudentAccountRepository: 第一包中得学生帐户..引用数据库中的表: M

  • 我有一个spring启动应用程序,我需要通过进入文件夹目录并通过命令行启动我的web应用程序来启动它。我有一门课叫应用。java及其内部代码如下所示。 我设置了类路径,然后试图运行命令"",但我得到了这个错误消息""

  • 我在intellij上启动spring boot应用程序时遇到问题,它失败了,并显示以下消息:与目标VM断开连接,地址:'127.0.0.1:49784',传输:'socket' 过程结束,退出代码为255。以前有人遇到过这种情况吗?

  • 运行时 当前的spring boot应用程序可以用当前的URL在浏览器中打开 但不是

  • 我有一个quarkus应用程序,当我用下面的命令构建应用程序时,进程第一次开始完美地编译quarkus:dev-DskipTests=true 成功启动的日志: 但是当我停下来重新开始这个过程时,过程并没有开始... 启动失败的日志: 当我尝试重新启动机器,然后启动quarkus服务时,它会再次工作。 pom。xml: 如果有人遇到过类似的行为,请告诉我,这可能是什么根源。

  • 我有下面的servlet过滤器。