Тело ответа фильтра весенней загрузки приложения - PullRequest
0 голосов
/ 28 апреля 2020

Я работаю над приложением весенней загрузки. Я хочу изменить ответ на запрос с помощью поля тела запроса "Id".

Я реализовал ниже, но все еще получаю только имя в выводе при реализации. Любые предложения по реализации ниже будут полезны:

Ниже requestBody:

{
"id" : "123"
}

В ответ я хочу добавить это поле к идентификатору ответа (имя поля из тела запроса). responseBody:

{
"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);
}

MyRequestWrapper:

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

public class MultiReadHttpServletRequest extends HttpServletRequestWrapper {

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();
        }
    };
}

}

Любые предложения приветствуются. ТИА. Nte: После обновления я не могу видеть обновленный ответ как вывод. Я все еще вижу только имя, но не идентификатор, добавленный к нему.

1 Ответ

0 голосов
/ 28 апреля 2020

Единственная проблема, которую я вижу с вашей собственной реализацией ServletRequest, заключается в том, что вы вызываете super.getInputStream() вместо 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;
    }
}
...