Masalah:
Dalam penapis Servlet Java, mengakses permintaan HTTP parameter daripada badan permintaan POST boleh menyebabkan parameter tidak tersedia kemudian dalam rantaian penapis. Ini berlaku kerana badan permintaan digunakan semasa bacaan awal.
Penyelesaian:
Untuk mengatasi isu ini dan membolehkan bacaan berbilang parameter badan permintaan, penyelesaian melibatkan melanjutkan HttpServletRequestWrapper dan menyimpan bait aliran input. Berikut ialah kelas pembungkus permintaan tersuai:
public class MultiReadHttpServletRequest extends HttpServletRequestWrapper { private ByteArrayOutputStream cachedBytes; public MultiReadHttpServletRequest(HttpServletRequest request) { super(request); } @Override public ServletInputStream getInputStream() throws IOException { if (cachedBytes == null) cacheInputStream(); return new CachedServletInputStream(cachedBytes.toByteArray()); } @Override public BufferedReader getReader() throws IOException{ return new BufferedReader(new InputStreamReader(getInputStream())); } private void cacheInputStream() throws IOException { cachedBytes = new ByteArrayOutputStream(); IOUtils.copy(super.getInputStream(), cachedBytes); } /* An input stream which reads the cached request body */ private static class CachedServletInputStream extends ServletInputStream { private final ByteArrayInputStream buffer; public CachedServletInputStream(byte[] contents) { this.buffer = new ByteArrayInputStream(contents); } @Override public int read() { return buffer.read(); } @Override public boolean isFinished() { return buffer.available() == 0; } @Override public boolean isReady() { return true; } @Override public void setReadListener(ReadListener listener) { throw new RuntimeException("Not implemented"); } } }
Penggunaan:
Balut permintaan asal dengan pembungkus tersuai sebelum meneruskannya melalui rantai penapis:
public class MyFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { MultiReadHttpServletRequest multiReadRequest = new MultiReadHttpServletRequest((HttpServletRequest) request); doMyThing(multiReadRequest.getInputStream()); chain.doFilter(multiReadRequest, response); } }
Ini membolehkan berbilang bacaan badan permintaan, sama ada melalui getInputStream() atau getReader() kaedah.
Nota:
Untuk versi baharu antara muka ServletInputStream, kaedah tambahan seperti isReady() dan setReadListener() perlu dilaksanakan dalam kelas aliran input tersuai . Rujuk pautan yang disediakan dalam jawapan untuk butiran.
Atas ialah kandungan terperinci Bagaimana untuk Mendayakan Bacaan Berbilang Badan Permintaan POST dalam Penapis Servlet Java?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!