标签:
Struts2框架技术重点笔记
1.Struts2 是在webwork基础上发展而来。
2.Struts2 不依赖struts API和 servlet API
3.Struts2提供了拦截器,表现层技术:jsp +freeMarket+ velocity
4.Struts2可以对指定的方法进行校验,提供了全局范围,包范围和action范围的国际化资源文件的管理实现。
环境搭建:找到对应的jar包
编写struts的配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.action.extension" value="do" />
<constant name="struts.devMode" value="false" />
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<package name="test" extends="struts-default">
<action name="hello" class="test.hello">
<result>/index.jsp</result>
</action>
</package>
</struts>
在web.xml中加入strutsMVC框架的启动配置。
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<display-name>Struts 2 Mailreader</display-name>
<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>
<!-- Application Listener for Mailreader database -->
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
逻辑处理类hello.java
package test;
import com.opensymphony.xwork2.ActionSupport;
@SuppressWarnings("serial")
public class hello extends ActionSupport{
public static String MESSAGE="hello world!";
public String execute() throws Exception{
setMessage(MESSAGE);
return SUCCESS;
}
private String message;
public void setMessage(String message){
this.message=message;
}
public String getMessage(){
return message;
}
}
前台jsp页面:
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP ‘index.jsp‘ starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<h2>
<s:property value="message"/>
</h2>
</body>
</html>
5.Struts2中的执行流程
StrutsPrepareAndExecuteFilter //struts2内部核心的类
Interceptor,struts2 //内置的一些拦截器或者用户自己定义的拦截器
Action //用户自己编写的action,其中的action是线程安全的
Result //类似于forward请求转发
Jsp/html //视图层
6.在Struts2中指定多个配置文件
<struts>
<include file=”struts-user.xml”/>
<include file=”struts-order.xml”/>
</struts>
7.Struts2有两种类型转换器
局部转换器:
针对某个action HelloWorldAction-conversion.properties,针对HelloWorldAction
属性文件中,属性名=类型转换器的所在包+类名
全局转化器:
针对整个项目的action
Xwork-conversion.properties
例如:
java.util.Date=ConvertDemo.DateTypeConverter
重写方法:
package ConvertDemo;
import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.Map;
import com.opensymphony.xwork2.conversion.impl.DefaultTypeConverter;
//自己定义了类型转换器
//如果对于局部类型转换器,则需要将某个属性文件对应于action
public class DateTypeConverter extends DefaultTypeConverter{
//重写方法
@Override
public Object convertValue(Map<String, Object> context, Object value,Class toType) {
// TODO Auto-generated method stub
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
try{
if(Date.class==toType){//当字符串向date类型转换时
//将value转换为string数组
String params[] = (String [])value;
//用dateFormat去按照索引解析字符串
return dateFormat.parse(params[0]);
}else if(toType==String.class) {//当data转换为字符串时
Date date = (Date)value;
//用dateFormat去解析字date
return dateFormat.format(date);
}
}catch(Exception e){
e.printStackTrace();
}
return null;
}
}
7. 各个属性的理解:
1.package:是来管理一组功能相关的action
2.mytest:名字自己定义,主要是供继承所使用
3.namespace:命名空间,作为访问action的路径的一部分
4.extends:继承,struts-default包含了很多struts2定义的很多核心功能,拦截器等
5.userAction:action的名称,来自于test.userAction
6./success.jsp:返回的结果,导向一个页面
7.注意:action的搜索顺序,为先在当前命名空间中查找,查找不到就返回上一级,知道追溯到默认的命名空间,即namespace为空字符串
8.如何在配置文件中设置一些常见的常量?
设置action的访问后缀
<constant name=”struts.action.extension” value=”do,action”/>
设置开启动态方法调用
<constantname=”struts.enable.DynamicMethodInvocation”value=”false”>
设置文件的上传大小
<constant name=”struts.multipart.maxSize” value=”1000000”>
9.定义全局的视图,可以被其他的包所继承
<package name="BasePackage" extends="struts-default">
<global-results>
<resultname="message">/WEB-INF/client/success.jsp</result>
</global-results>
</package>
只要action返回一个message就会调转到success.jsp
其他包的extends属性为extends=”BasePackage”
10.action中几个默认值
1.如果没有为action指定类class,默认是实现类ActionSupport
2.如果没有为action指定要执行哪个方法,默认执行execute方法,该方法会返回一个String类型的success
3.如果没有指定result的name,默认返回success
11.在一个action中处理请求时将页面重定向到另外一个action?
<action name="redirectAction">
<result type="redirectAction">
!-- action名称 -->
<param name="actionName">s1</param>
<!-- 命名空间名字 -->
<param name="namespace">/school</param>
</result>
</action>
注意将result的type类型设置为redirectAction
通过<param>设置要重定向到的action名称和所在的命名空间
12.使得一个action将页面的内容原样输出
<action name="plainText">
<!-- 注意在这里,result的name为默认值success,不可以乱写 ,result类型一定为plainText-->
<result type="plainText">
<param name="location">/index.jsp</param>
<!-- 指定读取文件的编码为utf-8 -->
<param name="charSet">UTF-8</param>
</result>
</action>
13.使用通配符进行action的动态方法调用
<action name="hwa*" class="test.HelloWorldAction" method="{1}">
<result name="success">/WEB-INF/client/message.jsp</result>
</action>
hwaAdd将执行action中的add方法
hwaUpdate将执行action中的update方法。
14.action获取请求参数
视图层:
<form action="<%=request.getContextPath()%>/test3/requestPara.do" method="post">
id:<input type="text" name="person.id"><br>
name:<input type="text" name="person.name"><br>
<input type="submit" value="OK"/>
</form>
配置器:
<!-- 测试请求参数 -->
<action name="requestPara" class="test.RequestAction" method="execute">
<result name="success">/WEB-INF/client/message.jsp</result>
</action>
Action:
package test;
import java.util.Date;
import JavaBean.Person;
public class RequestAction {
private Person person;
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
public String addUI(){
return "success";
}
public String execute(){
return "success";
}
}
结果显示层,通过el表达式输出对象的值:
<!-- 访问RequestAction中的JavaBean对象中的数据 ,person是一个复合类型-->
id=${person.id}<br/>
name=${person.name}
15.action进行输入校验
<!-- 验证输入校验的action -->
<package name="person" namespace="/person" extends="struts-default">
<action name="manage_*" class="validate.PersonAction" method="{1}">
<result name="input">/validate.jsp</result>
<result name="message">/WEB-INF/page/message.jsp</result>
</action>
</package>
在action中利用代码实现合法性检查:
package validate;
import java.util.regex.Pattern;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
/*
* PersonAction测试了action的输入校验
* 1.一定要继承ActionSupport类
* 2.并且重写validate方法
* 3.将错误信息写入FieldError
* 前台:
* 1.要引入struts2的标签库<%@ taglib uri="/struts-tags" prefix="s"%>
* 2.导入显示标签:<s:fielderror/>
* */
public class PersonAction extends ActionSupport {
// 注意:重写验证的方法,该方法对action中的所有方法进行校验,加@override注解
//如果是对某个方法进行校验,就执行validateXxx方法,不再有@override注解
//如果有错误信息或者类型转换失败,就会进入input视图,定义的返回为input的值在action中进行定向到validate.jsp页面
public void validateUpdate() {
if (this.username == null || "".equals(this.username.trim())) {
// 向FieldError中添加错误信息
this.addFieldError("username", "用户名不可以为空");
}
if (this.tel == null || "".equals(this.tel.trim())) {
this.addFieldError("tel", "手机号不可以为空");
} else {
// 利用正则表达式检验
if (!Pattern.compile("^1[358]\\d{9}$").matcher(this.tel).matches()) {
this.addFieldError("tel", "手机号格式不对");
}
}
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
// 定义用户名
private String username;
// 定义用户的电话
private String tel;
public String update() {
ActionContext.getContext().put("message", "update successfully");
return "message";
}
public String save() {
ActionContext.getContext().put("message", "save successfully");
return "message";
}
}
如果是用配置文件检查:
配置文件:
<?xml version="1.0" encoding="utf-8"?>
<!-- 指定校验配置文件的DTD信息 -->
<!DOCTYPE validators PUBLIC
"-//Apache Struts//XWork Validator 1.0.3//EN"
"http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
<!-- 校验文件的根元素 -->
<!-- 基于xml方法对action进行校验 xml文件和action放在同一个包下,如果对action中所有的方法进行校验,action名字-validation.xml -->
<!-- 如果对于action中某个方法进行校验,就取名PersonAction-manage_save-validation.xml
manage_*在struts配置文件中用了通配符
-->
<validators>
<field name="username">
<field-validator type="requiredstring">
<param name="trim">true</param>
<message>用户名不能为空!</message>
</field-validator>
</field>
<field name="mobile">
<field-validator type="requiredstring">
<message>手机号不能为空!</message>
</field-validator>
<field-validator type="regex">
<param name="expression"><![CDATA[^1[358]\d{9}$]]></param>
<message>手机号格式不正确!</message>
</field-validator>
</field>
</validators>
16.通过action访问几个作用域?
action中的execute方法:
public String execute(){
ActionContext ctx = ActionContext.getContext();
ctx.getApplication().put("application", "application");
ctx.getSession().put("session","session");
ctx.put("request", "request");
return "message";
}
先取得一个上下文对象,在该对象中放入键值对,返回message;
前台取值,
${applicationScope.application}
${sessionScope.session}
${resuestScope.request}
17.文件上传
处理文件上传的action,
public class FileUploadAction {
//定义文件对象
private File image;
//定义问价名
private String imageFileName;
public String getImageFileName() {
return imageFileName;
}
public void setImageFileName(String imageFileName) {
this.imageFileName = imageFileName;
}
public File getImage() {
return image;
}
public void setImage(File image) {
this.image = image;
}
//execute方法
public String execute() throws IOException{
//得到文件的上传路径,没有就创建
String realPath = ServletActionContext.getServletContext().getRealPath("/images");
System.out.println(realPath);
//如果文件不为空,根据文件的真实路径和文件名创建文件保存路径
if(image!=null){
File savefile = new File(new File(realPath),imageFileName);
if(!(savefile.getParentFile().exists())){
savefile.getParentFile().mkdirs();
}
//将该文件拷贝到该新创建的保存路径
FileUtils.copyFile(image, savefile);
//在上下文对象中放入一个标志message
ActionContext.getContext().put("message", "ok");
}
return "success";
}//end of execute
处理多文件上传:
public String execute2() throws IOException{
String realPath = ServletActionContext.getServletContext().getRealPath("/images");
System.out.println(realPath);
if(image!=null){
File savedir = new File(realPath);
if(!savedir.exists()){
savedir.mkdirs();
}
for(int i=0;i<image.length;i++){
File savefile=new File(savedir,imageFileName[i]);
FileUtils.copyDirectory(image[i], savefile);
}
}
ActionContext.getContext().put("message", "ok");
return "success";
}//end of execute
image和imageFileName属性全部定义成数组处理
struts中配置:
<!--测试文件上传 -->
<actionname="fileadd"class="FileUpload.FileUploadAction"method="execute">
<resultname="success">/WEB-INF/client/uploadResult.jsp</resul>
</action>
uploadResult.jsp页面输出${message},判断是否成功上传
18.action中如何申明拦截器?
Struts.Xml中的配置:
<packagename="test4"namespace="/test4"extends="struts-default>
<!-- 注册拦截器 -->
<interceptors>
<!-- 声明自己的拦截器 -->
<interceptorname="permission"class="Intercepter.PermissionInterceptor"></interceptor>
<!--将该拦截器放入拦截器栈中-->
<interceptor-stack name="permissionStack">
<!-- 应用系统默认的拦截器栈 -->
<interceptor-ref name="defaultStack"/>
<!-- 加入自己的拦截器 -->
<interceptor-ref name="permission"/>
</interceptor-stack>
</interceptors>
<!-- 定义该action的全局视图 -->
<global-results>
<result name="success">/WEB-INF/client/IntercepterResult.jsp</result>
</global-results>
<action name="intercepter" class="Intercepter.IntercepterAction"
method="execute">
<!-- 调用拦截器时,要去调用新的拦截器栈permissionStack -->
<interceptor-ref name="permissionStack"></interceptor-ref>
</action>
</package>
PermissionInterceptor一定要去实现Interceptor接口,例如定义的一个许可拦截器,先判断session中是否有该用户,有的话,,,,没有的话,,,。
public class PermissionInterceptor implements Interceptor {
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void init() {
// TODO Auto-generated method stub
}
@Override
public String intercept(ActionInvocation invocation) throws Exception {
// TODO Auto-generated method stub
Object user = ActionContext.getContext().getSession().get("user");
if (user != null) {
return invocation.invoke();
}
ActionContext.getContext().put("message", "no permission");
return "success";
}
}
IntercepterResult.jsp页面中:
${message},如果sesssion中得不到user,提示:no permission
19.struts中定义国际化文件?
配置文件:
<struts>
<!--通过常量,将test定义为全局范围的资源文价 -->
<constant name="struts.custom.i18n.resources" value="test"></constant>
<package name="person" namespace="/person" extends="struts-default">
<action name="manage" class="nativeDemo.managePersonAction">
<result name="message">/WEB-INF/page/message.jsp</result>
</action>
</package></struts>
1)在项目根路径下定义国际化文件:
定义中文,test_zh_CN.properties,test为基础名,随便起
定义英文,test_en_US.properties,test基础名,随便起
{0}{1}是占位符
2)定义包下的国际化文件:
package_zh_CN.properties,package是必须写的
3)定义针对于某个action的国际化文件:
managePersonAction_zh_CN.properties,managePersonAction为action的名字
搜素顺序:
Action->包->项目根路径
访问该国际化文件:
对于Action:
package nativeDemo;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
/*
* 在action中取值this.getText("name的值");
*
* */
public class managePersonAction extends ActionSupport {
@Override
public String execute() throws Exception {
//将国际化信息放入map集合中,key为message,值为我们定义的国际化信息的name
//没有占位符的情况:
//ActionContext.getContext().put("message",this.getText("welcome"));
//有占位符的情况,参数多个一个String类型的数组:
ActionContext.getContext().put("message",this.getText("welcome",new String[]{"admin","study"}));
return "message";
}
}
对于jsp:
<body>
<!-- 1.如果访问项目根路径,全局范围内的国际化文件,name为基础名test
2.如果访问某个包下的国际化文件,包名/package
3.如果访问包下的action,包名/actionName
4.s:param标签是给参数占位的
5.s:i18n控制优先访问的国际化文件的位置
-->
<s:i18n name="nativeDemo/managePersonAction">
<s:text name="welcome">
<s:param>jiaqing</s:param>
<s:param>direct-visit</s:param>
</s:text>
</s:i18n>
</body>
20.采用EL表达式仅能访问valueStack中某个对象的属性。可以直接访问action中的属性
21.struts2常用几个标签
<!-- property标签 -->
<s:set name="username" value="‘admin‘"></s:set>
<s:property value="#username"></s:property>
<br>
<!-- iterator标签 -->
<s:set name="mylist" value="{‘xjq‘,‘mm‘,‘admin‘,‘teacher‘}"></s:set>
<s:iterator value="#mylist">
<s:property></s:property>
</s:iterator>
<br>
<!-- ifelse标签 -->
<s:set name="age" value="210"></s:set>
<s:if test="#age==23">
23
</s:if>
<s:elseif test="#age==21">
21
</s:elseif>
<s:else>
not equal
</s:else>
<br>
<!-- checkboxlist复选框 -->
<s:checkboxlistname="list"list="{‘java‘,‘net‘,‘C‘,‘php‘,‘javascript‘}" value="{‘java‘,‘net‘}"></s:checkboxlist>
<br>
<!-- 如果为map集合 -->
<s:checkboxlist name="map"list="#{1:‘java‘,2:‘net‘,3:‘c#‘}" listKey=”key” listValue=”value” value="{1}">
</s:checkboxlist>
如果list中放入一个bean对象,如何生成复选框?
单选按钮:
<s:radio name="map" list="#{1:‘java‘,2:‘.net‘,3:‘c#‘}" listKey="key" listValue="value" value="{3}">
</s:radio>
下拉列表:
<s:select name="map" list="#{1:‘java‘,2:‘.net‘,3:‘c#‘}" listKey="key" listValue="value" value="{1}" >
</s:select>
22.防止表单重复提交
配置的struts.xml
<package name="itcast" namespace="/mytest" extends="struts-default">
<action name="handle" class="test.BdAction">
<interceptor-ref name="defaultStack"/>
<interceptor-ref name="token"/>
<result name="invalid.token">/tags.jsp</result>
<result name="success">/WEB-INF/page/message.jsp</result>
</action>
</package>
视图层的表单:
<s:form action="handle" namespace="/mytest" method="post">
name:<s:textfield name="name"></s:textfield><s:token></s:token>
<input type="submit" value="发送" />
</s:form>
标签:
原文地址:http://www.cnblogs.com/jiaqingshareing/p/5677226.html