Tôi cần một bộ lọc servlet sẽ chụp tất cả đầu vào, sau đó mangle đầu vào đó, chèn một mã thông báo đặc biệt vào mọi biểu mẫu. Hãy tưởng tượng rằng bộ lọc được gắn với tất cả các yêu cầu (Ví dụ: url-pattern=*
). Tôi có mã để nắm bắt nội dung, nhưng có vẻ như không phải là RequestWrapper
đủ mạnh để nắm bắt tất cả đầu vào. Một số đầu vào trả về 0 byte và sau đó tôi không thể "stream" nội dung đó cho người dùng. Ví dụ, chúng tôi vẫn đang sử dụng Struts 1.3.10 và bất kỳ mã Struts nào không "nắm bắt" đúng cách, chúng tôi nhận được nội dung byte không. Tôi tin rằng đó là vì cách Struts xử lý tiền đạo. Nếu có sự chuyển tiếp liên quan đến yêu cầu, tôi tự hỏi liệu mã chụp bên dưới có hoạt động không. Đây là tất cả các mã, bạn có một cách tiếp cận mà sẽ nắm bắt bất kỳ loại nội dung có nghĩa là để streaming cho người dùng.Bộ lọc servlet bắt tất cả nội dung đầu vào HTML để thao tác, chỉ hoạt động liên tục
<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);
}
}
}
}
Đây là những gì một ví dụ Struts ứng dụng có thể như thế nào, đối với một số ứng dụng (không Struts), chúng tôi có thể nắm bắt được nội dung. Nhưng đối với các ứng dụng như dưới đây, không có byte nào được trả lại cho nội dung HTML nhưng phải có nội dung.
<%@ 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>
Tôi nghi ngờ rằng MyResponseWrapper
và MyPrintWriter
không đủ mạnh mẽ để nắm bắt tất cả các loại nội dung.
Ví dụ servlet rằng sẽ làm việc (một):
response.getOutputStream().write(str.getBytes());
Ví dụ servlet đó sẽ không hoạt động (b):
response.getWriter().println("<html>data</html>");
Ví dụ một sẽ nhận được ảnh chụp, ví dụ b sẽ không.
Đây là lớp trình bao bọc được cải thiện, hầu hết các ứng dụng sẽ hoạt động nhưng NGAY BÂY GIỜ một số ứng dụng thanh chống, chỉ MỘT SỐ phản hồi được gửi tới trình duyệt.
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();
}
}
}
Tôi tìm thấy một giải pháp khả thi, trong phương pháp getInputStream
, có vẻ như nếu tôi gọi là 'gần' trên tất cả các đối tượng, ví dụ như outStream.flush()
và outStream.close()
và sau đó out.flush()
và out.close()
... nó trông giống như trận chung kết byte được viết đúng cách. nó không trực quan nhưng có vẻ như nó hoạt động.
Hiện chúng tôi biết bạn đăng ký bộ lọc của bạn. –
Được thêm ở trên cùng, phần bộ lọc hoạt động, ảnh chụp là phần bị hỏng. –
Vì vậy, về cơ bản bạn muốn nắm bắt tất cả các bài viết dạng Struts và thao tác nó? Điều gì về các tập tin tải lên (tôi cần rõ ràng về những gì bạn đang cố gắng để đạt được)? Đừng quên rằng Struts ánh xạ tất cả các thuộc tính biểu mẫu của bạn tới các thuộc tính 'ActionForm' của bạn. Nếu nó hoạt động, thì sẽ không có vấn đề gì. –