Im Spring Security-Autorisierungsprozess (Abstimmungsklasse usw.) Ich denke, es gibt Fälle, in denen Sie sich auf den Text der Anfrage beziehen müssen. (Zum Beispiel beim Aktualisieren der Datenbank mit POST oder PUT usw.
In der HttpServletRequest-Klasse jedoch Der Körper ist ein Strom und kann nur einmal gelesen werden.
Dieses Mal werde ich vorstellen, wie man Body mehrmals liest.
① Halten Sie die von Body gelesenen Informationen (2) Ersetzen Sie die Körpererfassungsquelle durch die Informationen in (1).
Stream-Klasse Wird beim Aufrufen von HttpServletRequest.getInputStream () als Rückgabetyp festgelegt. Verwenden Sie das Byte-Array zur Initialisierung
BufferedServletInputStream.java
public class BufferedServletInputStream extends ServletInputStream {
private ByteArrayInputStream inputStream;
//Mit Byte-Array initialisieren
public BufferedServletInputStream(byte[] buffer) {
this.inputStream = new ByteArrayInputStream(buffer);
}
@Override
public int available() throws IOException {
return inputStream.available();
}
@Override
public int read() throws IOException {
return inputStream.read();
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
return inputStream.read(b, off, len);
}
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener listener) {
}
}
Wrapper-Klasse für HttpServletRequest
BufferedServletRequestWrapper.java
public class BufferedServletRequestWrapper extends HttpServletRequestWrapper {
private byte[] buffer;
public BufferedServletRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
//Holen Sie sich Stream von Request Body
InputStream is = request.getInputStream();
//Konvertieren Sie Stream in ein Byte-Array und behalten Sie es in der Instanzvariablen bei
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte buff[] = new byte[1024];
int read;
while ((read = is.read(buff)) > 0) {
baos.write(buff, 0, read);
}
this.buffer = baos.toByteArray();
}
//Ersetzen Sie die Körpererfassungsquelle durch diese Methode
@Override
public ServletInputStream getInputStream() throws IOException {
//Stream-Klasse initialisieren und zurückgeben
return new BufferedServletInputStream(this.buffer);
}
}
Filterklasse Auf Anfrage durch OncePerRequestFilter ersetzen
MultipleReadEnableFilter.java
@Component
public class MultipleReadEnableFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
//Initialisieren Sie die Wrapper-Klasse von HttpServletRequest
HttpServletRequest wrappedRequest = new BufferedServletRequestWrapper((HttpServletRequest) request);
filterChain.doFilter(wrappedRequest, response);
}
}
Legen Sie den erstellten Filter in der Einstellungsklasse Spring Security fest
//Wrap, um inputStream mehrmals zu lesen
http.addFilter(multipleReadEnableFilter);
Recommended Posts