【发布时间】:2017-12-17 17:01:33
【问题描述】:
我目前正在开发旧系统。该系统使用 Java 4 和 Struts 1.3。好吧,他们的安全性很严格。反正
我被要求为他们的系统的请求和响应创建一个记录器。我们的想法是对他们的新用户界面和功能进行一些审核,如果有客户投诉,我们可以通过记录的请求和响应来追踪发生的情况。
我们的想法不是在每个模块上都放置日志。由于他们使用的是 struts 1.3,我最初的建议是使用 Servlet Filter、ActionServlet 或 Requestprocessor 实现一个模块。我已经尝试过 Servlet 过滤器,但它无法工作,因为它们的 web.xml 正在使用 http__java.sun.com_dtd_web_app_2.2.dtd。我已经找到了引入 Servlet 过滤器的 2.3。
当我尝试使用 ActionServlet 或 Requestprocessor 实现模块时。我至少能够获得 HttpServletRequest。然而,由于这个版本的 struts 和 java HttpServletResponse 真的没有吸气剂。我实现了一个派生自 HttpServletResponseWrapper 的类。
当我使用时,网络浏览器中没有收到任何内容。当我检查。我得到一个运行时异常 - java.lang.ClassCastException。我不确定 HttpServletResponseWrapper 是否只能与 Servlet Filter 一起使用,或者我拥有的库是旧的。
基本上这是我在 Action Servlet 中使用的方式。
public void doGet (HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
responseCapture = new M2UResponseWrapper((HttpServletResponse) response);
try
{
super.doGet(request, responseCapture);
}
catch (Exception e)
{
Logger.error("Exception Type 1 : " + e);
}
}
下面是我的HttpServletResponseWrapper 实现。这只是我的初步测试。
public class MyResponseWrapper extends HttpServletResponseWrapper {
private final HttpServletResponse httpResponse;
private int responseStatus;
private String errMessage;
private String redirectURL;
private ArrayList responseCookieList;
private Map responseDateHeader;
private Map responseHeader;
private Map responseIntHeader;
protected M2UServletOutputStreamWrapper output;
protected CharArrayWriter charWriter;
protected PrintWriter writer;
protected boolean getOutputStreamCalled;
protected boolean getWriterCalled;
public M2UResponseWrapper (HttpServletResponse httpResponse) {
super(httpResponse);
this.httpResponse = httpResponse;
getOutputStreamCalled = false;
getWriterCalled = false;
charWriter = new CharArrayWriter();
output = new M2UServletOutputStreamWrapper();
responseCookieList = new ArrayList();
responseDateHeader = new HashMap();
responseHeader = new HashMap();
responseIntHeader = new HashMap();
}
public String toString() {
return charWriter.toString();
}
public boolean containsHeader(String name) {
return httpResponse.containsHeader(name);
}
public void addIntHeader(String name, int value) {
responseIntHeader.put(name, Integer.toString(value));
httpResponse.addIntHeader(name, value);
}
public void addDateHeader(String name, long date) {
responseDateHeader.put(name,String.valueOf(date));
httpResponse.addDateHeader(name,date);
}
public void addHeader(String name, String value) {
responseHeader.put(name,value);
httpResponse.addHeader(name, value);
}
public void setDateHeader(String name, long date) {
responseDateHeader.put(name,String.valueOf(date));
httpResponse.setDateHeader(name, date);
}
public void setHeader(String name, String value) {
responseHeader.put(name,value);
httpResponse.setHeader(name, value);
}
public void setIntHeader(String name, int value) {
responseIntHeader.put(name, Integer.toString(value));
httpResponse.setIntHeader(name, value);
}
public Iterator getHeader() {
return responseHeader.keySet().iterator();
}
public Iterator getDateHeader() {
return responseDateHeader.keySet().iterator();
}
public Iterator getIntHeader() {
return responseIntHeader.keySet().iterator();
}
public void sendError(int sc) throws IOException {
responseStatus = sc;
try {
httpResponse.sendError(sc);
} catch (IOException e) {
e.printStackTrace();
}
}
public void sendError(int sc, String msg) throws IOException {
responseStatus = sc;
errMessage = msg;
try {
httpResponse.sendError(sc, msg);
} catch (IOException e) {
e.printStackTrace();
}
}
public void setStatus(int sc) {
responseStatus = sc;
httpResponse.setStatus(sc);
}
public void setStatus(int sc, String sm) {
responseStatus = sc;
errMessage = sm;
httpResponse.setStatus(sc, sm);
}
public String getErrorMessage() {
return errMessage;
}
public int getStatus() {
return responseStatus;
}
public String getRedirectURL() {
return redirectURL;
}
public void sendRedirect(String location) throws IOException {
responseStatus = 302;
redirectURL = location;
try {
httpResponse.sendRedirect(location);
} catch (IOException e) {
e.printStackTrace();
}
}
public void addCookie(Cookie cookie) {
responseCookieList.add(cookie);
httpResponse.addCookie(cookie);
}
public ArrayList getCookie() {
return responseCookieList;
}
public PrintWriter getWriter() throws IOException{
if (getOutputStreamCalled) {
throw new IllegalStateException("getOutputStream() has already been called on this response.");
}
try {
if (writer != null) {
writer = new PrintWriter(charWriter);
}
} catch (Exception e) {
e.printStackTrace();
}
getWriterCalled = true;
return writer;
}
public boolean isOutputStreamCalled() {
return getOutputStreamCalled;
}
public boolean isWriterCalled() {
return getWriterCalled;
}
public ServletOutputStream getOutputStream() throws IOException {
if (getWriterCalled) {
throw new IllegalStateException("getWriterCalled() has already been called on this response.");
}
getOutputStreamCalled = true;
return (ServletOutputStream) output;
}
}
我见过很多例子,HttpServletResponseWrapper 用于获取 HttpServletResponse,但它们都是在 Servlet 过滤器中实现的。我不知道我是否真的不能在 Action Servlet 或 Requestprocessor 上使用 HttpServletResponseWrapper 因为 Servlet Filter 请求和响应是 ServletRequest 和 ServletResponse 对象。
请注意,我正在使用遗留系统,因此升级到 struts 3 或 spring 或使用 java web app 2.3 及更高版本 dtd 并不是一个真正的选择。我只是希望我的包装器实现出错了。如果你们有其他建议。
我确实向他们提出了建议,我将使用命令 shell 运行管理嗅探工具来进行日志记录。马上就被拒绝了。
【问题讨论】: