之前初学struts整理的笔记,现载如下:
一.
1.六个基本包
struts2-core-2.1.6.jar :开发的核心类库freemarker-2.3.13.jar :struts2的UI标签的模板使用freemarker编写
commons-logging-1.0.4.jar:日志包
ognl-2.6.11.jar :对象图导航语言,通过它来读写对象属性
xwork-2.1.2.jar :xwork类图,struts2在其上进行构建
commons-fileupload-1.2.1.jar :文件上传组件,2.1.6版本后必须加入此jar包
2.struts2配置文件
1)web.xml文件
实质是一个过滤器,他负责初始化整个Struts框架并且处理所有的请求。这个过滤器可以包括一些初始化参数,有的参数指定了要加载哪些额外的xml配置文件
2)strusts.xml文件
3)struts.properties
需要在struts.properties文件中指定属性的key和value即可。属性文件可以放在任何一个包含在classpath的路径上,但是我们通常都把他放在/web-inf/classes目录下面。我们可以再strusts-default.properties文件中找到一个属性的列表
4)struts-default.xml
此文件是strusts2框架默认加载的配置文件,它定义了struts2一些核心bean和拦截器,她会自动包含(included)到struts.xml文件中(实质是通过<package etends="struts-default">),并为我们提供了一些标准的配置。我们可以在struts2-core.jar中找到这个文件
5)其他配置文件
velocity.properties,struts-default.vm,struts-plugin.xml
导入dtd以支持提示。
4.开启struts2自带的开发模式常量
在以前的开发中,当修改一些配置是总是不能及时地更新到服务器,我们总会重新部署或重启来更新改变的内容,在struts2中可以通过一个常量来达到此目的。即在struts.xml中的
<struts>元素下增加如下内容:<constant name="struts.configuration.xml.reload" value="true" />
5.vo传参模式
修改如下:在LoginAction中有两个字段:username,password.把此两个属性重构到com.asm.vo.User类中,然后在LoginAction中提供User对象及对应的get/set方法。现在需要注意的是login.jsp中会有如下的修改:
用户名:<input type="text" name="user.username"><br>
密码 :<input type="password" name="user.password"><br>
6.ModerDriver传参模式(不建议使用)
7.为什么使用struts2代替struts1
1)struts2的execute方法中的参数不会依赖于servletAPI,实现了servlet解耦,是一种无侵入式的设计
2)struts2提供了拦截器,利用拦截器可以进行AOP编程,实现权限拦截功能
3)struts2提供了类型转换器,我们可以很容易地对请求参数转换成需要的类型
4)提供了同种表现层技术支持,如JSP,FREEMARKER,velocity等
5)可以对指定的方法进行校验,可以轻松地实现表单校验功能
6)提供了全局范围,包范围和ACTION范围的国际化资源文件管理实现
二 struts.xml配置及例程
1.初识拦截器
拦截器能在action被调用之前和被调用之后执行一些“代码”。struts2框架的大部分核心功能都是通过拦截器来实现的。如防止重复提交,类型转换,对象封装,校验,文件上传,页面预装载等等,都是在拦截器的帮助下实现的。每一个拦截器都是独立装载的(pluggable),我们可以根据实际的需要为每一个action配置他所需要的拦截器。
2.使用ForwardAction实现页面屏蔽
我们在jsp页面之间写连接总会是 .../xxx.jsp,而如果我们想屏蔽掉具体的jsp,只需要把jsp页面配置成一个ForwardAction即可实现。示例如下:在根目录下有一个index.jsp主页,我们struts.xml中作如下配置:
<package name="def" extends="struts-default">
<action name="forward">
<result>/index.jsp</result>
</action>
</package>
说明:如果没在在action中指定class,,默认就是ActionSupport类,如果没有为action指定method属性,则默认执行execute方法,如果没有指定result的name属性,默认值为success。知道了这些再结合ActionSupport的代码就不难理解转发的原理了。
3.使用default-Action配置统一访问
default-action-ref,当访问没有找到对应的action时,默认就会调用default-action-ref指定的action.同样在上面的package中增加如下内容:
<default-action-ref name="error"></default-action-ref>
<action name="error">
<result>/other/error.jsp<result>
</action>
上面一段内容就是说当我们访问的action不能被找到时便指向名为error的action中去,接着我们在下面配置了这个error Action。但是要注意,一个package内只配置一个<default-action-ref>,治国配置多个,就无法预测结果了。
4.Reasult配置详解
三.在Action获取Scope对象
在前面的Action操作中,关键就是Action中的execute方法,但是此方法并没有request,session,application等对象作为参数,自然就不能利用这些对象来操作。下面我们建立struts2scope项目,并用四种方式来获取这些对象:
方式一.与Servlet解耦合的非IOC方式
获取的scope对象与容器无关,通过ActionContext获取
LoginAction代码如下:
package com.asm;
public class LoginAction extends ActionSupport {
private String username;
ActionContext context;
Map request;
Map session;
Map application;
public String execute() throws Exception{
context=ActionContext.getContext();
request=(Map)context.get("request");
session=context.getSession();
application=context.getApplication();
request.put("rep","request属性");
session.put("ses","session属性");
application.put("app","application属性");
return SUCCESS;
}
}
方式二.与Servlet解耦合的IOC方式
package com.asm;
public class Login2Action extends ActionSupport implements
RequestAware,SessionAware,ApplicationAware{
private String username;
Map request;
Map session;
Map application;
public String execute() throws Exception{
request.put("req","request属性");
session.put("ses","session属性");
application.put("app","application属性");
return SUCCESS;
}
public void setRequest(Map<String,Object> request){
this.request=request;
}
public void setSession(Map<String,Object> session){
this.session=session;
}
public void setApplication(Map<String,Object> application){
this.application=application;
}
.......省略username的get/set方法
}
此方法和方式一很相似,只是在方式一中我们需要手动的为Map request赋值,但是在方式二中它是通过实现接口,在重写接口中的方法中完成对Map request赋值,但是在方式二中它是通过实现接口,在重写接口中的方法中完成对Map request的赋值,所以称之为IOC方式。依赖注入与控制反转:所谓依赖注入就是一个对象自己本身的初始化是依赖其他对象。比如这里Map request这些对象会依赖struts2来给其初始化,称为依赖注入,而依赖注入的就表示,这些对象的控制权不再由此类本身掌握,而是交给了别的对象,即使控制反转了。强调:方式二是开发中主要用的方式,应重点掌握。
五.拦截器
1概述
拦截器是Struts框架的核心,它主要完成解析请求参数,将请求参数赋值给Action属性,执行数据校验,文件上传等工作。Struts2设计的灵巧性,拦截器起了关键性的作用,当需要扩展Struts2功能时,只需要提供对应拦截器,并将它配置在Struts容器中即可;如果不需要该功能时,也只需要取消该拦截器的配置即可。
Struts2内建了大量的拦截器,这些拦截器以name-class对的形式配置在struts-default.xml文件中,其中name是拦截器的名字,就是以后我们使用该拦截器的唯一标识:class则制定了该拦截器的实现类,如果我们定义的package继承了Struts2的默认struts-default包,则可以自由使用它下面定义的拦截器,否则必须自己定义这些拦截器。
2.自定义拦截器
自定义拦截器需要特别注意的是不要忘记引入struts2默认的拦截器。为了实现某些操作,我们可以自定义拦截器,自定义拦截器有三种方式定义。分别为实现Interceptor接口,继承抽象类AbstractInterceptor,继承MethodFilterInteceptor类。
方式一,实现Interceptor接口
准备工作,新建struts2iNTERCEPTOR项目。构建一个登录环境:当我们点登陆链接时,便成功登录(为了方便,这里不进行验证)。即在link.jsp页面中写如下链接:<a href="<%=request.getContextPath()%>/login.action">登录</a> 然后,我们点击此链接便可以登录。
login.action在struts.xml中的配置如下:
<package name="interceptor" extends="struts-default">
<action name="login" class="com.asm.LoginAction">
<result name="success">/success.jsp</result>
</action>
</package>
com.asm.LoginAction为了简单,com.asm.LoginAction总是返回SUCCESS;这样请求这个Action总会返回到.../success.jsp页面。
编写拦截器:MyIntercptor类,内容如下:
package com.asm;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
public class MyInterceptor implements Interceptor {
public void destroy(){
}
public void init(){
}
public String intercept(ActionInvocation invocation) throws Exception {
System.out.println("开始拦截");
String result=invocation.invoke();
System.out.println("结束拦截");
return result;
}
}
为了使用此拦截器,我们必须将此拦截器进行注册,随后再在要使用此拦截器的Action中引用。即首先在<package>中注册,内容如下:
<interceptions>
<interceptor name="myIpt" class="com.asm.MyInterceptor"></interceptor>
</interceptors>
注册完成后,如果我们要在login.action中使用此拦截器,只需要要<action>中增加如下内容:
<interceptor-ref name="mtIpt"></interceptor-ref>
这样便成功为LoginAction配置了我们自定义的拦截器MyInterceptor,下面只需发布测试。
实例流程分析:当我们为LoginAction配置了拦截器时,并且有客户端请求此Action时,会首先被此栏且其拦住,然后执行System.out.println("开始拦截"),随后我们调用invocation.invoke()方法,它会把请求继续传递给下一个拦截器,下一个拦截器也会继续执行相应代码后再调用invoke()方法继续传递,直到请求到达最后一个拦截器,它会把请求传递给Action,比如,我们这里只用到了一个拦截器,当它执行完成后,会把请求直接转交给LoginAction处理,LoginAction处理完成后,它会返回结果给MyInterceptor拦截器。
三种配置方式
六, 使用标签
1.基础表单标签
<%@ page language="java" pageEncoding="utf-8"%>
<%@ taglib url="/struts-tags" prefix="s" %>
<html>
<body>
<s:form action="login" method="post" namespace="/my">
<s:textfield label="用户名" name="user.username" required="true"
requiredposition="right"/>
<s:password label="密码" name="user.password" required="true" />
<s:reset value="重要" align="left" />
<s:submit value="注册" align="left" />
</s:from>
</body>
</html>
说明:label中的内容是显示在表单前的提示内容,required设为true,表示此表单项为必填内容
2.单选按钮盒复选框
<s:radiolist="#{1:'男',0:'女'}" value="1" label="性别" name="user.sex" />
<s:checkboxlist list="#{1:'足球,2:'排球',3:'篮球',4:'网球'}" name="user.love" label="爱好" />