struts2总结

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);
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容