关于struts2链接操作我有一个相当复杂的问题,提前感谢您耐心阅读我的问题。我会尽力清楚地描述它。
下面是我的struts.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.enable.SlashesInActionNames" value="true" />
<constant name="struts.devMode" value="false" />
<package name="default" extends="struts-default" namespace="/">
<action name="test" class="com.bv.test.TestAction1" >
<result name="success" type="chain">y</result>
</action>
<action name="x">
<result name="success">/index.jsp</result>
</action>
<action name="y" class="com.bv.test.TestAction2">
<result name="success">/index.jsp</result>
</action>
</package>
</struts>
我的逻辑是这样的: 访问/ myapp / test时,TestAction1将处理请求; 在TestAction1中,我“包含”动作x(我的配置中的第二个动作),如下所示:
ResponseImpl myResponse = new ResponseImpl(response);
RequestDispatcher rd = request.getRequestDispatcher("/x.action");
rd.include(request, myResponse);
重要的是我在使用“x.action”时使用自定义的ResponseIml。
包括之后,我返回“成功”,所以结果链到行动y(我的配置中的第3个动作);
最后,TestAction2继续处理请求,它将转到成功结果,并且应该呈现jsp,但是我看到的是一个空白页。
jsp文件非常简单: index.jsp的
<h1>Test!</h1>
我的疑问/难题是:
这个问题确实让我感到困惑,我花了几天时间 任何建议将不胜感激! 太感谢了!!
我的代码:
TestAction1:
public class TestAction1 {
public String execute() {
ActionContext ac = ActionContext.getContext();
System.out.println("Before including: the action context is : " + ac);
HttpServletRequest request = ServletActionContext.getRequest();
HttpServletResponse response = ServletActionContext.getResponse();
System.out.println("Before including: the response is : " + response);
ResponseImpl myResponse = new ResponseImpl(response);
RequestDispatcher rd = request.getRequestDispatcher("/x.action");
try {
rd.include(request, myResponse);
String s = myResponse.getOutput();
System.out.println("get from response: " + s);
}
catch (Exception e) {
e.printStackTrace();
}
ac = ActionContext.getContext();
System.out.println("After including : the action context is : " + ac);
response = ServletActionContext.getResponse();
System.out.println("After including : the response is : " + response);
return "success";
}
}
ResponseImpl:
import java.util.Locale;
import java.io.StringWriter;
import java.io.PrintWriter;
import java.io.OutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import javax.servlet.http.Cookie;
import javax.servlet.jsp.JspWriter;
/**
*
*
*/
public class ResponseImpl extends HttpServletResponseWrapper {
//=========================================================
// Private fields.
//=========================================================
private ServletOutputStream outputStream = null;
private ByteArrayOutputStream byteArrayOutputStream = null;
private StringWriter stringWriter = null;
private PrintWriter printWriter = null;
private HttpServletResponse _response = null;
private String contentType= "text/html";
private String encoding = "UTF-8";
/**
*
*/
class ServletOutputStream extends javax.servlet.ServletOutputStream {
private OutputStream outputStream = null;
/**
*
*/
ServletOutputStream(ByteArrayOutputStream outputStream) {
super();
this.outputStream = outputStream;
}
/**
*
*/
public void write(int b) throws IOException {
this.outputStream.write(b);
}
}
//=========================================================
// Public constructors and methods.
//=========================================================
/**
*
*/
public ResponseImpl(HttpServletResponse response) {
super(response);
this._response = response;
}
/**
*
*/
public String getOutput() {
if (this.stringWriter != null) {
return this.stringWriter.toString();
}
if (this.byteArrayOutputStream != null) {
try {
return this.byteArrayOutputStream.toString(this.encoding);
}
catch (UnsupportedEncodingException e) {
}
return this.byteArrayOutputStream.toString();
}
return null;
}
//=========================================================
// Implements HttpServletResponse interface.
//=========================================================
public void addCookie(Cookie cookie) {
}
public void addDateHeader(String name, long date) {
}
public void addHeader(String name, String value) {
}
public void addIntHeader(String name, int value) {
}
public boolean containsHeader(String name) {
return false;
}
public String encodeRedirectURL(String url) {
if (null != this._response) {
url = this._response.encodeRedirectURL(url);
}
return url;
}
public String encodeURL(String url) {
if (null != this._response) {
url = this._response.encodeURL(url);
}
return url;
}
public void sendError(int sc) {
}
public void sendError(int sc, String msg) {
}
public void sendRedirect(String location) {
}
public void setDateHeader(String name, long date) {
}
public void setHeader(String name, String value) {
}
public void setIntHeader(String name, int value) {
}
public void setStatus(int sc) {
}
public void resetBuffer() {
}
//=========================================================
// Implements deprecated HttpServletResponse methods.
//=========================================================
public void setStatus(int sc, String sm) {
}
//=========================================================
// Implements deprecated HttpServletResponse methods.
//=========================================================
public String encodeRedirectUrl(String url) {
return encodeRedirectURL(url);
}
public String encodeUrl(String url) {
return encodeURL(url);
}
//=========================================================
// Implements ServletResponse interface.
//=========================================================
public void flushBuffer() {
}
public int getBufferSize() {
return 0;
}
public String getCharacterEncoding() {
return this.encoding;
}
public String getContentType() {
return this.contentType;
}
public Locale getLocale() {
return null;
}
public javax.servlet.ServletOutputStream getOutputStream() {
if (this.outputStream == null) {
this.byteArrayOutputStream = new ByteArrayOutputStream();
this.outputStream =
new ServletOutputStream(this.byteArrayOutputStream);
}
return this.outputStream;
}
public PrintWriter getWriter() {
if (this.printWriter == null) {
this.stringWriter = new StringWriter();
this.printWriter = new PrintWriter(this.stringWriter);
}
return this.printWriter;
}
public boolean isCommitted() {
return true;
}
public void reset() {
}
public void setBufferSize(int size) {
}
public void setCharacterEncoding(String charset) {
}
public void setContentLength(int len) {
}
public void setContentType(String type) {
int needle = type.indexOf(";");
if (-1 == needle) {
this.contentType = type;
}
else {
this.contentType = type.substring(0, needle);
String pattern = "charset=";
int index = type.indexOf(pattern, needle);
if (-1 != index) {
this.encoding = type.substring(index + pattern.length());
}
}
}
public void setLocale(Locale locale) {
}
}
TestAction2:
public class TestAction2 {
public String execute() {
ActionContext ac = ActionContext.getContext();
System.out.println("In TestAction 2 : the action context is : " + ac);
HttpServletResponse response = ServletActionContext.getResponse();
System.out.println("In TestAction 2 : the response is : " + response);
return "success";
}
}
的web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_9" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Struts2 Application</display-name>
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
</web-app>
这是我的调试信息。
<h1>Test!</h1>
所以,我在包含!!之前和之后都有不同的ActionContext实例。
答案 0 :(得分:1)
当您执行rd.include时,会在Web服务器内部触发另一个请求。因此,从struts的角度来看,它会看到一个全新的请求,并且会创建一个新的操作上下文。 (这就是为什么你需要在struts2过滤器上包含'INCLUDE'的东西..所以它也看到包含的请求)。可能因为线程局部变量用于跟踪操作上下文,所以当您执行ActionContext.getContext()时,将检索与新请求相关的上下文(与include相关)。
您是否尝试将响应重置为finally块中的初始响应,如下所示
try {
rd.include(request, myResponse);
String s = myResponse.getOutput();
System.out.println("get from response: " + s);
}
catch (Exception e) {
e.printStackTrace();
} finally {
ServletActionContext.setResponse(response);
}
如果这解决了响应问题..您可以将字符串's'作为变量存储在操作上下文中并在Action2中检索它
答案 1 :(得分:0)
您也可以尝试以下操作。而不是在您的TestAction1中使用链接..包括具有原始响应的TestAction2。从操作返回'none'作为返回值。
public class TestAction1 {
public String execute() {
ActionContext ac = ActionContext.getContext();
System.out.println("Before including: the action context is : " + ac);
HttpServletRequest request = ServletActionContext.getRequest();
HttpServletResponse response = ServletActionContext.getResponse();
System.out.println("Before including: the response is : " + response);
ResponseImpl myResponse = new ResponseImpl(response);
RequestDispatcher rd = request.getRequestDispatcher("/x.action");
try {
rd.include(request, myResponse);
String s = myResponse.getOutput();
System.out.println("get from response: " + s);
}
catch (Exception e) {
e.printStackTrace();
}
RequestDispatcher rd = request.getRequestDispatcher("/y.action");
try {
rd.include(request, response);
}
catch (Exception e) {
e.printStackTrace();
} finally {
return "none";
}
}
}