struts2 (2017.7.24)
1.在struts2的jar包中拿出apps/blank.war文件,放进Tomcat的文件webapps中然后运行Tomcat,然后拿出所产生的包
2.在刚刚tomcat解压的文件夹中找到struts.xml文件,在src下面粘贴struts.xml配置文件
3.配置web.xml的配置文件并添加核心过滤器
4.编写action类,并将其配置到struts.xml的配置文档中
5.启动项目访问action
核心过滤器的配置
<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>
</filter-mapping>
[图片上传中。。。(1)]
一个请求在Struts2框架中的处理大概分为以下几个步骤:
1、客户端初始化一个指向Servlet容器(例如Tomcat)的请求;
2、这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助,例如:SiteMesh Plugin);
3、接着FilterDispatcher被调用,FilterDispatcher询问ActionMapper来决定这个请求是否需要调用某个Action;
4、如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy;
5、ActionProxy通过Configuration Manager询问框架的配置文件,找到需要调用的Action类;
6、ActionProxy创建一个ActionInvocation的实例。
7、ActionInvocation实例使用命名模式来调用,在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用。
8、一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可能是另外的一个Action链)一个需要被表示的JSP或者FreeMarker的模版。在表示的过程中可以使用Struts2框架中继承的标签。在这个过程中需要涉及到ActionMapper。
[图片上传中。。。(2)]
struts2原理总结:
当用户的一个请求进来时,要先经过核心过滤器,那么此时的核心过滤器会派出ActionMapper来分析这次请求
的目的地,经过访问之后它会生成一个actionMapping对象(里面包含着这次请求需要访问的资源信息)返回给
核心拦截器,核心拦截器会去分析actionMapping对象里面的信息,来确定这次请求是否需要struts2框架来进行
处理,当分析出需要struts2框架来处理时,那么核心拦截器就会将actionMapping对象传递给ActionProxy(负责
调度,指挥整个框架)这个代理,actionMapping就会做一个内部调研,命令ConfigurationManager来读取struts.xml
配置文件,看有没有对应的action来处理这次请求,那么ConfigurationManager会将读取的结果返回给ActionProxy,
如果有相对应的action,那么此时ActionProxy就会将这个Action对象创出来,然后将Action对象和Interceptors交给
ActionInvocation,那么ActionInvocation就会将action通过一个个的拦截器,最终调用这个action,然后这个action
会根据执行的结果返回一个字符串,那么此时的结果处理器类会根据这个字符串和配置文件来进行转发或者重定向,
那么会将结果相应到我们的jsp,我们jsp就会用一些脚本语言来获取这些结果,之后一级一级经过拦截器,最终响应
就会来到浏览器
在包里面配置全局错误页面
<default-action-ref name="default"/>
<action name="default">
<result>/hh.jsp</result> //注意命名的规范
在写ognl表达式的时候form也要写上s <s:form></s:form>
一般解决util和jdbc的date属性时
处理跳转到多少页的处理办法:
<input id="in" style="width: 20px"/>
<button onclick="tiao();">跳转到</button>
function tiao(){
var c=$("#in").val();
location.href="StudentAction_getDetail?page.currentPage="+c;
}
struts2的表单校验
//采用方法校验
1,继承actionsuppost后重写validate方法,然后在里面写出表单校验信息
@Override
public void validate() {
System.out.println("执行这个校验方法");
if(user.getPassword().trim().length()>16){
this.addFieldError("msg", "密码不能超过16位");
}
if(user.getUsername().trim()==""){
this.addFieldError("msg", "用户名不能为空");
}
}
2.在struts。xml的配置文件中写input一个input的返回调用页面
<result name="input">/login.jsp</result>
3,在该页面填写一个<s:fielderror></s:fielderror>标签
注:因为上面的方法所有的方法都回去校验,那么如果只校验一个action的话,那么校验单额方法名称这样写重写validateXxx方法,后面跟需要校验的方法名
//采用配置文件校验
在你需要验证的action的同一级包下面建立ActionName-validation.xml的文件,然后在里面写上请求头约束
<!DOCTYPE validators PUBLIC
"-//Apache Struts//XWork Validator 1.0.3//EN"
"http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
也需要在struts的文件中写上input
如果在用配置文件做校验的时候,要注意配置文件命名规则
StudentAction-add-validation.xml
左边写action的名字,中间写写你要校验的方法名(不写的话那么每个方法都会去校验,可能会报错)
然后在ActionName-validation.xml以这种类型的格式做校验:
<validators>
<field name="user.username">
<field-validator type="requiredstring">
<param name="trim">true</param>
<message>用户名不能为空!</message>
</field-validator>
<field-validator type="stringlength">
<param name="minLength">8</param>
<param name="maxLength">20</param>
<message>用户名长度必须在${minLength}-${maxLength}之间</message>
</field-validator>
</field>
<field name="user.password">
<field-validator type="requiredstring">
<param name="trim">true</param>
<message>密码不能为空!</message>
</field-validator>
<field-validator type="stringlength">
<param name="minLength">6</param>
<message>密码长度必须大于${minLength}</message>
</field-validator>
</field>
<field name="repassword">
<field-validator type="requiredstring">
<param name="trim">true</param>
<message>确认密码不能为空!</message>
</field-validator>
<field-validator type="fieldexpression">
<param name="expression">user.password==repassword</param>
<message>两次密码不一致</message>
</field-validator>
</field>
<field name="user.phone">
<field-validator type="requiredstring">
<param name="trim">true</param>
<message>电话号码不能为空!</message>
</field-validator>
<field-validator type="regex">
<param name="regex">1[3578][0-9]{9}</param>
<message>电话号码格式不正确!</message>
</field-validator>
</field>
<field name="user.email">
<field-validator type="requiredstring">
<param name="trim">true</param>
<message>邮箱不能为空!</message>
</field-validator>
<field-validator type="email">
<message>邮箱格式不正确</message>
</field-validator>
</field>
</validators>
//struts2里面提供的转换器的使用方式:
若struts2框架提供的转换类型没有我们想要的,此时我们可以自己来转换:
1,为要转换的类创建一个转换器,这个类要继承StrutsTypeConterver重写里面的方法,返回值是我们想要的类型,在转换器内部我们要实现转换功能,这个转化器会在action使用这个实体类之前进行转换
2,还要在src的文件夹下面创建固定名字格式的xwork-conversion.properties文件,里面写:
要转换的类(全类名)=装换器类(全类名)
//国际化
1.先在src下自定义配置文件类型resource_zh_CN.properties,分国家的不同来定
然后里面的key为页面上面的key,里面的value翻译为当地国家的语言
2,然后再struts 的配置文件中,配置全局常量
<constant name="struts.custom.i18n.resources" value="resource"/>
那么此时他就会根据浏览器的语言来自定义浏览器显示内容的语言
//文件的的上传
前端页面
<form action="upload.action" method="post" enctype="multipart/form-data">
<input type="file" name="file"/>
文件名<input name="fileName"/>
<button type="submit">上传</button>
</form>
//action写法
private File file;
private String fileFileName; //这个属性为固定的写法,会将文件名自动注入其中
public String upload(){
String path=ServletActionContext.getServletContext().getRealPath("\upload");
File aim=new File(path,fileFileName);
try {
FileUtils.copyFile(file, aim);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
文件的下载:
private InputStream inputStream;
private String fileName;
public String downLoad() throws IOException{
String path=ServletActionContext.getServletContext().getRealPath("\download\1.jpg"); //下载的路径
setInputStream(new FileInputStream(path));
fileName=path.substring(path.lastIndexOf("\")+1); //分割获得文件名
return SUCCESS;
}
<action name="download" class="com.qy.action.DownAction" method="downLoad" >
<result type="stream">
<param name="inputName">inputStream</param>
<param name="contentDisposition">attachment;filename=${fileName}</param>
</result>
</action>
struts2的ajax:
注意:这里需要借助struts的插件来完成对json数据的响应
到struts软件包查找
json-lib-2.3-jdk15.jar
ezmorph-1.0.6.jar
struts2-json-plugin-2.3.20.1.jar
commons-lang-2.4.jar
commons-logging-1.1.3.jar
commons-collections-3.1.jar
commons-beanutils-1.8.0.jar
在action中设置的全局的集合通过配置可以直接在jsp页面取,那么在struts配置文件中要进行相关的配置
<package name="default" namespace="/" extends="json-default">
<action name="json" class="com.qy.action.JsonAction" method="json">
<result name="success" type="json"> 要有类型为json
<param name="root">list</param> name为root ,还有要转换为json的集合
</result>
</action>
</package>
实现隔行换色
<c:forEach items="${page.list }" var="stu" varStatus="status">
<c:if test="${status.index % 2 == 0}">
<tr style="background-color: moccasin ">
<td>${stu.id}</td>
<td>${stu.name}</td>
<td>${stu.age}</td>
<td>${stu.subject}</td>
<td>${stu.birthday}</td>
</tr>
</c:if>
<c:if test="${status.index % 2 != 0}">
<tr style="background-color: lawngreen ">
<td>${stu.id}</td>
<td>${stu.name}</td>
<td>${stu.age}</td>
<td>${stu.subject}</td>
<td>${stu.birthday}</td>
</tr>
</c:if>
</c:forEach>
util.date转化为sql.date的一种方法
ps.setDate(4, new Date(student.getBirthday().getTime()));
ognl遍历方式:
<s:iterator value="list" var="stu">
<tr>
<td><s:property value="#stu.id"/></td>
<td><s:property value="#stu.name"/></td>
<td><s:property value="#stu.age"/></td>
<td><s:property value="#stu.subject"/></td>
<td><s:property value="#stu.birthday"/></td>
</tr>
</s:iterator>
struts—ognl一些标签的用法
[图片上传中。。。(3)]
读取配置文件的方式:
[图片上传中。。。(4)]
可以将值赋值到字段
private void setProperties(Object actionProxy, HttpServletRequest request) throws Throwable {
Map<String, String[]> map = request.getParameterMap();
BeanUtils.populate(actionProxy, map);
}