strust2框架

1 概述

     struts2是一个实现MVC的框架

     struts2不是struts1的升级版本,在WebWork框架技术基础之上。

     struts2核心拦截器,struts2框架的核心功能都是依靠拦截器实现的。

2 MVC

     MVC模型视图控制器

     1M : javaBean 实现业务逻辑,数据访问,实体类,持久化类,工具类。

     2V : JSP 显示数据,JSTL+EL

     3C : Servlet 实现M与V之间的调度。(核心)

    

  2.1 一个控制器当中做三件事

         1接收用户请求,并获取请求数据。

         2调用M层的业务逻辑。实现业务功能。

         3页面导航到V层。

 

struts2框架就是对控制器进行了规范和统一。对一个控制器当中的三件事做了下个规范。

 

3 struts2的执行基本流图

strust2框架

3.1 开发人员只要完成三个部分的编写

     1struts.xml文件:struts2执行的配置文件。现在使用注解比较多

     2编写Action类。是使用struts2框架进行开发的核心类。(类似于Servlet)

     3导航,在struts2中有一个叫Result对象,这个对象就是导航器对象,只要在Action中返回一个String类型的值,就可以直接影响到一个Result对象。实现页面的导航。

3.2开发过程说明三件事件

     1参数都有哪些

     2调用哪个业务

     3导航页面

 

4 开发的第一个struts2工程

4.1 创建工程并导入struts2框架

strust2框架

4.2 配置struts2的核心过滤器

现在所有后缀为.action的请求都将提交给struts2框架处理。

strust2框架

4.3 编写Action类

     Action是Struts2框架的核心组件,开发时就主要编写Action类。

     而在Struts2框架中,对于Action类的要求非常简单。

     1无参

     2返回字符串类型

public class UserAction extends ActionSupport {

     public String login() throws Exception {

         return super.execute();

     }

}

4.4 注册Action类

在struts.xml文件中注册UserAction类的login方法。

<struts>

 <!-- 包,组织Action, name属性,extends=值固定,

 namespace="URL",以后访问当前包下的Action时,必须先访问包。 -->

 <package name="user" extends="struts-default" namespace="/user">

     <!-- action,核心组件 nameAction的访问名称,class是类,method类中的方法名称 -->

     <!-- ?当想访问这个Action时,URL=“/user/login.action” -->

     <action name="login" class="com.no8.actions.UserAction" method="login">

         <!-- 当前Action的导航,name是方法的返回值。 -->

         <result name="ok">/ok.jsp</result>

         <result name="nook">/error.jsp</result>

     </action>

 </package>

</struts>   

4.5 编写jsp页面

     <form action="${pageContext.request.contextPath }/user/login.action"

         method="post">

         用户名:<input name="username" value=""><br>

         密&nbsp;&nbsp;码:<input name="password" value=""><br>

         <input type="submit" value="登录">

     </form>

4.6 编写后台模型层

业务规则:只要用户名与密码一致就认为登录成功!

public class UserSerivce {

     public boolean isLogin(String username,String password){

         return username.equals(password);

     }

}

4.7 编写核心Action的功能

     一个Action就是一个控制器。

     1接收用户请求的参数

public class UserAction extends ActionSupport {

     private String username;

     private String password;

     //set/get方法

     public String login() throws Exception {

         System.out.println(username);

         System.out.println(password);

         return "nook";

     }

}

     2调用后台业务逻辑

     public String login() throws Exception {

         System.out.println(username);

         System.out.println(password);

         UserSerivce userSerivce= new UserSerivce();

         boolean bool = userSerivce.isLogin(username, password);

        

         return "nook";

     }

     3页面导航,返回注册时配置的导航器的name属性

     public String login() throws Exception {

         System.out.println(username);

         System.out.println(password);

         UserSerivce userSerivce = new UserSerivce();

         boolean bool = userSerivce.isLogin(username, password);

         if (bool) {

              return "ok";

         } else {

              return "nook";

         }

     }

 

5 练习:使用struts2+Hibernate框架实现注册功能

 

6 Struts2的配置文件

6.1 struts2框架的属性配置

     struts.properties文件是由程序员编写。

     default.properties文件是由框架提供,默认的struts2框架的属性配置。

 

default.properties文件:能看不能改

lib->struts2->strutscore->org.apache.struts->default.properties

strust2框架

struts.properties文件:程序员编写,用来修改默认的struts2框架的属性配置。

现在基本不在使用这个文件。因为在struts.xml文件中可以实现同样的功能

