Joh*_*n O 2 java servlets character-encoding wrapper servlet-filters
Servlet响应包装器正在Servlet过滤器中使用.这个想法是响应被操纵,并将"nonce"值注入表单中,作为防御CSRF攻击的一部分.
Web应用程序在任何地方都使用UTF-8.当Servlet过滤器不存在时,没有问题.添加过滤器时,会出现编码问题.(似乎响应回复到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);
...
}
...
}
Run Code Online (Sandbox Code Playgroud)
据我了解,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;
}
}
Run Code Online (Sandbox Code Playgroud)
来自new PrintWriter(OutputStream)javadoc:
从现有的OutputStream创建一个没有自动行刷新的新PrintWriter.此便捷构造函数创建必要的中间OutputStreamWriter,它将使用默认字符编码将字符转换为字节.
这是你的罪魁祸首.看看OutputStreamWriter你可以在哪里指定编码.
| 归档时间: |
|
| 查看次数: |
3846 次 |
| 最近记录: |