Struts2学习笔记

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Struts1是一个优秀的框架,但是还是具有很多不好的地方,如Action和ActionForm严重倚赖系统框架中的API。

如ActionForm必须继承ActionForm,Action控制器继承Action,测试麻烦。

Struts2是基于webwork发展而来,并非struts1
使用MyEclipse8.5版本,可自动添加依赖struts2的系统库
Struts2原理:
说明:Struts2没使用Servlet作为核心控制器,而是换做一个Filter过滤器来进行,其类是org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter 过滤器所拦截的请求是<url-pattern>/*</ url-pattern>
(当然根据版本的不同,过滤器类也不同,
如Org.apache.Struts2.dispatcher.FilterDispatcher)
如果请求中带有.action或.do,则转入Struts2框架处理。

配置文件:
Web.xml中:
<filter>
<filter-name>struts2</filter-name>
<!-版本不同这里的配置不同-→
<!—
<filter-class>
Org.apache.Struts2.dispatcher.FilterDispatcher
</filter-class>

<filter-class>
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFi lter
</filter-class>
<init-param>
<param-name>config</param-name>
<param-value>
struts-default.xml,struts-plugin.xml,../struts.xml </param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>struts2</ filter-name>
<url-pattern>/*</ url-pattern>
</filter-mapping>
Struts.xml
<?xml version="1.0"encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC"-//Apache Software Foundation//DTD Struts Configuration 2.1//EN""/dtds/struts-2.1.dtd"> <struts>
<!—这个package可以处理文件同名的情况,一般不会更换-- >
<package name="default"extends="struts-default"namespace="\"> <action name="Login"class="com.test.action.LoginAction">
<result name="cheng">/index.jsp</result>
<result name="bai">/fail.jsp</result>
</action>
</package>
</struts>
配置文件说明:
1、package中的name为了区分不同的包
2、extends是继承的包名
3、namespace是提交时区分的地址,如namespace=”user”,则提交时需要加入
action=”/user/xxx.action”
控制其中的代码,其中数据直接封装和页面表单元素名称对应。

如果是对象,则页面表单元素名称写法为对象.属性名
LoginAction代码:
public class LoginAction extends ActionSupport{
// 封装用户请求参数的uid
private String uid;
private String pwd;
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
private String[] shops;
public String[] getShops() {
return shops;
}
public void setShops(String[] shops) {
this.shops = shops;
}
// 这里直接返回字符串,和xml配置文件中的键值对应
public String execute() throws Exception {
UserInfo userInfo = UserService.newInstance().login(this.uid, this.pwd);
if (userInfo != null) {
//将用户放入session中
ActionContext.getContext().getSession().put("currUser",u);
String[] shops = ShopService.newInstance().getShopNames();
this.setShops(shops);//以下是说明
//当action设置了某个属性后,struts2将会将这些属性全部封装在一个Struts.valueStack的请求属性中。

为了在JSP中输出商品信息,可以通过如下代码获取:
//获得ValueStack 它类似于一个Map结构这是JSP中代码
//ValueStack vs =
(ValueStack)request.getAttribute(“Struts.valueStack”);
//String shops[] = (String[])vs.findValue(“shops”);//并非通过Action中的属性名关联,而是通过getter和setter方法
return"cheng";
//这里可以返回系统常量
Return this.SUCCESS;
}
return"bai";
}
//获得request
ActionContext actx = ActionContext.getContext();
//获得request
Map req = (Map)actx.get("request");
HttpServletRequest request =
ServletActionContext.getRequest();
HttpSession session =
ServletActionContext.getRequest().getSession();
ServletContext ctx =
ServletActionContext.getServletContext();
// Map session = (Map)actx.getSession();
// Map application = (Map)actx.getApplication();
流程:
1、页面提交请求:action=” Login.action”
2、系统拦截.action后缀,找到对应的action—Name,找到对应的Action处理
3、Action中可自动获取页面表单的数据,并采用execute方法处理
4、处理完毕后返回字符串,由字符串自动对应了Struts.xml中配置的result处理
<result name="cheng">/index.jsp</result>
1、配置常量:
在Struts.xml或者Struts.properties中
<Struts>
更改为.do来处理请求
<constant name=”Struts.action.extension” value=”do” />
</Struts>
或者:
#将struts2业务逻辑控制器Action默认访问扩展名*.action修改为*.do
Struts.action.extension = do
解决中文乱码问题:
<constant name=”Struts.i18n.encoding” value=”GBK” / >
修改为GBK时,相当于调用HttpServletRequest的setCharacterEncoding方法
2、设置Struts2默认主题,解决页面布局混乱
<constant name=”Struts.ui.theme” value=”simple” />
配置Struts包配置
<package name=”...” extends=”...” ...>
在Struts2中配置包时,必须继承自Struts-default包,否则出错Namespace为命名空间配置
<package name=”default” extends =”Struts-default” namespace=”/manager”> 那么页面提交时必须加入:
<a href=”/manager/test.action”>测试</a>
Action中的操作
1、获取Request对象
ActionContext ctx = ActionContext.getContext();
Map request = (Map)ctx.get("request");
2、获取session
ActionContext ctx = ActionContext.getContext();
Map session = (Map)ctx.getSession();
3、获取ServletContext对象
ActionContext ctx = ActionContext.getContext();
Map application = (Map)ctx.getApplication();
其他获取方式:
ActionContext.getContext().get(ServletActionContext.HTTP_REQUEST) ActionContext.getContext().get(ServletActionContext.HTTP_RESPONSE) ActionContext.getContext().get(ServletActionContext.HTTP_CONTEXT)
技巧:一般为了方便处理,会建立Action父类。

BaseAction
Public class BaseAction{
//获取Request
Public Map<String.Object> getRequest(){
Return (Map)ActionContext.getContext().get(“request”);
}
//..获取session
//..获取ServletContext
//..获取Response
Public HttpServletResponse getResponse(){
HttpServletResponse response = ServletActionContext.getResponse();
Response.setContentType(“text/html;charset=gbk”);
Response.setCharacterEncoding(“gbk”);
Return response;
}
}
-----------------------------------关于公用同一个Action--------------------------------------------
方法一:
提交代码如下:
<script>
function submitInfo(type){
var form = document.regForm;
form.action = 'myReg!'+type+'.action';
form.submit();
}
</script>
对应的Action代码如下:
public class RegAction extends BaseAction {
//定义注册方法
public String reg() throws Exception{
//获取输出对象
PrintWriter out = this.getResponse().getWriter();
out.println("<h2>正在执行注册方法...</h2>");
return null;
}
public String check() throws Exception{
PrintWriter out = this.getResponse().getWriter();
out.println("<h2>正在执行检查方法</h2>");
return null;
}
}
方法二:使用通配符配置,struts.xml中
<action name=”user_*” class=”com.scce.action.RegAction” method=”{1}”>
这里的{1}是占位符,对应前面name后面的*号,那么提交时需要按照指定格式进行:form.action = 'user_reg.action';
form.action = …user_check.action‟;
Struts提供了一个ValueStack值栈,所有提交请求的数据先放入值栈中,然后再由值栈中放
入对象或者属性中。

----------------------------------------------------------BaseAction-------------------------------------------
所有的Action中获取request、response很麻烦,于是可以开发一个BaseAction,如下:
package com.scce.action;
import com.opensymphony.xwork2.ActionContext;
import java.util.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.ServletActionContext;
public class BaseAction {
//获得request对象
public Map<String,Object> getRequest(){
return (Map)ActionContext.getContext().get("request");
}
//获得Session对象
public Map<String,Object> getSession(){
return (Map)ActionContext.getContext().getSession();
}
//获得ServletContext对象
public Map<String,Object> getApplication(){
return (Map)ActionContext.getContext().getApplication();
}
//获得Response对象
public HttpServletResponse getResponse(){
HttpServletResponse response = ServletActionContext.getResponse();
//设置相应头
response.setContentType("text/html;charset=gbk");
response.setCharacterEncoding("gbk");
return response;
}
}
-------------------------------------------------------------------------Action公用
在Struts1中,默认方法为execute,Struts2中同样也是,这样问题来了,每个操作写个Action 吗?struts1中是通过Action类继承DispatchAction,然后通过在表单或者超链接后传递一个配置的参数用于和方法对应。

那么Struts中简单了,Action中写的方法,如checkLogin(),如addUser,deleteUser等等,则页面提交如下:
<form action=”XXX!addUser.action”>用这种格式去区分
方法2:使用通配符,如下:
<struts>
<!-- Struts2的Action都必须配置在package里面-->
<package name="default" extends="struts-default"><!--继承自默认包-->
<!—使用通配符定义一个user的Action类,实现类为UserManagerAction --> <action
name="user_*"
class="erManagerAction"
method="{1}"/>
</package>
</struts>
为了规范Action类,Struts2提供了一个Action接口
public interface Action
{
public static final ng.String SUCCESS = "success";
public static final ng.String NONE = "none";
public static final ng.String ERROR = "error";
public static final ng.String INPUT = "input";
public static final ng.String LOGIN = "login";
//定义处理用户请求的execute方法
public abstract ng.String execute() throws Exception;}
》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》
public class LoginAction implements Action
{
. . .
public String execute() throws Exception
{
if("scott".equals(this.uid) && "tiger".equals(this.pwd))
{ return this.SUCCESS;
}
return this.ERROR;

--------------------------Action中的验证功能:
ActionSupport是一个工具类,它已经实现了Action借口,还实现了Validatable接口,用于进行验证功能。

通过重写该方法可以在校验表单输入出错时,将错误添加至ActionSupport 类的fieldErrors域中,然后通过Struts2的标签输出错误提示。

Action可以继承ActionSupport类,重写Validate()方法,如下:
Public class LoginAction extends ActionSupport{
Private String uid;
Private String pwd;
Public String execute() throws Exception{
}
Public void validate(){
If(uid.equals(“”)){
This.addFieldError(“uid”,”用户名不能为空”);
}
Else if(pwd.equals(“”)){
This.addFieldError(“pwd”,”密码不能为空”);
}
}
注:validate在execute方法之前执行
页面上使用
<%@taglib uri="/struts-tags"prefix="s"%>
<body>
<s:fielderror />自动显示错误信息
</body>
}
指向跳转还是重定向:
<result name="cheng" type=”dispatcher”>/index.jsp</result>
<result name="bai" type=”redirect”>/fail.jsp</result>
----------------------------
---------------------------------------------拦截器------------------------------------
拦截器类必须实现借口:Interceptor
Void destroy();//执行一次
Void init();//执行一次
String intercept(ActionInvocation invocation) throws Exception;
该方法是用户需要实现的拦截器动作,返回一个result配置字符串作为逻辑视图,该方法的ActionOnvocation参数包含被拦截的Action的引用,可以通过调用该参数的Invoke方法,将控制权转给拦截器或者Action的execute方法
一般通过继承AbstractInterceptor类实现,如下:
一、重写intercept拦截器拦截方法
public class MyInterceptor extends AbstractInterceptor {
// 定义拦截器属性,指定被拦截的Action休眠的时间
private int sleep;
public int getSleep() {
return sleep;
}
public void setSleep(int sleep) {
this.sleep = sleep;
}
public String intercept(ActionInvocation invocation) throws Exception {
System.out.println("开始执行Action的时间:" + (new
Date()).toLocaleString());
//获得当前的Action(这里只是举例看看就行)
//LoginAction ac = (LoginAction)invocation.getAction();
// 获得被拦截的ActionContext对象
ActionContext ctx = invocation.getInvocationContext();
// 取得session
HttpSession session = (HttpSession) ctx.getSession();
// 获得权限
String role = (String) session.getAttribute("role");
// 获得request
Map request = (Map) ctx.get("request");
if (role == null) {
// 说明未登录
request.put("msg", "您还没有登录,请先登录!<a
href=\"login.jsp\">登录</a>");
return"error";
} else {
// 已登录
// System.out.println("已登录......");
// 拦截Action执行的方法名
String method =
invocation.getProxy().getMethod().toLowerCase();
if (!"admin".equals(role) && method.contains("add")
|| method.contains("del") ||
method.contains("update")) {
request
.put("msg",
"对不起,您不是管理员,无此操作权限!<a
href=\"javascript:history.back()\">返回</a>");
return"error";
}
}
// 若权限通过,则直接将请求交给对应的控制器
return invocation.invoke();
}
}
二、配置拦截器:struts.xml文件中:
<package name="default"extends="struts-default"namespace="/">
<!-- 配置拦截器 -->
<interceptors>
<!-- 定义拦截器名称,指定实现类 -->
<interceptor name="myInterceptor"
class="com.scce.invo.MyInterceptor"></interceptor>
</interceptors>
<action name="login"class="com.scce.action.LoginAction"> <result name="input">/login.jsp</result>
<result name="cheng">/index.jsp</result>
<result name="bai">/fail.jsp</result>
<!-- 引用拦截器 -->
<interceptor-ref name="myInterceptor">
<!-- 为拦截器设置属性值,对应到拦截器中的set封装方法 -->
<param name="sleep">2000</param>
</interceptor-ref>
</action>
<!-下面这个未引用拦截器-
<action name="myReg"class="com.scce.action.RegAction"> <result name="cheng">/cheng.jsp</result>
<result name="bai">/bai.jsp</result>
</action>
</package>
注意:Struts2中存在默认的拦截器,只有当Action中未显示指定拦截器时,该Action所在的包的默认拦截器才会对它生效,一旦指定了拦截器,则默认拦截器实效。

配置如下:
<default-interceptor-ref name=”myInterceptor” />//配置为当前包的默认拦截器
-------------------------------查看struts源代码跟踪设置---------------------------------
右键struts2的jar包,属性,找到struts的源代码,进行跟踪设置
------------------------关于在myeclipse中的xml文件中不出提示的问题----------------------
原因在于xml前面的dtd或者xsd文件
Window---Profeences-----XML---XMLcatalog-----Add增加定义文档的dtd文件(struts libary...struts2-core2.16...struts-2.0.dtd文件)
-------------------------------------Namespace说明---------------------------------------- Namespace决定了action的访问路径,默认为””,可以接收所有路径的action Namespace可以写为/,或者/xxx,或/xxx/yyy,对应的action访问路径为/index.action,/xxx/index.action或/xxx/yyy/index.action
Namespace最好也用模块来进行命名。

相关文档
最新文档