strust2框架

struts.xml文件:核心配置文件,可以修改Struts2框架的属性配置。

<struts>

     <!-- 用来修改default.properties文件中对于struts2框架的配置 -->

     <constant name="struts.i18n.encoding" value="utf-8" />

 

6.2 struts2框架的配置文件

     struts.xml文件:程序员编写的struts2的核心配置文件

     struts-default.xml文件:struts2框架提供的配置文件,这里配置了struts2框架的所有核心功能。

 

struts-default.xml文件:

lib->struts2->strutscore->struts-default.xml文件

在这文件中配置了“struts-default”的package

 

7 struts2的注解

@ParentPackage("struts-default")

@Namespace("/useranno")

public class UserAnnoAction {

     private Integer userId;

     @Action(value = "findbyid", results = {

              @Result(name = "ok", location = "/ok.jsp"),

              @Result(name = "nook", location = "/error.jsp") })

     public String findById() {

         UserSerivce userSerivce = new UserSerivce();

         Users user = userSerivce.findById(userId);

         if (user != null) {

              return "ok";

         } else {

              return "nook";

         }

     }

     //set&get方法

@ParentPackage("struts-default") 表示继承struts-default。固定值。

@Namespace("/useranno") 为类设置访问的URL

@Action(value = "findbyid",   value是为方法设置访问的URL

@Action(value = "findbyid", results = {

         @Result(name = "ok", location = "/ok.jsp"),

         @Result(name = "nook", location = "/error.jsp") })

results是个数组,表示多个导航器

@Result(name = "ok", location = "/ok.jsp")

一个导航器注解,name表示的方法返回值。location表示导航的路径

 

7.1 Result导航器的类型

7.1.1 在struts-default.xml文件中配置的导航类型

strust2框架

7.1.2 type="dispatcher" 转发,默认值。

7.1.3 type="redirect" 重定向

7.1.4 type="redirectAction" 重定向到下一个Action

7.1.5 type="chain" 转发到下一个Action

7.2 在chain和redirectAction时的处理

     在chain和redriectAction进行下一个Action的导航时,分两种情况处理

     1同一个包(package的其他的Action

         只要指定Action的name属性

     2不同包(@Namespace的Action

         要使用参数设置的方式:

         1namespace :不同包的name属性

         2actionName : 不同包的Action的name属性

 

先看XML文件的方式:

strust2框架

基于注解方式的导航类型的设置

同一个包的其他的Action

@ParentPackage("struts-default")

@Namespace("/goods")

public class GoodsAction {

     @Action(value = "findall", results = {

              @Result(name = "ok", location = "/index.jsp")

         }

     )

     public String findAll() {

         System.out.println("findall()");

         return "ok";

     }

     @Action(value="save" , results={

              @Result(name="ok",type="redirectAction",location="findall")

     })

     public String save() {

         System.out.println("save");

         return "ok";

     }

}

不同包中的Action

@ParentPackage("struts-default")

@Namespace("/user")

public class UserAction {

     @Action(value="login",results={

              @Result(name="ok",type="redirectAction",

                       params={"namespace","/goods","actionName","findall"}

              )

     })

     public String login(){

         System.out.println("login");

         return "ok";

     }

}

 

8 接收用户请求参数

     在struts2框架中一共提供三种方式实现接收用户请求的参数。

8.1 属性驱动方式

     直接在Action类中设置属性,保证属性的名称与请求的参数名称一致。就可以实现自动将参数保存到属性中。

public class UserAction extends ActionSupport {

     private String username;

     private String password;

     private String userAddress;

     private String userPhone;

<form>

     <input name="username">

</form>

8.2 使用域模型方式

     1创建域模型对象

public class Goods implements java.io.Serializable {

     // Fields

     private Integer goodsId;

     private GoodsType goodsType;

     private String goodsName;

     private Float goodsPrice;

     private Integer goodsNum;

     private String goodsImg;

     private Timestamp goodsDate;

     2在Action类中使用域模型创建接收请求参数的实例并实例化

@ParentPackage("struts-default")

@Namespace("/goods")

public class GoodsAction {

     // 域模型对象

     private Integer id ;

     private Goods goods = new Goods();

     private GoodsType goodsType = new GoodsType();

     //set&get方法

     3在jsp页面上的表单上格式

     格式:实例名.属性名

    <form action="goods/save.action" method="post">

          <input type="hidden" name="id">

         goodsname:<input type="text" name="goods.goodsName"><br>

         goodsprice:<input type="text" name="goods.goodsPrice"><br>

         goodsnum:<input type="text" name="goods.goodsNum"><br>

         goodstype:<select name="goodsType.typeId">

             <option value="1">家用电器</option>

             <option value="2">数码产品</option>

         </select>

         <input type="submit" value="save">

    </form>

8.3 使用模型驱动方式

1 在Action类中实现接口ModelDriven<T>。

@ParentPackage("struts-default")

@Namespace("/user")

public class UserAction implements ModelDriven<Users> {

2 在Action类中重写getModel方法并返回模型对象

@ParentPackage("struts-default")

@Namespace("/user")

public class UserAction implements ModelDriven<Users> {

     private Users user = new Users();

     @Override

     public Users getModel() {

         return user;

     }

3 在JSP页面上不会再影响name="值" , 值 必须与模型对象的属性一致。

<form action="${pageContext.request.contextPath }/user/reg.action" method="post">

         用户名:<input name="userName" value=""><br>

         密码:<input name="userPass" value=""><br>

         地址:<input name="userAddress" value=""><br>

         电话:<input name="userPhone" value=""><br>

         <input type="submit" value="注册">

</form>

 

9 访问ServletAPI

     在WEB开发时,使用Servlet的类。HttpServletRequest,HttpSession

     但是struts2框架中,将Action与SerlvetAPI进行了解耦合的设计。

9.1 struts2框架中提供了两种访问serlvetAPI 的方法

     1解耦合方式

         就是在Action中不使用ServletAPI,但是实现相同的功能。

     2耦合方式

         就是在Action中直接使用ServletAPI。

9.2 与Servlet解耦合方式

     在struts2框架中封装了三个Map集合来代替HttpSession,HttpServletRequest和ServletContext的使用

     但是这三个Map集合只代替了其中保存数据的功能。保存数据:setAttribute(Key,value)

     这三个Map集合中由struts2框架提供的。要想获得这个三个Map要使用ActionContext类。

9.2.1 ActionContext类

     Action运行的上下文对象,就是环境对象。可以从个对象的方法中获得三个Map集合对象

     1 获得ActionContext类的实例

         通过ActionContext类的静态方法getContext方法获得的实例

         ActionContextactionContext = ActionContext.getContext();

     2 获得代替HttpServletRequest(请求)的Map集合

         Map<String,Object>reqMap = (Map<String, Object>) actionContext.get("request");

     3 获得代替HttpSession(会话)的Map集合

          Map<String,Object> sessMap= actionContext.getSession();

     4 获得代替ServletContext(应用程序)的Map集合

         Map<String,Object>appMap = actionContext.getApplication();

9.2.2 Struts2提供了三个接口的方式获得三个Map集合对象

     1 org.apache.struts2.interceptor.ApplicationAware接口

          public void setApplication(Map<String,Object> application)

     2 org.apache.struts2.interceptor.RequestAware接口

         publicvoid setRequest(Map<String, Object> request)

     3 org.apache.struts2.interceptor.SessionAware接口

         publicvoid setSession(Map<String, Object> session)

@ParentPackage("struts-default")

@Namespace("/interface")

public class InterfaceAction implements SessionAware {

     private Map<String,Object> sessMap ;

     @Override

     public void setSession(Map<String, Object> arg0) {

         this.sessMap = arg0;

     }

     @Action(value="add",results={

              @Result(name="ok",location="/ok.jsp",type="redirect")

     })

     public String add(){

         this.sessMap.put("user", "peterSun");

         return "ok";

     }

}

 

9.3 与Servlet耦合的方式

     耦合的方式就是在Action中直接访问ServletAPI。直接使用Servlet的对象。

9.3.1 ServletActionContext类

     通过这个类的静态方法来获得真正的ServlerAPI中的各个对象

strust2框架

9.3.2 struts2提供了二个接口可以获得ServletAPI

     1 org.apache.struts2.interceptor.ServletRequestAware接口

         publicvoid setServletRequest(HttpServletRequest request)

     2 org.apache.struts2.util.ServletContextAware接口

         publicvoid setServletContext(ServletContext context)

 

@ParentPackage("struts-default")

@Namespace("/interface")

public class InterfaceAction implements SessionAware,ServletRequestAware {

     private Map<String,Object> sessMap;

     private HttpServletRequest request;

     @Override

     public void setServletRequest(HttpServletRequest arg0) {

         request = arg0;

     }

     @Override

     public void setSession(Map<String, Object> arg0) {

         this.sessMap = arg0;

     }

     @Action(value="add",results={

              @Result(name="ok",location="/ok.jsp",type="redirect")

     })

     public String add(){

         this.sessMap.put("user", "peterSun");

         ServletContext app = ServletActionContext.getServletContext();

         app.setAttribute("user", "Sun");

         return "ok";

     }

}

 

10 补遗

10.1 Action的结构

     在struts2的Action上没有规范。

     类上没有规范(必须继承,必须实现接口)

     类的方法有规范:

     1public

     2public String

     3public String xxx()

 

     在struts2中还是有关于Action的结构。

     一般开发时Action类会继承ActionSupport

     ActionSupport类有一个接口叫Action接口

     Action接口是所有Action类的规范。

 

Action接口中只有一个抽象方法:execute()

     这个方法也是默认的方法。

<struts>

     <package name="demo" extends="struts-default" namespace="/demo">

         <action name="demo1" class="com.no8.action.TestAction" />

     </package>

</struts>

这种情况下默认调用execute方法

 

@Action(value="demo1")

public class TestAction extends ActionSupport {

}

这种情况下默认调用execute方法

 

Action接口中有5个常量。

     这5个常量也是开发中使用的最频繁的5个常量。

     其中有一个叫success的常量。字符串值 “success”默认值。导航的默认值。

@Action(value="demo1",results={

         @Result(location="/index.jsp")

})

public class TestAction extends ActionSupport {

     @Override

     public String execute() throws Exception {

         return ActionSupport.SUCCESS;

     }

}

 

11 手动校验

11.1 在Action类中重写validate()和编写validateXxx()方法

11.1.1 重写validate()-ActionSupport类

     @Override

     public void validate() {

         System.out.println("validate!$%^&^%$#%^$");

     }

     validate方法是一个校验规则方法。

     在struts2框架中为手动校验做了一系列的规范。有自己的调用规则。

     validate方法,这个方法就是struts2框架进行校验的方法,通过给Action为中的每一个方法的校验规则方法。

     validate方法的作用,在struts2框架调用Action方法之前会先调用validate方法,通过validate方法的执行结果判断校验时否成功。如果成功就继续调用Acton的业务方法。否则进行页面导航,不再调用Action的业务方法。

     在struts2中使用校验框架时一般都要继承ActionSupport类。

     特点:所有业务方法调用之前统一调用validate方法。

     不Action中不同的业务方法应该有不同的校验规则。不能只用使用一个validate方法。

11.1.2编写validateXxx()

     因为validate方法是一个通用的方法,所有业务都会调用的方法,在不同业务时不能体现不同的数据校验规则。

     针对每一个业务方法都有不同的校验规则时使用validateXxx方法。

     Xxx--表示的是业务方法的名称。名称就是对应业务方法的名称。

     public void validateReg() {//这个校验方法只针对reg业务

         System.out.println("validateReg!$%^&^%$#%^$");

     }

     public void validateLogin() {

         System.out.println("validateLogin!$%^&^%$#%^$");

     }

11.2 在方法中使用addFieldError()方法保存校验错误信息

     validate方法是一个没有返回值的方法。public void validate()

     在struts2框架中有一个错误容器。在调用完validate方法之后,struts2框架会判断错误容器是否为空(is empty)。

     如果容器为emtpy则表示校验成功,可以调用业务方法。

     所以我们在validate方法中如果发现校验有错误,我们只要将错误信息添加到错误容器。

     addFieldError()方法就是将错误信息添加到错误容器。

     这个方法ActionSupport已经写好了。我们只要调用就可以。

     public void validateReg() {

         System.out.println("validateReg!$%^&^%$#%^$");

         if(users.getUsername()==null || "".equals(users.getUsername())){

               //将错误信息添加到错误容器

              this.addFieldError("username", "用户名不能为空!");

         }

         if(users.getPassword()==null || "".equals(users.getPassword())){

              this.addFieldError("password", "密码不能为空!");

         }else if (users.getPassword().length()<6){

              this.addFieldError("password", "密码长度不能小于6位!");

         }

     }

11.3 Action的配置信息中要加入name=“input”视图,确定错误显示页面

     validate方法可以将错误信息添加到错误容器。struts2框架调用完成validate方法会自动验证错误容器是否为空。

     如果为空说明校验成功,调用业务方法。

     如果不为空说明校验失败,自动页面导航。自动按业务方法的input的导航器进行导航

     为业务方法指定一个name="input"的视图。

11.4 在jsp页面中使用fielderror标签输出错误消息

     fielderror标签是struts2框架提供的一组标签库中一个专门用于显示校验错误信息的标签

<%@ taglib prefix="s" uri="/struts-tags" %>

<s:fielderror/>显示所有错误信息

<s:fielderror fieldName="username"/>显示一个错误信息

11.4.1 异常提示

strust2框架

问:<s:fielderror/>这个标签是谁的?struts2框架的。所以应该于struts2框架对这个标签进行处理。

所以reg.jsp页面是不是应该让struts2框架也进行加载。

  <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>

 

12 Struts2框架提供校验框架

12.1 编写校验规则文件

12.1.1 同Action类在一个目录下

strust2框架

如果我们要为UserAction类中的业务方法编写校验规则文件

这个文件的位置必须放在com.no8.action下面。

12.1.2 校验规则的文件名称

     1UserAction-validation.xml

          通用于UserAction类中所有方法的校验规则文件

     2UserAction-reg-validation.xml(推荐)

          用于UserAction类中reg业务方法的校验规则文件

12.1.3 校验规则文件的格式

     在工程的struts2的jar包中找到规则的规范dtd文件

     xwork-core-2.1.jar-> xwork-validator-1.0.3.dtd

<!DOCTYPE validators PUBLIC

         "-//OpenSymphony Group//XWork Validator 1.0.3//EN"

         "http://www.opensymphony.com/xwork/xwork-validator-1.0.3.dtd">

 

<validators>

     <field name="">

         <field-validator type="">

              <message></message>

         </field-validator>

     </field>

</validators>

12.1.4 每一个节点的作用

     1<field name=""> 用来指定需要校验的属性字段

     2<field-validator type="?"> 用来指定校验规则的内置校验器

     3 <message></message>用来指定错误信息

<validators>

     <field name="repassword">

         <field-validator type="requiredstring">

              <message>确认密码不能为空!</message>

         </field-validator>

     </field>

     <field name="users.username">

         <field-validator type="requiredstring">

              <message>用户名不能为空!</message>

         </field-validator>

     </field>

</validators>

<form action="${pageContext.request.contextPath }/user/reg.action" method="post">

    用户名:<input type="text" name="users.username" value="" >

               <s:fielderror fieldName="users.username" theme="simple"/><br>

    密码:<input type="password" name="users.password" value="">

               <s:fielderror fieldName="password"/><br>

    确认密码:<input type="password" name="repassword" value="">

               <s:fielderror fieldName="repassword"/><br>

    <input type="submit" value="注册">

</form>

 

12.2 常用的内置校验器

strust2框架

12.2.1 stringlength:字符串长度

     1maxLength : 最大长度

     2minLength : 最小长度

     3trim : 去空格

     <field name="repassword">

         <field-validator type="requiredstring">

              <message>确认密码不能为空!</message>

         </field-validator>

         <field-validator type="stringlength">

              <param name="minLength">4</param>

              <param name="maxLength">8</param>

              <param name="trim">true</param>

              <message>密码长度大于${minLength}位小于${maxLength}位</message>

         </field-validator>

     </field>

12.2.2 int : 类型校验器

12.2.3 email : 邮箱校验器

12.2.4 regex : 正则表达式校验器

12.2.5 fieldexpression 字段比较器校验器

<validators>

     <field name="repassword">

         <field-validator type="requiredstring">

              <message>确认密码不能为空!</message>

         </field-validator>

         <field-validator type="stringlength">

              <param name="minLength">4</param>

              <param name="maxLength">8</param>

              <param name="trim">true</param>

              <message>密码长度大于${minLength}位小于${maxLength}位</message>

         </field-validator>

         <field-validator type="fieldexpression">

              <param name="expression">repassword.equals(users.password)</param>

              <message>两次密码不一致!</message>

         </field-validator>

     </field>

     <field name="users.username">

         <field-validator type="requiredstring">

              <message>用户名不能为空!</message>

         </field-validator>

     </field>

     <field name="users.email">

         <field-validator type="email">

              <message>邮箱格式不正确!</message>

         </field-validator>

     </field>

     <field name="users.phone">

         <field-validator type="regex">

              <param name="expression">\d{11}</param>

              <message>手机格式不正确!</message>

         </field-validator>

     </field>

</validators>

 

13 练习:实现商品上传功能

     要求:1 使用struts2的校验实现服务器端验证

           2 JSP页面使用日历控件输入日期

           3 商品应该有的属性:

                   名称,价格,出厂日期,到期时间(大于出厂日期),

                   数量(整数),产品地,二维码(只能四位数字)

 

14 拦截器(了解)

14.1 token拦截器:

     作用:防止表单重复提交

     token令牌。每次在表单提交时,带一个编号过来(令牌),如果再次请求时编号没有发生变化,服务器就认为是重复提交。

14.2 使用步骤

     1在jsp页面的表单上使用struts2的标签加入token令牌。web.xml文件

   <form action="" method="post">

   <s:token/>

  

   </form>

     2在注册Aciton时指定引用拦截器

     <package extends="struts-default" name="goods" namespace="/goods">

         <action name="save" class="com.no8.action.GoodsAction" method="save">

              <result>/ok.jsp</result>

              <interceptor-ref name="token"/><!-- 引用token拦截器 -->

              <!-- 当你有指定拦截器时,默认就不启作用,手动指定引用默认拦截器 -->

              <interceptor-ref name="defaultStack"/>

         </action>

     </package>

     3当表单重复提交时,会自动按invalid.token导航跳转

         <action name="save" class="com.no8.action.GoodsAction" method="save">

              <result>/ok.jsp</result>

              <result name="invalid.token">/token.jsp</result>

 

14.3 execAndWait拦截器

     1在Aciton注册上加入execAndWait拦截器

     2为execAndWait拦截器配置导航name="wait"

         <action name="save" class="com.no8.action.GoodsAction" method="save">

              <result>/ok.jsp</result>

              <result name="wait">/wait.jsp</result>

              <!-- 当你有指定拦截器时,默认就不启作用,手动指定引用默认拦截器 -->

              <interceptor-ref name="defaultStack" />

              <interceptor-ref name="execAndWait" />

         </action>

     3在jsp页面上使用struts2标签实现自动跳转

<meta http-equiv="refresh" content="5;url=<s:url includeParams="all"/>">

请求已发送,请耐心等着。5秒之后自动跳转,

如果没有跳转请点<A href="<s:url includeParams="all"/>">这里</A><br>

 

 

15 自定义拦截器

15.1 步骤1:编写自定义的拦截器类

     1实现Interceptor接口

     2继承AbstractInterceptor类(使用)

public class StringInterceptor extends AbstractInterceptor {

     @Override

     public String intercept(ActionInvocation invocation) throws Exception {

         return "ok";

     }

}

intercept方法返回值类型是String,这个地方返回一个字符串也表示按result导航进行跳转,与Action类中的方法的返回值的作用是一样的。

return invocation.invoke(); 返回invocation.invoke()时调用后面的内容,理解时当成Filter中的放行就可以了。

15.2 步骤2:在struts2框架中注册这个拦截器

     <package name="my-struts-default" extends="struts-default"

         abstract="true">

         <interceptors>

              <interceptor name="stringInterceptor"

                         class="com.no8.interceptor.StringInterceptor" />

              <interceptor-stack name="stringStack">

                   <interceptor-ref name="defaultStack" />

                   <interceptor-ref name="stringInterceptor" />

              </interceptor-stack>

         </interceptors>

         <default-interceptor-ref name="stringStack" />

     </package>

15.3 步骤3:在需要使用的Action中引用这个拦截器

     <package extends="my-struts-default" name="goods" namespace="/goods">

         <action name="save" class="com.no8.action.GoodsAction" method="save">

              <result>/ok.jsp</result>

              <result name="StringInterceptor">/str.jsp</result>

              <interceptor-ref name="defaultStack" />

              <interceptor-ref name="stringInterceptor" />

         </action>

     </package>

15.4 实现对敏感字的过滤功能

public class StringInterceptor extends AbstractInterceptor {

     @Override

     public String intercept(ActionInvocation invocation) throws Exception {

         System.out.println("StringInterceptor");

         Object obj = invocation.getAction();

         if(obj instanceof GoodsAction){

              GoodsAction goodsAction = (GoodsAction) obj;

              String goodsName = goodsAction.getGoodsName();

              goodsAction.setGoodsName(goodsName.replace("夜总会", "***"));

         }

         return invocation.invoke();

     }

}

15.5 基于注解的方式

@ParentPackage("my-struts-default")

@Namespace("/goods")

public class GoodsAction extends ActionSupport {

     @Action(value="save" ,results={

              @Result(name=SUCCESS ,location="/ok.jsp")

         }, interceptorRefs={

              @InterceptorRef("defaultStack"),

              @InterceptorRef("stringInterceptor")

         }

     )

     public String save() throws Exception {

         System.out.println(goodsName);       

         return super.execute();

     }

     private String goodsName;

 

16 struts2整合JSON

     做为一个现在使用的很多的JSON。已经导入到struts2框架jar文件中。

16.1 Struts2中对json的支持

strust2框架

16.2 查看一个支持的插件文件

struts2-json-plugin-2.2.1.jar文件

strust2框架

strust2框架

16.3 在一个Action类中使用JSON

@ParentPackage("json-default")

@Namespace("/goods")

public class GoodsAction extends ActionSupport {

     private String jsonText; //用来存放返回的json文本的

     @Action(value="save" ,results={

              @Result(name=SUCCESS , type="json" , params={"root","jsonText"})

         }, interceptorRefs={

              @InterceptorRef("defaultStack"),

              @InterceptorRef("json")

         }

     )

     public String save() throws Exception {

         System.out.println(goodsName);  

         JSONObject jsonObject = new JSONObject();

         jsonObject.put("username", "peter");

         jsonObject.put("isEmpty", true);

         this.jsonText = jsonObject.toString();

         return SUCCESS;

     }

     <script type="text/javascript" src="js/jquery-1.11.1.js"></script>

     <script type="text/javascript">

         $(function(){

              $.ajax({

                   url:"goods/save.action",

                   type: "post",

                   data: {"goodsName":"pt"},

                   dataType:"json",

                   success:function(data){

                       alert(data);

                       var jsonobj = eval("("+data+")");

                       alert(jsonobj.isEmpty);

                       if(jsonobj.isEmpty){

                            alert("用户名可用!");

                       }else{

                            alert("用户名不可用!");

                       }

                   }

              });

         });

     </script>

 

17 练习:实现struts2整合JSON的异步刷新

17.1 数据库模型

strust2框架

17.2 创建工程并导入struts2和Hibernate框架

17.3 返回映射,和Filter,和Listener

17.4 编写业务方法,提供查询所有商品和按类型查询商品功能

     1GoodsDAO.java

     public List findAll() {

         log.debug("finding all Goods instances");

         try {

              String queryString = "from Goods order by goodsprice desc";

              Query queryObject = getSession().createQuery(queryString);

              return queryObject.list();

         } catch (RuntimeException re) {

              log.error("find all failed", re);

              throw re;

         }

     }

     2GoodsService.java

public class GoodsService {

     private GoodsDAO goodsDAO = new GoodsDAO();

     private TypesDAO typesDAO = new TypesDAO();

     public List<Goods> findAll(){

         return this.goodsDAO.findAll();

     }

     public List<Goods> findByTypeId(Integer typeId){

         return this.typesDAO.findById(typeId).getGoodses();

     }

}

17.5 编写Action类返回json文本

@ParentPackage("json-default")

@Namespace("/goodsjson")

public class GoodsByJsonAction extends ActionSupport {

     @Action(value="find",results={

              @Result(type="json",params={"root","jsontext"})

     },interceptorRefs={

              @InterceptorRef("defaultStack"),

              @InterceptorRef("json")

     }

     )

     public String find(){

         GoodsService goodsService = new GoodsService();

         List<Goods> goodsList = null;

         if(goodsTypeId == -1){

              goodsList = goodsService.findAll();

         }else{

              goodsList = goodsService.findByTypeId(goodsTypeId);

         }

         JsonConfig jsonConfig = new JsonConfig();

         jsonConfig.setExcludes(new String[]{"goodses"});

         JSONArray jsonarr = JSONArray.fromObject(goodsList,jsonConfig);

         this.jsontext = jsonarr.toString();

         System.out.println(jsontext);

         return SUCCESS;

     }

     private String jsontext;

     private int goodsTypeId;

     public int getGoodsTypeId() {

         return goodsTypeId;

     }

     public void setGoodsTypeId(int goodsTypeId) {

         this.goodsTypeId = goodsTypeId;

     }

     public String getJsontext() {

         return jsontext;

     }

     public void setJsontext(String jsontext) {

         this.jsontext = jsontext;

     }

}

 

 

注意:当使用json进行Java对象转换时,要做两件事

     1破坏双向映射

     2关闭lazy加载

17.6 编写jsp页面上的ajax-使用jQuery

     <script type="text/javascript" src="js/jquery-1.11.1.js"></script>

     <script type="text/javascript">

         $(function(){

              $("#goodsType").change(function(){

                   $.ajax({

                       url:"goodsjson/find.action",

                       type: "post",

                       data: {"goodsTypeId":$("#goodsType").val()},

                       dataType:"json",

                       success:function(data){

                            alert(data);

                            var jsonarr = eval("("+data+")");

                            $("#databody").text("");

                            for(var i=0;i<jsonarr.length;i++){

                                 var trobj = $("<tr>");

                                 $("#databody").append(trobj);

                                 var goodsid_tdobj = $("<td>");

                                 goodsid_tdobj.css("color","red").css("font-size","72px");

                                 goodsid_tdobj.text(jsonarr[i].goodsid);

                                 trobj.append(goodsid_tdobj);

                                 var goodsname_tdobj= $("<td>");

                                 goodsname_tdobj.text(jsonarr[i].goodsname);

                                 trobj.append(goodsname_tdobj);

                                 var types_tdobj= $("<td>");

                                 types_tdobj.text(jsonarr[i].types.typename);

                                 trobj.append(types_tdobj);

                            }

                       }

                   });

              });

             

              $("#goodsType").change();

         });

     </script>

    <select id="goodsType" name="goodsType" >

              <option value="-1">所有类型</option>

         <c:forEach items="${applicationScope.typeList }" var="type">

              <option value="${type.typeId}">${type.typename}</option>

         </c:forEach>

    </select>

     <table>

         <thead>

              <tr>

              <th>商品编号</th>

              <th>商品名称</th>

              <th>类型名称</th>

              </tr>

         </thead>

         <tbody id="databody">

         </tbody>

     </table>

 

18 Struts2文件上传

18.1 基本流程

     1编写JSP页面

    <form action="upload/up.action" method="post" enctype="multipart/form-data">

         <input type="file" name="goodsImg"><br>

         <input type="submit" value="上传">

    </form>

     2在接收的Action类中使用File类型的变量接收

@ParentPackage("struts-default")

@Namespace("/upload")

public class UpLoadAction extends ActionSupport {

     private File goodsImg;

     //set&get

 

     3在文件上传的业务方法中使用流操作实现文件复制

     @Action(value = "up", results = { @Result(location = "/index.jsp") })

     public String up() {

         // IO操作

         try {

              InputStream is;

              is = new FileInputStream(goodsImg);

              OutputStream os;

              os = new FileOutputStream("d:/a.jpg");

              byte[] bytes = new byte[1024];

              int len = -1;

              while ((len = is.read(bytes)) != -1) {

                   os.write(bytes, 0, len);

              }

              is.close();

              os.close();

         } catch (Exception e) {

              e.printStackTrace();

         }

         return SUCCESS;

     }

18.2 获取上传时文件的更多信息

     1String xxxFileName   获得文件的真实名称

     2String xxxContentType    获得文件的文件类型,mime协议

@ParentPackage("struts-default")

@Namespace("/upload")

public class UpLoadAction extends ActionSupport {

     private File goodsImg;

     private String goodsImgFileName;

     private String goodsImgContentType;

     //set&get方法

 

18.3 限制文件上传的类型与大小

Struts2支持在fileUpload拦截器上设置参数来进行限制。

     1allowedTypes:指定允许上传的文件的类型,如果存在多种类型,以逗号隔开。

         注意:这里添的不是文件的扩展名,而是对应的ContentType  .jpg --- image/gif

     2maximumSize:指定允许上传的文件的最大字节数。

     3allowedExtensions:指定允许上传的文件的扩展名。 .jpg

不满足参数条件,则跳转input的<result>

     @Action(value = "up", results = { @Result(location = "/index.jsp"),

              @Result(name = INPUT, location = "/input.jsp") },

         interceptorRefs = {

              @InterceptorRef(value = "fileUpload", params = {

                       "allowedExtensions", ".jpg" }),

              @InterceptorRef(value = "defaultStack") })

     public String up() {

     }

18.4 一次性上传多个文件

    <form action="upload/up.action" method="post" enctype="multipart/form-data">

         <input type="file" name="goodsImg"><br>

         <input type="file" name="goodsImg"><br>

         <input type="submit" value="上传">

    </form>

@ParentPackage("struts-default")

@Namespace("/upload")

public class UpLoadAction extends ActionSupport {

     private List<File> goodsImg;

     private List<String> goodsImgFileName;

     private List<String> goodsImgContentType;

@ParentPackage("struts-default")

@Namespace("/upload")

public class UpLoadAction extends ActionSupport {

     private File[] goodsImg;

     private String[] goodsImgFileName;

     private String[] goodsImgContentType;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

相关文章: