gpt4 book ai didi

java - Servlet 响应包装器存在编码问题

转载 作者:行者123 更新时间:2023-11-30 06:36:36 24 4
gpt4 key购买 nike

在 Servlet 过滤器中使用了 servlet 响应包装器。这个想法是响应被操纵,将“nonce”值注入(inject)表单,作为防御 CSRF 攻击的一部分。

Web 应用到处都使用 UTF-8。当 Servlet Filter 不存在时,没有问题。添加过滤器后,会出现编码问题。 (似乎响应恢复到 8859-1。)

代码的核心:

final class CsrfResponseWrapper extends AbstractResponseWrapper {
...
byte[] modifyResponse(byte[] aInputResponse){
...
String originalInput = new String(aInputResponse, encoding);
String modifiedResult = addHiddenParamToPostedForms(originalInput);
result = modifiedResult.getBytes(encoding);
...
}
...
}

据我了解,byte-land 和 String-land 之间的转换应该指定一种编码。如您所见,这是在两个地方完成的。 'encoding'变量的值为'UTF-8'; String 本身的更改是标准字符串操作(使用正则表达式),并且从不指定编码 (addHiddenParamToPostedForms)。

我在哪里编码有误?

编辑:这是基类(抱歉它有点长):

package hirondelle.web4j.security;

import javax.servlet.ServletOutputStream;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintWriter;

/**
Abstract Base Class for altering response content.
(May be useful in future contexts as well. For now, keep package-private.)
*/
abstract class AbstractResponseWrapper extends HttpServletResponseWrapper {

AbstractResponseWrapper(ServletResponse aServletResponse) throws IOException {
super((HttpServletResponse)aServletResponse);
fOutputStream = new ModifiedOutputStream(aServletResponse.getOutputStream());
fWriter = new PrintWriter(fOutputStream);
}

/** Return the modified response. */
abstract byte[] modifyResponse(byte[] aInputResponse);

/** Standard servlet method. */
public final ServletOutputStream getOutputStream() {
//fLogger.fine("Modified Response : Getting output stream.");
if ( fWriterReturned ) {
throw new IllegalStateException();
}
fOutputStreamReturned = true;
return fOutputStream;
}

/** Standard servlet method. */
public final PrintWriter getWriter() {
//fLogger.fine("Modified Response : Getting writer.");
if ( fOutputStreamReturned ) {
throw new IllegalStateException();
}
fWriterReturned = true;
return fWriter;
}

// PRIVATE

/*
Well-behaved servlets return either an OutputStream or a PrintWriter, but not both.
*/
private PrintWriter fWriter;
private ModifiedOutputStream fOutputStream;

/*
These items are used to implement conformance to the
javadoc for ServletResponse, regarding exceptions being thrown.
*/
private boolean fWriterReturned;
private boolean fOutputStreamReturned;

/** Modified low level output stream. */
private class ModifiedOutputStream extends ServletOutputStream {
public ModifiedOutputStream(ServletOutputStream aOutputStream) {
fServletOutputStream = aOutputStream;
fBuffer = new ByteArrayOutputStream();
}
/** Must be implemented to make this class concrete. */
public void write(int aByte) {
fBuffer.write(aByte);
}
public void close() throws IOException {
if ( !fIsClosed ){
processStream();
fServletOutputStream.close();
fIsClosed = true;
}
}
public void flush() throws IOException {
if ( fBuffer.size() != 0 ){
if ( !fIsClosed ) {
processStream();
fBuffer = new ByteArrayOutputStream();
}
}
}
/** Perform the core processing, by calling the abstract method. */
public void processStream() throws IOException {
fServletOutputStream.write(modifyResponse(fBuffer.toByteArray()));
fServletOutputStream.flush();
}
// PRIVATE //
private ServletOutputStream fServletOutputStream;
private ByteArrayOutputStream fBuffer;
/** Tracks if this stream has been closed. */
private boolean fIsClosed = false;
}
}

最佳答案

来自new PrintWriter(OutputStream) javadoc :

Creates a new PrintWriter, without automatic line flushing, from an existing OutputStream. This convenience constructor creates the necessary intermediate OutputStreamWriter, which will convert characters into bytes using the default character encoding.

这是你的罪魁祸首。看看OutputStreamWriter您可以在其中指定编码。

关于java - Servlet 响应包装器存在编码问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4697034/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com