struts2基础——需要注意的几点
struts是流行和成熟的基于MVC设计模式的web应用程序框架,使用struts可以帮助我们减少运用MVC设计模型来开发web应用的时间。
目录:
一、struts2的工作原理及文件结构
二、三种访问Servlet API的方式
三、struts接收参数的三种方式
四、自定义拦截器
一、struts2的工作原理及文件结构

注:FilterDispatcher被替成StrutsPrepareAndExecuteFilter(如果使用FilterDispatcher过滤器时,程序员自己写的Filter过滤器必须放在所有过滤器的前面。而StrutsPrepareAndExecuteFilter过滤器可以让程序员在执行action之前写自己的Filter)
描述Struts流程:
网页产生HttpServletRequest请求->经过多个过滤器->到达ActionMaaper,判断是否是action请求(如果是)->通过StrutsPrepareAndExecuteFilter过滤器到达Actionproxy,一方面通过configuration Manager(配置管理器)读取struts.xml文档,另一方面创建一个实例,经过一系列的拦截器->执行到Action->返回result(对应了视图)->经过一系列的拦截器(逆序)->通过HttpServletResponse返回到用户实例。
二、三种访问servlet API的方法
struts2中没有提供任何一个servlet对象,不存在HttpServletRequest,HttpServletResponse对象。但是Struts2提供了三种方式间接的去访问Servlet API
1、ActionContext
通过ActionContext的getContext()静态方法获取ActionContext对象,通过ActionContext对象的一些getSession(),getApplication(),put()等方法,但是千万要注意的是,get获取到的对象都为Map键值对类型。com.opensymphony.xwork2.ActionContext
public String execute() {
if ("ping".equals(username)) {
/*
* ActionContext可以获得Servlet对象 但是无法获得response响应对象获得
* 获得的request、session、Application 都是Map类型
*/
ActionContext.getContext().put("用户名", username);
Map session=ActionContext.getContext().getSession();
Map application=ActionContext.getContext().getApplication();
Map request=(Map)ActionContext.getContext().get(StrutsStatics.HTTP_REQUEST);
} else {
ActionContext.getContext().put("info", "信息");
}
return SUCCESS;
}
2、ServletActionContext
通过调用ServletActionContext类的一些包括getResponse(),getRequest(),getServletContext()等在内的静态方法,这些静态方法的返回类型是和Servlet中的对象类型是一一对应的。其中getResponse()返回类型为HttpServletResponse,getRequest()返回类型为HttpServletRequest().
public String execute2() throws IOException {
if ("ping".equals(username)) {
HttpServletResponse response=ServletActionContext.getResponse();
4 HttpServletRequest request=ServletActionContext.getRequest();
HttpSession session=ServletActionContext.getRequest().getSession();
ServletContext application=ServletActionContext.getServletContext();
} else {
}
System.out.println(username);
return SUCCESS;
}
3、实现xxxAware接口
(1)实现ServletRequestAware,ServletResponseAware,ServletSessionAware
public class LoginAction extends ActionSupport implements ServletRequestAware private HttpServletRequest request;
//需实现方法 public void setServletRequest(HttpServletRequest request) { this.request=request; } //response示例
public String execute1() throws IOException {
if ("ping".equals(username)) {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
out.print("<script type='text/javascript'>alert('验证码输入错误!')</script>");
out.print("<script type='text/javascript'>location.href='/index.jsp'</script>");
out.flush();
out.close();
} else {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
out.print("<script type='text/javascript'>alert('验证码输入错误!')</script>");
out.flush();
out.close();
}
System.out.println(username);
return SUCCESS;
}
(2)实现RequestWare、SessionWare、ApplicationWare等接口
public class LoginAction2 extends ActionSupport implements RequestAware,SessionAware, ApplicationAware {
private Map<String, Object> request;
private Map<String, Object> session;
private Map<String, Object> application;
//DI dependency injection
//IoC inverse of control
public String execute() {
request.put("r1", "r1");
session.put("s1", "s1");
application.put("a1", "a1");
return SUCCESS;
}
@Override
public void setRequest(Map<String, Object> request) {
this.request = request;
}
@Override
public void setSession(Map<String, Object> session) {
this.session = session;
}
@Override
public void setApplication(Map<String, Object> application) {
this.application = application;
}
}
三、struts三种接收参数方式
Struts有三种方式接收参数,且这三种方式都是自动完成赋值的setter方法。
1、使用Action的属性接收参数
代码:
struts.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <package name="default" namespace="/" extends="struts-default">
<action name="LoginAction" method="login" class="com.third.LoginAction1">
<result>/loginSuccess.jsp</result>
</action>
</package> </struts>
login.jsp(登陆提示页面)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>login page</h1>
<form action="LoginAction.action" method="post">
<table>
<tr>
<td>username:</td>
<td><input type="text" name="username"/></td>
</tr>
<tr>
<td>password:</td>
<td><input type="password" name="password"/></td>
</tr> <tr>
<td><input type="submit" value="submit"></td>
<td><input type="reset" value="reset"></td>
</tr> </table> </form>
</body>
</html>
loginSuccess.jsp(登陆成功提示界面)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>login success!</title>
</head>
<body>
<h1>login success!</h1>
</body>
</html>
LoginAction.java
package com.third;
import com.opensymphony.xwork2.ActionSupport;
public class LoginAction1 extends ActionSupport {
private String username;
private String password;
public String login(){
//这里能够打印出来传入的值,则说明能够自动调用setter方法完成赋值
System.out.println("username:"+username+" password:"+password);
return SUCCESS;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
运行结果截图:


2、使用DomainModel接收参数
注:这里在表单传值是,必须指明这个属性值,到底穿个action中的那个引用,例如user.username.
代码:
struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts> <package name="default" namespace="/" extends="struts-default">
<action name="LoginAction" method="login" class="com.third.LoginAction">
<result>/loginSuccess.jsp</result>
</action>
</package> </struts>
login.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>"> <title>My JSP 'login.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
--> </head> <body>
<h1>login page!</h1>
<form action="LoginAction.action" method="post">
<table>
<tr>
<td>username:</td>
<td><input type="text" name="user.username"/></td>
</tr>
<tr>
<td>password:</td>
<td><input type="password" name="user.password"/></td>
</tr> <tr>
<td><input type="submit" value="submit"></td>
<td><input type="reset" value="reset"></td>
</tr>
</table>
</form>
</body>
</html>
loginSuccess.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>"> <title>My JSP 'loginSuccess.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
--> </head> <body>
<h1>login success!</h1>
</body>
</html>
User.java
package com.third;
public class User {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
LoginAction.java
package com.third; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.inject.Context; public class LoginAction extends ActionSupport { private User user;
public User getUser() {
return user;
} public void setUser(User user) {
this.user = user;
}
public String login(){
//这里可以打印出传入的值的话,Action完成了自动调用setter方法赋值
System.out.println("username:"+user.getUsername()+" password:"+this.getUser().getPassword());
return SUCCESS;
} }
运行结果截图:


3、使用ModelDriven接受参数
struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts> <package name="default" namespace="/" extends="struts-default">
<action name="LoginAction" method="login" class="com.third.LoginAction">
<result>/loginSuccess.jsp</result>
</action>
</package> </struts>
login.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>"> <title>My JSP 'login.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
--> </head> <body>
<h1>login page!</h1>
<form action="LoginAction.action" method="post">
<table>
<tr>
<td>username:</td>
<td><input type="text" name="username"/></td>
</tr>
<tr>
<td>password:</td>
<td><input type="password" name="password"/></td>
</tr> <tr>
<td><input type="submit" value="submit"></td>
<td><input type="reset" value="reset"></td>
</tr>
</table>
</form>
</body>
</html>
loginSuccess.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>"> <title>My JSP 'loginSuccess.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
--> </head> <body>
<h1>login success!</h1>
</body>
</html>
User.java
package com.third;
public class User {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
LoginAction.java
package com.third; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.opensymphony.xwork2.inject.Context; public class LoginAction extends ActionSupport implements ModelDriven<User> { private User user=new User();
public String login(){
//这里打印出传入的参数值,说明自动调用setter方法赋值
System.out.println("username:"+user.getUsername()+" password:"+user.getPassword());
return SUCCESS;
} @Override
public User getModel() { return user;
} }
运行结果截图:


四、自定义拦截器
注:特别要注意在使用拦截的器的时候,使用表单传值,会导致Action中获得的属性的值为null,或是其他的默认的初始化值。
1、实现Interceptor接口
-void init()方法:初始化拦截器所需要的资源
-void destory()方法:释放init()中分配的资源
-String intercept(ActionInvocation invocation)throws Exception:实现拦截器功能,利用ActionInvocation参数获取Action状态,返回result字符串作为逻辑视图。
代码:
struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts> <package name="default" namespace="/" extends="struts-default">
<!--注册拦截器 -->
<interceptors>
<interceptor name="timefigureFilter" class="com.third.TimeInterceptor">
</interceptor>
</interceptors> <action name="LoginAction" method="login" class="com.third.LoginAction">
<result>/loginSuccess.jsp</result>
<interceptor-ref name="timefigureFilter"></interceptor-ref>
</action>
</package> </struts>
login.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>"> <title>My JSP 'login.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
--> </head> <body>
<h1>login page!</h1>
<form action="LoginAction.action" method="post">
<table>
<tr>
<td>username:</td>
<td><input type="text" name="username"/></td>
</tr>
<tr>
<td>password:</td>
<td><input type="password" name="password"/></td>
</tr> <tr>
<td><input type="submit" value="submit"></td>
<td><input type="reset" value="reset"></td>
</tr>
</table>
</form>
</body>
</html>
loginSuccess.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>"> <title>My JSP 'loginSuccess.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
--> </head> <body>
<h1>login success!</h1>
</body>
</html>
User.java
package com.third;
public class User {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
TimeInterceptor.java
package com.third; import javax.servlet.http.HttpServletRequest; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor; public class TimeInterceptor implements Interceptor { @Override
public void destroy() {
// TODO Auto-generated method stub } @Override
public void init() {
// TODO Auto-generated method stub } @Override
public String intercept(ActionInvocation invocation) throws Exception {
HttpServletRequest request=ServletActionContext.getRequest();
String username=request.getParameter("username");
String password=request.getParameter("password");
request.setAttribute("username", username);
//1执行action之前
long start=System.currentTimeMillis();
//2执行下一个拦截器,直到最后一个拦截器,则执行目标Action
String result=invocation.invoke();
//3执行完action之后
long end=System.currentTimeMillis();
System.out.println("执行Action花费的时间为:"+(end-start)+"ms");
return result;
} }
LoginAction.java
package com.third; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.opensymphony.xwork2.inject.Context; public class LoginAction extends ActionSupport implements ModelDriven<User> { private User user=new User();
public String login(){
//着重看着两行代码运行打印的结果
System.out.println("username:"+user.getUsername());
//System.out.println("username:"+ServletContext.getRequest().getAttribute("username");//这里也可完成正常的获值
System.out.println("username:"+ServletActionContext.getRequest().getAttribute("username"));
return SUCCESS;
} @Override
public User getModel() { return user;
} }
运行结果截图:


注:注意看结果,打印的第一个username的属性值为null,而第二个为表单填写的dasd。这里涉及到拦截器的使用导致的表单传值问题。
分析:拦截器的使用导致的表单传值问题
原因:登陆界面填写完成之后,表单需要实现页面跳转,而这些将会交给struts,struts在调用action的过程其实是调用action中的struts.xml配置action标签method属性指定的方法(默认是execute()),而在调用这个方法前会对表单的属性信息将会别匹配赋值给action中同名属性。正常情况下没有自定义的拦截器,通过表单传递的属性值没有问题。
要完成这个功能,有很大程度上, Struts 2 要依赖与 ValueStack 对象。这个对象贯穿整个 Action 的生命周期 (每个 Action 类的对象实例会拥有一个 ValueStack 对象 ) 。当 Struts 2 接收到一个 action 的请求后,会先建立Action 类的对象实例,但不会调用 Action 方法,而是先将 Action 类的相应属性放到 ValueStack 对象的顶层节点(ValueStack 对象相当于一个栈 ). 只是所有的属性值都是默认的值,如 String 类型的属性值为 null,int 类型的属性值为 0 等。
在处理完上述工作后, Struts 2 就会调用拦截器链中的拦截器,当调用完所有的拦截器后,最后会调用 Action 类的 Action 方法,在调用 Action 方法之前,会将 ValueStack 对象顶层节点中的属性值赋给 Action 类中相应的属性。大家要注意,在这里就给我们带来了很大的灵活性。也就是说,在 Struts 2 调用拦截器的过程中,可以改变ValueStack 对象中属性的值,当改变某个属性值后, Action 类的相应属性值就会变成在拦截器中最后改变该属性的这个值。
好多废话~总结就是:在拥有自定义的过滤器时,表单传属性值会先赋值给Action中属性,当运行完过滤器时,才会调用Action中的方法,在调用之前会将 ValueStack 对象中的默认初始化值赋给action中的属性,然后调用action中的方法,这样action中的属性全是ValueStack 对象中的默认初始化值。
解决的方法:间接访问Servlet的API,通过request对象去访问属性和属性值。如:
HttpServletRequest request=ServletActionContext.getRequest();
String username=request.getParameter("username");
2、方式二:继承AbstractInterceptor类
-提供了init()和destroy()方法的实现
-只需要实现intercept()方法即可
代码:
struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts> <package name="default" namespace="/" extends="struts-default">
<!--注册拦截器 -->
<interceptors>
<interceptor name="timefigureFilter1" class="com.third1.TimeInterceptor">
</interceptor>
</interceptors> <action name="TimeAction" class="com.third1.TimeAction">
<result>/index.jsp</result>
<!--引用拦截器 -->
<interceptor-ref name="timefigureFilter1"></interceptor-ref>
</action> </package> </struts>
TimeInterceptor.java
package com.third1; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor; public class TimeInterceptor extends AbstractInterceptor { @Override
public String intercept(ActionInvocation invocation) throws Exception {
//1.执行action之前
long start=System.currentTimeMillis();
//2.执行下一个拦截器,如果已经是最后一个拦截器,则执行目标Action ServletActionContext.getRequest().setAttribute("username", "小帅哥");
ServletActionContext.getRequest().getSession().setAttribute("username","小美女");
ServletActionContext.getServletContext().setAttribute("username", "少艾");
String result=invocation.invoke();
//3.执行Action之后
long end=System.currentTimeMillis();
System.out.println("执行Action花费的时间:"+(end-start)+"ms");
//获取request对象,调用其setAttribute函数,将时间作为属性保存到request对象中
ServletActionContext.getRequest().setAttribute("time", (end-start));
ServletActionContext.getRequest().getSession().setAttribute("time1",(end-start));
ServletActionContext.getServletContext().setAttribute("time2", (end-start));
return result;
} }
TimeAction.java
package com.third1;
import com.opensymphony.xwork2.ActionSupport;
public class TimeAction extends ActionSupport {
@Override
public String execute() throws Exception{
for(int i=0;i<3;i++){
Thread.sleep(1000);
}
return SUCCESS;
}
}
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>"> <title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head> <body> <h1>执行Action用户名:<%=request.getAttribute("username") %>(通过request方式获取)</h1>
<h1>执行Action用户名:<%=session.getAttribute("username") %>(通过session方式获取)</h1>
<h1>执行Action用户名:<%=application.getAttribute("username") %>(通过application方式获取)</h1> <h1>执行Action花费的时间:<%=request.getAttribute("time") %>(通过request方式获取)</h1>
<h1>执行Action花费的时间:<%=session.getAttribute("time1") %>(通过session方式获取)</h1>
<h1>执行Action花费的时间:<%=application.getAttribute("time2") %>(通过application方式获取)</h1>
</body>
</html>
运行结果截图:

分析:对比两种颜色标记的代码区,对比一下他们,并且结合结果进行分析。我们不难发现过滤器的调用分为两个阶段,第一个阶段是在产生HttpServletRequest请求之后、action方法调用之前;第二阶段是产生与action之后,jsp页面(Template显示)跳转之后,HttpServletResponse之前。所以当你在 String result=invocation.invoke(); 这条语句之后通过request,application,session给它设置属性值,将会没有起到任何作用。
可以结合struts2的工作原理及文件结构图进行参考。
struts2基础——需要注意的几点的更多相关文章
- Struts2入门1 Struts2基础知识
Struts2入门1 Struts2基础知识 20131130 代码下载: 链接: http://pan.baidu.com/s/11mYG1 密码: aua5 前言: 之前学习了Spring和Hib ...
- Struts2基础学习2
Struts2基础学习2 项目结构,测试页面与实体类 <%@ page language="java" contentType="text/html; charse ...
- Struts2基础入门
Struts2基础入门 创建一个web工程 0)导包并且创建一个核心配置文件 <?xml version="1.0" encoding="UTF-8"?& ...
- Struts2基础学习总结
引用自:http://www.cnblogs.com/jbelial/archive/2012/05/10/2486886.html Struts 2是在WebWork2基础发展而来的. 注意:str ...
- 经典MVC框架技术-struts2基础知识
Struts2框架简介 struts2框架是在struts1和webwork技术的基础上,进行合并的全新框架,struts2以Webwork为核心,采用拦截器来处理用户的请求,这样的设计使得业务逻辑控 ...
- Struts2框架学习第三章——Struts2基础
本章要点 — Struts 1框架的基本知识 — 使用Struts 1框架开发Web应用 — WebWork框架的基本知识 — 使用WebWork框架开发Web应用 — 在Eclipse中整合To ...
- (一)Struts2 基础
一.Struts简介 1.1 历史 虽然Struts 2号称是一个全新的框架,但这仅仅是相对Struts 1而言.Struts 2与Struts 1相比,确实有很多革命性的改进,但它并不是新发布的新框 ...
- struts2 基础
框架(frameWork):某一种应用的半成品 struts2: 表现层 处理与页面进行交互的相关功能 hibernate: 持久层 负责业务逻辑数据的持久化 spring: 业务层 负责复杂的业 ...
- struts2 基础学习
Struts 2是在WebWork2基础发展而来的. 注意:struts 2和struts 1在代码风格上几乎不一样. Struts 2 相比Struts 1的优点: 1.在软件设计上Struts ...
- 2. Struts2 基础
1. Struts2简介 Struts2是一个WEB端MVC框架.作为比较早的MVC 框架之一,Struts2在使用中还是比较多的.虽然个人感受没有SpringMVC还那么的好用 Struts2 官网 ...
随机推荐
- Iptables规则执行顺序详解
1.The first is the mangle table which is responsible for the alteration of quality of service bits ...
- C语言 百炼成钢25
/* 题目61:编写一个名为removestring的函数,该函数用于从一个字符串中删除一定量的字符. 该函数接受三个参数: 第1参数代表源字符串 第2参数代表需要删除字符的起始位置(位置从0开始) ...
- mfc小工具开发之定时闹钟之---多线程急线程同步
一.MFC对多线程编程的支持 MFC中有两类线程,分别称之为工作者线程和用户界面线程.二者的主要区别在于工作者线程没有消息循环,而用户界面线程有自己的消息队列和消息循环. 工作者线程没有消息机制,通常 ...
- pip使用代理下载
sudo pip install <packageName>的时候有时候会遇到connection error,原因是sudo的环境变量没有继承普通用户的环境变量,这样会导致普通用户设置的 ...
- API 接口设计中 Token 类型的分类与设计
在实际的网站设计中我们经常会遇到用户数据的验证和加密的问题,如果实现单点,如果保证数据准确,如何放着重放,如何防止CSRF等等 其中,在所有的服务设计中,都不可避免的涉及到Token的设计. 目前,基 ...
- MathType输入补集符号的步骤有哪些
集合符号在很多的数学领域都会用到,其基本的集合运算可以分为交.并.补这三种.但是一些用户朋友们在编辑文档的时候想输入集合符号这个时候就需要用到数学公式编辑器MathType,但是很多人能够快速地编辑出 ...
- servlet之模板方法和多线程
接触了一小段时间的servlet,以下就总结一下关于servlet的两个方面的知识,一个是模板方法的应用.另外一个是servlet多线程产生的原因. 1. 模板方法设计模式 定义一个操作中的算法的骨架 ...
- PAT Advance 1020
题目: 1020. Tree Traversals (25) 时间限制 400 ms 内存限制 32000 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue S ...
- SpringMVC学习(十一)——SpringMVC实现Resultful服务
http://blog.csdn.net/yerenyuan_pku/article/details/72514034 Restful就是一个资源定位及资源操作的风格,不是标准也不是协议,只是一种风格 ...
- android应用安全——代码安全(android代码混淆)
android2.3的SDK开始在eclipse中支持代码混淆功能(理论上java都支持混淆,但关键在于如何编写proguard的混淆脚本,2.3的SDK使用简单的配置就可以实现混淆).使用SDK2. ...