내가 모든 입력을 캡처 한 후 모든 형태의 특별 토큰을 삽입, 그 입력을 난도질하는 서블릿 필터를 필요로 작동합니다. 필터가 모든 요청에 묶여 있다고 가정 해 보겠습니다 (예 : url-pattern=*
). 콘텐츠 캡처 용 코드가 있지만 RequestWrapper
처럼 모든 입력을 캡처 할 수있을만큼 강력하지는 않습니다. 일부 입력은 0 바이트를 반환하고 그 내용을 다시 사용자에게 "스트리밍"할 수 없습니다. 예를 들어, 우리는 여전히 Struts 1.3.10을 사용하고 있으며 Struts 코드는 적절하게 "포착"되지 않습니다. 우리는 0 바이트 내용을 얻습니다. Struts가 전달을 처리하는 방식 때문이라고 생각합니다. 요청에 포워드가 포함 된 경우 아래 캡처 코드가 작동하는지 궁금합니다. 모든 코드는 다음과 같습니다. 사용자에게 스트리밍하기위한 모든 유형의 콘텐츠를 캡처하는 접근 방식이 있습니까? 캐치 - 모든 서블릿 필터는 간헐적으로 만
<filter>
<filter-name>Filter</filter-name>
<filter-class>mybrokenCaptureHtml.TokenFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
package mybrokenCaptureHtml;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
public class TokenFilter implements Filter {
@Override
public void destroy() {
}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
try {
final MyResponseWrapper responseWrapper = new MyResponseWrapper((HttpServletResponse) response);
chain.doFilter(request, responseWrapper);
// **HERE DEPENDING ON THE SERVLET OR APPLICATION CODE (STRUTS, WICKET), the response returns an empty string //
// Especiall struts, is there something in their forwards that would cause an error?
final byte [] bytes = responseWrapper.toByteArray();
// For some applications that hit this filter
// ZERO BYTE DATA is returned, this is bad, but SOME
// CODE, the data is captured.
final String origHtml = new String(bytes);
final String newHtml = origHtml.replaceAll("(?i)</(\\s)*form(\\s)*>", "<input type=\"hidden\" name=\"zval\" value=\"fromSiteZ123\"/></form>");
response.getOutputStream().write(newHtml.getBytes());
} catch(final Exception e) {
e.printStackTrace();
}
return;
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
static class MyResponseWrapper extends HttpServletResponseWrapper {
private final MyPrintWriter pw = new MyPrintWriter();
public byte [] toByteArray() {
return pw.toByteArray();
}
public MyResponseWrapper(HttpServletResponse response) {
super(response);
}
@Override
public PrintWriter getWriter() {
return pw.getWriter();
}
@Override
public ServletOutputStream getOutputStream() {
return pw.getStream();
}
private static class MyPrintWriter {
private ByteArrayOutputStream baos = new ByteArrayOutputStream();
private PrintWriter pw = new PrintWriter(baos);
private ServletOutputStream sos = new MyServletStream(baos);
public PrintWriter getWriter() {
return pw;
}
public ServletOutputStream getStream() {
return sos;
}
byte[] toByteArray() {
return baos.toByteArray();
}
}
private static class MyServletStream extends ServletOutputStream {
ByteArrayOutputStream baos;
MyServletStream(final ByteArrayOutputStream baos) {
this.baos = baos;
}
@Override
public void write(final int param) throws IOException {
baos.write(param);
}
}
}
}
이 예는 (스트럿츠를하지 않음) 일부 응용 프로그램처럼 보일 수 있습니다 응용 프로그램을 스트럿츠 무엇
, 우리는 콘텐츠를 캡처 할 수 있습니다. 그러나 아래의 앱과 같은 경우 0 바이트가 HTML 콘텐츠로 반환되지만 콘텐츠는 있어야합니다.<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
<%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %>
<%@ taglib uri="/WEB-INF/struts-nested.tld" prefix="nested"%>
<html:html>
<head>
<title><bean:message key="myApp.customization.title" /></title>
<LINK rel="stylesheet" type="text/css" href="../theme/styles.css">
</head>
<body>
<html:form styleId="customizemyAppForm" method="post" action="/customizemyApp.do?step=submit">
<html:submit onclick="javascript:finish(this.form);" styleClass="input_small"> <bean:message key="myApp.customization.submit" /> </html:submit>
<input type="button" styleClass="input_small" width="80" style="WIDTH:80px" name="<bean:message key="myApp.customization.cancel" />" value="<bean:message key="myApp.customization.cancel" />" onclick="javascript:cancel();">
</html:form>
</body>
</html:html>
나는 MyResponseWrapper
과 MyPrintWriter
(가) 모든 유형의 콘텐츠를 캡처 할 수있을만큼 강력하지 않은 것으로 판단됩니다. 일하는 것이
예 서블릿 () :
response.getOutputStream().write(str.getBytes());
예 서블릿 작동하지 않을 것입니다 (B) :
response.getWriter().println("<html>data</html>");
예 얻을 것이다 캡처, 예제 b은 그렇지 않습니다.
여기에 대부분의 응용 프로그램은 작동하지만 지금은 스트럿 응용 프로그램의 일부는 만 응답의 일부는 브라우저로 전송되어, 개선 된 래퍼 클래스입니다.
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
public class ByteArrayResponseWrapper extends HttpServletResponseWrapper {
private PrintWriter output = null;
private ServletOutputStream outStream = null;
private static final String NL = System.getProperty("line.separator");
public ByteArrayResponseWrapper(final HttpServletResponse response) {
super(response);
}
public String getDocument() {
InputStream in = null;
try {
in = this.getInputStream();
if (in != null) {
return getDocument(in);
}
} catch(final Exception ee) {
// ee.print;StackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
//e.prin;tStackTrace();
}
}
}
return "";
}
protected String getDocument(final InputStream in) {
final StringBuffer buf = new StringBuffer();
BufferedReader br = null;
try {
String line = "";
br = new BufferedReader(new InputStreamReader(getInputStream(), this.getCharacterEncoding()));
while ((line = br.readLine()) != null) {
buf.append(line).append(NL);
}
} catch(final IOException e) {
//e.print;StackTrace();
} finally {
try {
if (br != null) {
br.close();
}
} catch (IOException ex) {
}
}
return buf.toString();
}
@Override
public PrintWriter getWriter() throws IOException {
if (output == null) {
output = new PrintWriter(new OutputStreamWriter(getOutputStream(), this.getCharacterEncoding()));
}
return output;
}
@Override
public ServletOutputStream getOutputStream() throws IOException {
if (outStream == null) {
outStream = new BufferingServletOutputStream();
}
return outStream;
}
public InputStream getInputStream() throws IOException {
final BufferingServletOutputStream out = (BufferingServletOutputStream) getOutputStream();
return new ByteArrayInputStream(out.getBuffer().toByteArray());
}
/**
* Implementation of ServletOutputStream that handles the in-memory
* buffering of the response content
*/
public static class BufferingServletOutputStream extends ServletOutputStream {
ByteArrayOutputStream out = null;
public BufferingServletOutputStream() {
this.out = new ByteArrayOutputStream();
}
public ByteArrayOutputStream getBuffer() {
return out;
}
public void write(int b) throws IOException {
out.write(b);
}
public void write(byte[] b) throws IOException {
out.write(b);
}
public void write(byte[] b, int off, int len) throws IOException {
out.write(b, off, len);
}
@Override
public void close() throws IOException {
out.close();
super.close();
}
@Override
public void flush() throws IOException {
out.flush();
super.flush();
}
}
}
내가 가능한 해결책을 발견의
getInputStream
방법, 내가 예를 들어
outStream.flush()
및
outStream.close()
다음
out.flush()
및
out.close()
... 그것은 최종처럼 보이는 모든 개체에 닫기를 호출하는 경우처럼 보인다 바이트가 제대로 기록됩니다. 직관적이지는 않지만 작동하는 것처럼 보입니다.
당신이 당신의 필터를 등록하는 방법을 우리에게 보여줍니다. –
상단에 필터 부품이 추가되어 캡쳐가 깨졌습니다. –
그래서 기본적으로 모든 Struts 양식 게시물을 캡처하고 조작하고 싶습니까? 업로드 된 파일은 무엇입니까? (달성하고자하는 것에 대해 명확하게 설명해야합니까?) Struts가 모든 폼 속성을'ActionForm' 속성으로 매핑한다는 것을 잊지 마십시오. 그게 효과가 있다면 아무런 문제가 없어야합니다. –