一.struts2框架的开发准备
1.介绍
struts2是实现的MVC模式的JavaEE企业级的轻侵入性.轻量级的表现层web开源框架,提供了开发,发布,到维护过程中的支持.
2.需要资源下载
在apache的官网开开源软件中进行下载https://struts.apache.org/
注意事项:
有两个版本
可下载Struts2.3.15以上版本或者struts2.5.10以上版本,较低版本存在远程执行漏洞
3.jar包的添加
8个jar包
commons-fileupload/commons-io 支持文件上传下载
commons-lang3 提供语言的一些扩展
javassist 字节码处理
ognl 一种强大的El表达式
freemarker 模板视图技术
log4j 日志管理
struts2-core 核心jar包
二:开发流程
1.前端控制器的配置
在web项目的WebContent下的WEB-INF下的web.xml中行进行配置
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>这里写欢迎首页</welcome-file>
</welcome-file-list>
2.定义核心配置文件
在src下新建struts.xml的文件
加入文件声明,然后配置文件
配置xml文件提示(如果有网络支持则不需要):
讲strruts-2.5.dtd文见另存在当前项目下,然后再eclipse中进行如下配置
3.控制器的三种定义方法
方法一;
不继承任何类也不实现任何借口
在该类中有一个如下方法
public String execute(){
return "返回的标志";
}
方法二:
实现Action接口
五大常量
1.success 执行器中执行正常,跳转成功页
2.none 不做跳转,一般用用于调试
3.input 显示校验不通过返回页面
4.error 显示错误输出页面
5.login 显示登录成功页面
@Override
public String execute() throws Exception {
return SUCCESS;
}
@Override
public void validate() {
//校验前端数据
}
方法三:
继承ActionSupport类
implements Action, 实现了Action接口,则5大常量和execute方法签名有效
Validateable, ValidationAware,对于服务器端数据校验提供了支持
TextProvider, LocaleProvider,对于国际化I18N、本地化L10N
Serializable序列化接口
重写该方法
@Override
public String execute() throws Exception {
return SUCCESS;
}
@Override
public void validate() {
//校验前端数据
}
4.action中接受前台数据
1.属性驱动
定义一个类,其中属性对应输入域中的那么属性,并添加set/get方法
示例代码
页面输入域
<input name="username" />
后台类
public class HelloAction {
private String username;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
2.模型驱动
定义一个类实现ModelDriven泛型为JavaBean类
示例代码
页面输入域
<input name="username" />
控制类
public class HelloActionDemo extends ActionSupport implements ModelDriven<UserBean> {
private static final long serialVersionUID = 1L;
private UserBean user=new UserBean();
@Override
public UserBean getModel() {
return user;
}
}
JavaBean
package com.tubo.service;
public class UserBean {
private String username;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
3.对象驱动
定义一个类 生命出一个JavaBean的对象
输入域中name属性为 对象.属性
示例代码
页面输入域
<input name="user.username" />
控制类
public class HelloActionDemo {
private UserBean user;
}
JavaBean
public class UserBean {
private String username;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
5..核心文件的配置参数解读
- 基本配置
<constant name="struts.action.extension" value="action"/>
url默认后缀为action
<constant name="struts.i18n.encoding" value="utf-8"/>
这部分设置在/org/apache/struts2/default.properties文件中保存着
<package name="aaa" extends="struts-default" namespace="/">
aaa为给包起的名字
struts-default继承的报名
namespace=""用于定义action地址的名空间,可以不配置,不配置则等价于 namespace=""
<action name="hello" class="com.tubo.service.HelloAction" >
hello为 页面提交的名称去掉后缀
com.tubo.service.HelloAction为 包名.类名
<result name="show">/WEB-INF/context/welcome.jsp</result>
定义响应 show为exectue执行后返回的标志
/WEB-INF/context/welcome.jsp 需要跳转的也面位置
</action>
</package>
- action类中的方法定义配置
方法一
//逐个进行配置
<package name="default" extends="struts-default" strict-method-invocation="false">
<action name="add" class="com.tubo.service.HelloDemoAction" method="add"></action>
<action name="del" class="com.tubo.service.HelloDemoAction" method="del"></action>
<action name="user" class="com.tubo.service.HelloDemoAction" method="user"></action>
<action name="find" class="com.tubo.service.HelloDemoAction" method="find"></action>
<action name="hello" class="com.tubo.service.HelloAction">
<result name="show">/WEB-INF/context/welcome.jsp</result>
</action>
方法二
//模糊配置
<package name="default" extends="struts-default" strict-method-invocation="false">
strict-method-invocation设为false关闭严格匹配
<action name="*" class="com.tubo.service.HelloAction" method="{1}">
//前面name所对应的模糊匹配和后面method的{1}相对应
<result name="show">/WEB-INF/context/welcome.jsp</result>
</action>
</package>
方法三
<action name="*_*" class="com.tubo.service.{1}Action" method="{2}"></action>
//第一个*对应类名,第二个*对应方法名
- 和调试相关的常量配置
建议在开发阶段打开,部署阶段关闭
//方法一
<filter>
<init-param>
<param-name>struts.configuration. xml.reload</param-name>
//自动发现并加载修改的 struts.xml 之类的配置文件
<param-value>true</param-value>
<init-param>
<param-name>struts.i18n.reload </param-name>
//自动发现并加载修改的properties文件
<param-value>true</param-value>
</init-param>
</filter>
//方法二(相当于以上俩个方法)
<filter>
<init-param>
<param-name>struts.devMode</param-name>
<param-value>true</param-value>
</init-param>
</filter>
resault
在result的type属性中进行定义
<result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>
<!--请求转发-->
<result-type name="redirect" class="org.apache.struts2.result.ServletRedirectResult"/>
<!--重定向-->
<result-type name="stream" class="org.apache.struts2.result.StreamResult"/>
<!--设置缓冲流-->
这里写代码片
6.jsp页面存放最佳实践
,一般建议将所有的jsp页面定义在/WEB-INF/content/文件夹下,这样可以保护页面的访问
struts中路径配置如下
< result name=”success”>/WEB-INF/content/user/welcome.jsp< / resault>
7.Action中的数据校验
方法一:
Action中定义方法进行校验
前面已经引入了execute()方法对应的校验方法vaildate(),其实还可以定义Action中单个方法对应的校验方法
//命名规则vaildate+方法名
//例如要给login方法添加校验方法 方法名应为vaildateLogin()
在执行login方法之前会执行vaildate()方法[通用,每个方法之前都会调用此方法进行校验]
和vaildateLogin()方法
方法二;
配置文件校验
Xml校验规则文件对应的dtd文件位于struts2-core.jar中/xwork-validator-1.0.3.dtd
校验子说明文件—规定验证的名称
Struts2-core.jar中com/opensymphony/xwork2/validator/validators/ default.xml\
<validator name="required" class="com.opensymphony.xwork2.validator.validators.RequiredFieldValidator"/>
<!-- 必填验证,用户验证数据不能为null,但是简单类型不适用(简单类型存在默认值)-->
<validator name="requiredstring" class="com.opensymphony.xwork2.validator.validators.RequiredStringValidator"/>
<!--必填验证,用于验证字串不能为null或者空串,默认会去除空格(即trim()方法) -->
<validator name="int" class="com.opensymphony.xwork2.validator.validators.IntRangeFieldValidator"/>
<!--整数范围验证,,可以定义最大值max和最小值min -->
<validator name="long" class="com.opensymphony.xwork2.validator.validators.LongRangeFieldValidator"/>
<!-- 整数范围验证 -->
<validator name="short" class="com.opensymphony.xwork2.validator.validators.ShortRangeFieldValidator"/>
<!-- 整数范围验证-->
<validator name="double" class="com.opensymphony.xwork2.validator.validators.DoubleRangeFieldValidator"/>
<!--浮点数范围验证,minInclusive和maxInclusive允许等于、minExclusive和maxExclusive不允许等于,这4个参数允许任意组合 -->
<validator name="date" class="com.opensymphony.xwork2.validator.validators.DateRangeFieldValidator"/>
<!-- 日期范围验证可定义最大值max嗯哼最小值min-->
<validator name="expression" class="com.opensymphony.xwork2.validator.validators.ExpressionValidator"/>
<!--定义OGNL表达式,满足定义则通过 -->
<validator name="fieldexpression" class="com.opensymphony.xwork2.validator.validators.FieldExpressionValidator"/>
<!-- 自定义属性相关的表达式验证-->
<validator name="email" class="com.opensymphony.xwork2.validator.validators.EmailValidator"/>
<!--邮箱格式验证 -->
<validator name="creditcard" class="com.opensymphony.xwork2.validator.validators.CreditCardValidator"/>
<!--visa信用卡号验证 -->
<validator name="url" class="com.opensymphony.xwork2.validator.validators.URLValidator"/>
<!-- 网址格式验证-->
<validator name="visitor" class="com.opensymphony.xwork2.validator.validators.VisitorFieldValidator"/>
<!--符合验证 -->
<validator name="conversion" class="com.opensymphony.xwork2.validator.validators.ConversionErrorFieldValidator"/>
<!-- 数据类型转换失效验证-->
<validator name="stringlength" class="com.opensymphony.xwork2.validator.validators.StringLengthFieldValidator"/>
<!--字串长度验证,不区分中英文,可设置minlength和maxlength -->
<validator name="regex" class="com.opensymphony.xwork2.validator.validators.RegexFieldValidator"/>
<!--正则表达式验证 -->
<validator name="conditionalvisitor" class="com.opensymphony.xwork2.validator.validators.ConditionalVisitorFieldValidator"/>
<!-- 复合验证-->
针对某个Action类进行校验
命名规则 类名-vaildate.xml
//例如针对HelloAction类进行校验的xml应命名为 HelloAction-vaildate.xml
针对某个url进行校验
命名规则 类名-url-vaildate.xml
//例如针对HelloAction类的hello.action地址进行的校验 HelloAction-hello-vaildate.xml
validate配置文件的属性解析
<validators>
<field name="username"需要验证的输入域名称>
<field-validator type="填写需要的验证" short-circuit="true"给属性指定为true即表示前面验证不通过不进行后续验证>
<message>用户名不允许为空!(报错信息)</message>
</field-validator>
</field>
<validators>
客户端校验
事实上xwork对客户端校验也提供了支持,只需要在标签中添加属性validate=true即可
8.Action中访问ServletAPI的方法
方法一:
通过ActionContext工具类获取的就是attribute:
public String execute() {
ActionContext context = ActionContext.getContext();
context.put("", "");
return "show";
}
方法二:
使用工具类ServletActionContext可以直接获取Servlet API对象
PageContext pageContext = ServletActionContext.getPageContext();
HttpServletRequest request = ServletActionContext.getRequest();
HttpServletResponse response = ServletActionContext.getResponse();
ServletContext servletContext = ServletActionContext.getServletContext();
ActionContext context2 = ServletActionContext.getContext();
方法三:
在Action类声明上使用xxxAware接口,由框架负责注入所需要的对象
public class HelloAction implements ServletRequestAware{
private ServletRequest request;
public String execute() {
return "show";
}
@Override
public void setServletRequest(HttpServletRequest arg0) {
this.request=arg0;
}
}
9:文件上传及下载
一:上传
在页面的输入域中定义的那么属性值在action中应该定义三个属性与之对应
例如
页面
<s:file name="photo" >
Action中应该定义以下三个属性
private File photo;//用于表示上传文件的对象名称
private String photoFileName;//用于表示上传文件在客户端的名称
private String photoContentType;//用于表示上传文件的类型
if(photo!=null&&photo.length()>0) throws Exception {
String path = application.getRealPath("文件存放路径");
File ff = new File(path,"新文件名");
FileUtils.copyFile(photo, ff);//将文件拷贝到服务器文件夹下
}
在struts中设置文件上传拦截器
<interceptor-ref name="fileUpload">
<param name="maximumSize">204800</param>
<param name="allowedExtensions">jpg,png,pif</param>
<param name=""></param>
</interceptor-ref>
由于报错信息为英文,处理为在struts中配置全局参数
<constant name="struts.custom.i18n.resources" value="msg" />
并且在src的根目录下创建文件msg.properties
内容修改为相关的中文报错信息
struts.messages.error.file.too.large=大小不对应的报错信息
struts.messages.error.file.extension.not.allowed=文件格式不匹配的报错信息
二:下载
页面
将<img>表情嵌套在<a>标签中
<a href="download.action?filename=${mm}">
<img src="upload/${mm}"></a>
Action
private String filename;
public String execute() throws Exception {
response.resetBuffer();//刷新缓冲区
response.setHeader("Content-disposition", "attachment;filename="+filename);
//设置响应头
byte[] buf=new byte[8192];
int len=0;
String path = application.getRealPath("upload");
File ff = new File(path, filename);
ServletOutputStream os = response.getOutputStream();
if(ff.exists()) {
FileInputStream is = new FileInputStream(ff);
while((len=is.read(buf))>0) {
os.write(buf, 0, len);
}
is.close();
os.close();
}
return NONE;
}
10页面显示的标签属性
<s:property>标签
访问Action中的普通属性: <s:property value="attrName"/>
访问Action中的对象属性(要有get set方法): <s:property value="obj.attrName"/>
访问对象属性的方法 <s:property value="obj.methodName()"/>
访问值栈中action的普通方法: <s:property value="methodName()"/>
defaule //表示不能获取到值是所显示的属性
escapeHtml //用于设置是否将所包含的html标签转换为实体字符
value //用于表示ognl表达式所显示的值
<s:if标签>
用于进行条件判断,可以单独使用也可以配合<s:else><s:elseif使用>
#parameters是struts2中OGNL所使用的默认对象,用于获取请求参数,获取方法类似于request.getParameterValues():String[]
<s:if value="#parameters.属性值>85">优秀<s:if>
<s:iterater> 用于实现迭代访问集合
value 用于获取被跌代的对象
var 指定元素集合中元素的临时变量
stauts 用于表示跌代对象的状态
生成一个url地址,可以通过url标签制定的<s:param>子元素向URL地址发送请求参数
<s:url var=”变量名称” action="对应的action名称"> 指定请求地址
<s:param name="参数名称" value="OGNL表达式,获取参数的值"/>指定参数
<s:a> 用于生成a标签
默认的href会指定默认的地址值 如果使用ognl表达式则需要指定的格式 %{ognl表达式}进行强制计算
<s:a href="login.action">