j2ee开发之struts2框架学习笔记

Struts2框架技术重点笔记

1.Struts2 是在webwork基础上发展而来。

2.Struts2 不依赖struts APIservlet 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.userActionaction的名称,来自于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.如果没有指定resultname,默认返回success

11.在一个action中处理请求时将页面重定向到另外一个action?

<action name="redirectAction">

<result type="redirectAction">

!-- action名称 -->

<param name="actionName">s1</param>

<!-- 命名空间名字 -->

<param name="namespace">/school</param>

</result>

</action>

注意将resulttype类型设置为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

imageimageFileName属性全部定义成数组处理

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>

带着热忱学技术,带着耐心做技术,带着分享去交流,带着微笑探我们的程序人生!
原文地址:https://www.cnblogs.com/jiaqingshareing/p/5677226.html