struts2

1.     struts2的简介

1.1. 什么是struts2

Struts2 是一个非常优秀的MVC框架,基于Model2 设计模型,由传统Struts1和WebWork两个经典框架发展而来.

Model -View-Controller: 前台页面与后台代码分离

1.2. struts2核心功能

允许对象作为Action。Action的execute 方法不再与Servlet API耦合,更易测试支持更多视图技术(JSP、FreeMarker、Velocity)基于Spring AOP思想的拦截器机制,更易扩展更强大、更易用输入校验功能整合Ajax支持.

 

2.     struts2的入门案例

2.1. struts2的目录结构

 

2.2. struts2的入门案例

1.     导入jar包

解压struts2的包下的apps/struts-blank.war中的jar包就是struts2使用到的基础包

2.        在web.xml中配置核心控制器

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">

  <display-name>struts2_day01_demo02_start</display-name>

  <welcome-file-list>

    <welcome-file>index.html</welcome-file>

  </welcome-file-list>

   <!-- 配置struts2的核心控制器 -->

   <filter>

      <filter-name>strutsPrepareAndExecuteFilter</filter-name>

      <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>

   </filter>

  

   <filter-mapping>

       <filter-name>strutsPrepareAndExecuteFilter</filter-name>

       <url-pattern>/*</url-pattern>

   </filter-mapping>

 

</web-app>

 

 

3.        核心配置文件(struts.xml)

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "struts-2.3.dtd" >

<struts>

    <!--

       name:可以为任意值,方便其他package继承

     -->

    <package name="first">

      

       <!-- 配置请求与处理类的关系 -->

       <action name="helloworld" class="com.ys.action.HelloAction" method="sayHello"></action>

    </package>

  

</struts>

 

 

 

4.        编写对应的处理类并配置在核心配置文件中

package com.ys.action;

 

publicclass HelloAction {

   

    publicvoid sayHello(){

        System.out.println("-----------sayHello--------");

    }

}

 

 

 

2.3. struts2的处理过程

 

 

3.     struts2的核心配置文件

3.1. 常用的常量

struts2核心包中/org/apache/struts2/default.properties找对应的常量

i18n:internationalization

1. <constantname="struts.i18n.encoding" value="UTF-8"/>

  指定默认编码集,作用于HttpServletRequest的setCharacterEncoding方法 和freemarker 、velocity的输出

2. <constantname="struts.action.extension" value="action"/>

该属性指定需要Struts 2处理的请求后缀,该属性的默认值是action,即所有匹配*.action的请求都由Struts2处理。如果用户需要指定多个请求后缀,则多个后缀之间以英文逗号(,)隔开

3. <constantname="struts.devMode" value="true" />

 开发模式下使用,这样可以打印出更详细的错误信息

4. <constantname="struts.serve.static.browserCache" value="false"/>

   是否缓存静态资源

5. <constantname="struts.objectFactory" value="spring" />

  该属性设置Struts 2是否支持动态方法调用,该属性的默认值是true。如果需要关闭动态方法调用,则可设置该属性为 false

 

3.2. 指定多个struts配置文件

在大部分应用里,随着应用规模的增加,系统中Action的数量也会大量增加,导致struts.xml配置文件变得非常臃肿。为了避免struts.xml文件过于庞大、臃肿,提高struts.xml文件的可读性,我们可以将一个struts.xml配置文件分解成多个配置文件,然后在struts.xml文件中包含其他配置文件。下面的struts.xml通过<include>元素指定多个配置文件:

 

<struts>

         <includefile="struts-part1.xml"/>

         <includefile="struts-part2.xml"/>

</struts>

 

通过这种方式,我们就可以将Struts 2的Action按模块添加在多个配置文件中。

 

3.3. 配置文件的代码

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "struts-2.3.dtd" >

<struts>

<!-- 配置对应的常量 -->

<!-- 配置编码格式 -->

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

<!-- 配置请求的后缀名 -->

<constant name="struts.action.extension" value="action,do,"/>

<!-- 开启开发者模式 -->

<constant name="struts.devMode" value="true"/>

<!-- 缓存静态资源 -->

<constant name="struts.serve.static.browserCache" value="true"/>

 

 <!-- name:当前package的名称,用户其他package继承

      namespace:相当于给业务请求分包,请求具体的方法是需要把命名空间加上

      extends:继承struts-defaultstruts-defaultstruts2内置的很多拦截器来帮助我们实现功能(文件上传,国际化)

  -->

 <package name="second" namespace="test" extends="struts-default">

    <!-- 配置请求路径与处理类的映射

      name:请求路径

      class:请求处理类

      method:请求处理方法,如果不配置method,默认执行的方法为execute

    -->

    <action name="test" class="com.ys.action.TestAction"></action>

   

    <action name="jumpIndex" class="com.ys.action.TestAction" method="jumpPage">

        <!-- 根据处理方法的返回值,跳转到指定的页面 -->

    </action>

    

    <action name="toRe" class="com.ys.action.TestAction" method="testRe">

    </action>

   

 </package>

 

</struts>

 

 

 

 

4.     访问Action

Action接口

struts2 的Action可以是普通类

为了让用户开发的Action更加规范struts2提供了一个Action接口

ActionSupport基类

Struts2为Action接口提供了一个实现类ActionSupport,定义了表单域校验、错误信息设置和获得国际化信息相关一些方法

4.1. 编写Action类的方案

1.用户编写Action 可以是普通类

2.用户编写Action 可以实现Action接口

可以使用结果集常量字符串

3.用户编写Action 可以继承ActionSupport基类

对请求参数进行校验,设置错误信息,读取国际化信息

execute方法编写注意细节,public 修饰符,String 返回值,无参数

 

4.2. 配置action映射的方式

4.2.1.  通过method属性指定Action执行方法

1.     没有指定method属性,默认执行execute方法

2.     通过method属性,指定调用Action相应方法处理请求

4.2.2.  使用通配符配置Action

1.在配置<action...>元素时,允许在指定name属性时,使用模式字符串(用"*"代表一个或多个任意字符)

2.在class、method属性及<result>子元素中通过 {N} 形式代表前面地N个* 匹配子串

    <!-- 配置MultipartAction的请求映射关系

      *匹配任意长度字符,{N}取的是实际上第几个*的值作为填充内容

     -->

   <!--  <action name="*" class="com.ys.action.MultipartAction" method="{1}">

       <result name="{1}">/{1}.jsp</result>

    </action> -->

    <!-- 请求的路径为test_index -->

    <action name="*_*" class="com.ys.action.MultipartAction" method="{1}">

       <result name="success">/{2}.jsp</result>

    </action>

 

4.2.3.  使用Action的动态方法调用

通过url动态指定调用Action哪个方法而无需配置<action>的method属性

通过 !方法名指定调用Action哪个方法

注意事项:使用格式需要在struts.xml中设置对应的常量

<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>

 

5.     结果处理Result

5.1. 理解结果处理

Action处理完用户请求后,将返回一个普通字符串整个普通字符串就是一个逻辑视图名

Struts2 根据逻辑视图名,决定响应哪个结果,Struts2处理结果使用<result>元素配置

局部结果:将<result>作为<action>子元素配置

全局结果:将<result>作为<global-results>元素的子元素配置

配置<result>元素通常需要指定两个属性

name 该属性指定配置逻辑视图名

type 该属性指定结果类型

5.2. 全局结果

当多个action中都使用到了相同result,这时我们应该把result定义为全局结果

<package ....>

         <global-results>

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

         </global-results>

</package>

 

5.3. 示例代码:

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

       <!-- 配置全局的结果映射 -->

       <global-results>

            <result name="global">/index.jsp</result>

       </global-results>

   

      <!-- 配置请求urlaction处理方法的映射 -->

      <action name="login" class="com.ys.action.LoginAction" method="login">

         <result name="local">/login.jsp</result>

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

      </action>

      

    </package>

 

 

注意事项:

局部的会覆盖全局(局部优先于全局)

Struts1中应用范围内action的实例 action是单实例(执行时,现在缓存中查找实例,有用,没有创建新的实例)

Struts2中 应用范围内action的实例,每个请求都会创建一个action实例

Servlet属于单实例多线程的应用,实例只在初始化时被加载

多实例比单实例的优点,不会产生并发问题,但执行速度不如单实例

5.4. 结果类型

 <result-types>

            <result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>

            <result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/>

            <result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/>

            <result-type name="httpheader" class="org.apache.struts2.dispatcher.HttpHeaderResult"/>

            <result-type name="redirect" class="org.apache.struts2.dispatcher.ServletRedirectResult"/>

            <result-type name="redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/>

            <result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>

            <result-type name="velocity" class="org.apache.struts2.dispatcher.VelocityResult"/>

            <result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/>

            <result-type name="plainText" class="org.apache.struts2.dispatcher.PlainTextResult" />

            <result-type name="postback" class="org.apache.struts2.dispatcher.PostbackResult" />

        </result-types>

 

5.4.1.  dispatcher

把控制权转发给应用程序里的某个资源(请求转发到页面)

5.4.2.  redirect

把响应重定向到另一个资源, 而不是转发给该资源(重定向到页面)

5.4.3.  chain

把响应转发到另外一个Action(转发到具体的指定的action)

5.4.4.  redirectAction

把响应重定向到另一个Action

redirectAction 结果类型接受下面这些参数:

actionName: 指定 “目的地” 动作的名字. 它是默认属性

namespace: 用来指定 “目的地” 动作的命名空间. 如果没有配置该参数,Struts 会把  当前 Action 所在的命名空间作为 “目的地” 的命名空间

 

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "struts-2.3.dtd" >

<struts>

 

   <!-- 配置动态方法映射 -->

   <constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>

 

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

       <!-- 配置全局的结果映射 -->

       <global-results>

            <result name="global">/index.jsp</result>

       </global-results>

   

      <!-- 配置请求urlaction处理方法的映射 -->

      <action name="login" class="com.ys.action.LoginAction" method="login">

         <result name="local">/login.jsp</result>

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

      </action>

     

      <!-- 动态方法绑定 -->

      <!-- 当处理结果跳转到的是具体的action处理方法时,result的值为actionname即可 -->

      <action name="result" class="com.ys.action.ResultTypeAction">

         <result name="resultOne" type="dispatcher">/resultOne.jsp</result>

         <result name="resultTwo" type="chain">chainAction</result>

         <result name="resultThree" type="redirect">/resultThree.jsp</result>

         <result name="resultFour" type="redirectAction">redirectAction</result>

      </action>

     

      <action name="chainAction" class="com.ys.action.ResultTypeAction" method="chainAction"></action>

      <action name="redirectAction" class="com.ys.action.ResultTypeAction" method="redirectAction"></action>

      

    </package>

</struts>

 

 

namespace是的注意事项:

访问路径为:http://localhost:8080/a/b/test.action

首先,会去命名空间”/a/b”去找test.action,如果没有找到则去下一级命名空间(/a)找。

如果在找不到则去默认的命名空间(/)中找.

 

 

5.4.5.  动态结果

根据action类中属性的getter方法获取值,作为结果视图的名称

 

 

5.5. ActionSuport的常量

SUCCESS:行动的执行是成功的。结果视图展示给最终用户

NONE:Action执行成功,但是不会显示一个视图。通常产生这种情况的原因是被其他视图重定向了。

ERROR:Action执行失败。显示一个错误的视图(页面),这个页面可以要求用户再次输入相关数据

INPUT:Action的执行成功需要更多的输入。这个结果是一个典型的结果,它表明如果一个表单通过提供默认的表单来操作一个Action。这个表单会显示给最终用户。
这个结果也用于用户输入无效,意味着用户需要再次输入。

 LOGIN:Action不能执行,因为用户没有登录。已登录的画面会被关闭。

6.     参数绑定

Servlet:request.getParamter(“key”);

Struts2:字段,实体,ModelDriven

页面数据---->action

6.1. 字段绑定

 页面代码:

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

                用户名:<input type="text" name="username"/><br/>

               密码:<input type="text" name="password"/><br/>

               <input type="submit" value="提交"/><br/>

    </form>

   

action的代码:

publicclass LoginAction extends ActionSupport{

   

    private String username;

    private String password;

    publicvoid setUsername(String username) {

        this.username = username;

    }

    publicvoid setPassword(String password) {

        this.password = password;

    }

    publicvoid login(){

        System.out.println("用户登录:"+username+":"+password);

        //获取到用户名和密码

    }

}

 

 

6.2. 实体类绑定

页面代码:

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

                用户名:<input type="text" name="user.username"/><br/>

               密码:<input type="text" name="user1.password"/><br/>

               <input type="submit" value="提交"/><br/>

    </form>

业务控制器代码:

package com.ys.action;

 

import com.opensymphony.xwork2.ActionSupport;

import com.ys.entity.User;

 

//user.username  setUser().setUsername();

publicclass LoginEntityAction extends ActionSupport{

   

//必须给user属性添加setter/getter方法

    private User user;

   

    public void setUser(User user) {

        this.user = user;

    }

 

public User getUser() {

        return this.user;

    }

 

    publicvoid login(){

        System.out.println("用户登录LoginEntityAction---"+user);

    }

   

 

}

 

实体类代码:

package com.ys.entity;

 

publicclass User {

   

    private String username;

    private String password;

   

   

    public String getUsername() {

        returnusername;

    }

    publicvoid setUsername(String username) {

        this.username = username;

    }

    public String getPassword() {

        returnpassword;

    }

    publicvoid setPassword(String password) {

        this.password = password;

    }

    @Override

    public String toString() {

        return"User [username=" + username + ", password=" + password + "]";

    }

}

 

 

6.3. ModelDriven绑定

页面代码:

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

                用户名:<input type="text" name="username"/><br/>

               密码:<input type="text" name="password"/><br/>

               <input type="submit" value="提交"/><br/>

    </form>

业务控制器代码:

publicclass LoginModelDrivenAction extends ActionSupport implements ModelDriven<User>{

   

    private User user = new User();

   

   

    publicvoid login(){

        System.out.println("通过ModelDriven绑定参数:"+user);

    }

 

    @Override

    public User getModel() {

        returnuser;

    }

}

 

实体类代码:

package com.ys.entity;

 

publicclass User {

   

    private String username;

    private String password;

   

   

    public String getUsername() {

        returnusername;

    }

    publicvoid setUsername(String username) {

        this.username = username;

    }

    public String getPassword() {

        returnpassword;

    }

    publicvoid setPassword(String password) {

        this.password = password;

    }

    @Override

    public String toString() {

        return"User [username=" + username + ", password=" + password + "]";

    }

}

 

 

6.4. 将数据封装到List集合

页面代码:

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

        method="post">

        用户名:<input type="text" name="list" /><br />密码:<input type="text"

            name="list" /><br />

        用户名:<input type="text"

            name="userList[0].username" /><br />密码:<input type="text"

            name="userList[0].password" /><br />用户名:<input type="text"

            name="userList[1].username" /><br />密码:<input type="text"

            name="userList[1].password" /><br />

            <input type="submit" value="提交" /><br />

    </form>

业务控制器代码:

package com.ys.action;

 

import java.util.List;

 

import com.opensymphony.xwork2.ActionSupport;

import com.ys.entity.User;

 

publicclass ListAction extends ActionSupport{

   

    //提交多个checkbox的值时,可以这么使用

    private List<String> list;

   

    private List<User> userList;

 

    publicvoid setList(List<String> list) {

        this.list = list;

    }

   

    public List<User> getUserList() {

        returnuserList;

    }

    publicvoid setUserList(List<User> userList) {

        this.userList = userList;

    }

    publicvoid login(){

        System.out.println("集合为:"+list);

        System.out.println(userList);

    }

}

6.5.   将数据封装到Map集合

页面代码:

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

        method="post">

        用户名:<input type="text" name="maps['first'].username" /><br />

        密码:<input type="text" name="maps['first'].password" /><br />

            <input type="submit" value="提交" /><br />

</form>

业务控制器代码:

publicclass MapAction extends ActionSupport{

   

    private Map<String,User> maps;

   

    publicvoid setMaps(Map<String, User> maps) {

        this.maps = maps;

    }

    public Map<String, User> getMaps() {

        returnmaps;

    }

   

    publicvoid login(){

        Set<String> keySet = maps.keySet();

        for (String string : keySet) {

            User user = maps.get(string);

            System.out.println(user);

        }

    }

}

 

 

7.     Action访问Servlet API

actionContext:与servletapi解耦

实现接口:

ServletActionContext:与servletapi耦合

 

7.1. ActionContext

1)通过 ActionContext 访问 Web 资源:ActionContext是 Action 执行的上下文对象, 在 ActionContext 中保存了 Action 执行所需要的所有对象, 包括 parameters, request, session, application 等.

2)获取 HttpSession 对应的 Map 对象: publicMap getSession() , session 对应的Map 实际上是SessionMap 类型的,强转之后调用其invalidate() 方法,可以使其session 失效

3)获取 ServletContext 对应的 Map 对象: publicMap getApplication()

4)获取请求参数对应的 Map 对象: publicMap getParameters()

5)获取 HttpServletRequest对应的 Map 对象: public Object get(Object key):ActionContext 类中没有提供类似getRequest() 这样的方法来获取 HttpServletRequest 对应的 Map 对象. 要得到 HttpServletRequest 对应的 Map 对象, 可以通过为 get() 方法传递“request”参数实现

 

package com.ys.action;

 

import java.util.Map;

 

import com.opensymphony.xwork2.ActionContext;

import com.opensymphony.xwork2.ActionSupport;

 

 

/**

 * 访问ServletAPI的第一种方式

 * @author Administrator

 *

 */

public class ServletOneAction extends ActionSupport{

        

   //把数据带回页面

         public String transferData(){

                  

                   //获取到ActionContext

                   ActionContext actionContext = ActionContext.getContext();

                   //把数据添加到request域

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

                   request.put("requestText","requestText");

                   //把数据局添加到Session域

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

                   session.put("sessionText", "session作用域的值");

                   //把数据局添加都application域

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

                   application.put("applicationText", "session作用域的值");

 

                   return ActionSupport.SUCCESS;    

         }

}

 

 

7.2. 实现接口

实现ServletContextAware,ServletRequestAware,ServletResponseAware注入servletAPI

 

package com.ys.action;

 

import java.util.Map;

 

import javax.servlet.ServletContext;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.servlet.http.HttpSession;

 

import org.apache.struts2.interceptor.ServletRequestAware;

import org.apache.struts2.interceptor.ServletResponseAware;

import org.apache.struts2.util.ServletContextAware;

 

import com.opensymphony.xwork2.ActionContext;

import com.opensymphony.xwork2.ActionSupport;

 

public class ServletTwoAction implements ServletRequestAware,ServletResponseAware,ServletContextAware{

        

         private HttpServletRequest request;

         private HttpServletResponse response;

    private ServletContext servletContext;//application

        

         //注入request

         @Override

         public void setServletRequest(HttpServletRequest request) {

                   this.request = request;

         }

 

         //注入Reponse

         @Override

         public void setServletResponse(HttpServletResponse response) {

                   this.response = response;

         }

 

         //注入Application

         @Override

         public void setServletContext(ServletContext servletContext) {

                   this.servletContext = servletContext;

         }

        

         //把数据带回页面

                   public String transferData(){

                           

                            request.setAttribute("requestText","r12345678t");

                           

                            HttpSession session = request.getSession();

                            session.setAttribute("sessionText", "session作用域的值");

                            servletContext.setAttribute("applicationText", "session作用域的值");

 

                            return ActionSupport.SUCCESS;

                   }

 

}

 

 

7.3. ServletActionContext

   1) 直接访问 ServletAPI 将使 Action 与 Servlet 环境耦合在一起,  测试时需要有Servlet 容器, 不便于对 Action 的单元测试;

  2) 直接获取 HttpServletRequest 对象: ServletActionContext.getRequest();

   3) 直接获取HttpSession 对象:ServletActionContext.getRequest().getSession();

4) 直接获取 ServletContext 对象:ServletActionContext.getServletContext();

 

package com.ys.action;

 

import java.util.Map;

 

import javax.servlet.ServletContext;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.servlet.http.HttpSession;

 

import org.apache.struts2.ServletActionContext;

 

import com.opensymphony.xwork2.ActionContext;

import com.opensymphony.xwork2.ActionSupport;

 

publicclass ServletThreeAction {

 

    // 把数据带回页面

    public String transferData() {

       

        HttpServletRequest request = ServletActionContext.getRequest();

        HttpServletResponse response = ServletActionContext.getResponse();

    ServletContext servletContext = ServletActionContext.getServletContext();

       

        request.setAttribute("requestText","asdfghjklqwertyui");

       

        HttpSession session = request.getSession();

       

        session.setAttribute("sessionText", "session作用域的值");

        servletContext.setAttribute("applicationText", "session作用域的值");

 

        return ActionSupport.SUCCESS;

 

    }

 

}

 

 

 

8.     struts标签

引入struts标签库

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

 

8.1. 数据标签

8.1.1.  property标签

  ${}

  1.功能说明

      获取对象的属性值,目标对象默认位于ValueStack栈顶

  2.标签属性

3.示例代码

<s:property value="user.userName"/>

8.1.2. set 标签

1.  功能说明
设定指定 scope 范围内对象的属性值。指出:这里的scope 只能修改如下表格中的属性。

2.  标签属性

 

8.2. form表单UI标签

8.2.1.   Form UI 简单表单

8.2.2.   select 标签

1.功能说明:
生成 select 标签(含option)

2.标签属性:

3.示例代码

<s:select list="products" listKey="id" listValue="name" label="产品" />

8.2.3.  checkboxlist 标签

1.功能说明:

生成一组 checkbox

2.  标签属性:

 

3.示例代码:

 <s:checkboxlist name="favors" list="products" listKey="id" listValue="name"/>

 

8.2.4.   Radio 标签

1.功能说明:

生成一组 radio

2.  标签属性:

 

3.示例代码

<s:radio name="favorite" list="products" listKey="id" listValue="name"/>

 

action代码:

package com.ys.action;

import java.util.HashMap;

import java.util.Map;

import com.opensymphony.xwork2.ActionContext;

import com.opensymphony.xwork2.ActionSupport;

/**

 *

 * 业务控制器的三种编写方式

 * 1.普通java类

 * 2.实现Action接口

 * 3.继承ActionSupport(数据校验,国际化之类...)

 * @author Administrator

 *

 */

public class LoginAction extends ActionSupport{

         private Map<String,String> radioMap = new HashMap<String,String>();

         private Map<String,Object> hobbysMap = new HashMap<String,Object>();

         public Map<String, String> getRadioMap() {

                   return radioMap;

         }

         public void setRadioMap(Map<String, String> radioMap) {

                   this.radioMap = radioMap;

         }

         public Map<String, Object> getHobbysMap() {

                   return hobbysMap;

         }

         public void setHobbysMap(Map<String, Object> hobbysMap) {

                   this.hobbysMap = hobbysMap;

         }

         public String toPage(){

                   radioMap.put("0", "男");

                   radioMap.put("1", "女");

                   radioMap.put("2", "人妖");

                   hobbysMap.put("eat","吃饭");

                   hobbysMap.put("sleep","睡觉");

                   hobbysMap.put("hitdoudou","打豆豆");

              Map<String,String> maps = new HashMap<String,String>();

              maps.put("a","a");

              maps.put("b","b");

              ActionContext context = ActionContext.getContext();

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

              request.put("requstMaps", maps);

                   System.out.println(hobbysMap);

                  

                   return "index";

         }

}

页面代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

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

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Insert title here</title>

</head>

<body>

 

    <s:property value="#request.list"/>

    <h2>radio</h2>

   <s:radio list="radioMap" name="sex" />

   <h2>checkbox</h2>

   <s:checkbox name="hobby" value="篮球" label="篮球"></s:checkbox>

   <s:checkbox name="hobby" value="王者" label="王者"></s:checkbox>

   <s:checkbox name="hobby" value="吃鸡" label="吃鸡"></s:checkbox>

  

   <h2>使用checkboxlist实现复选框</h2>

   <s:checkboxlist list="#{'lanqiu':'篮球','zuqiu':'足球'}" name="aihao"></s:checkboxlist>

   <s:checkboxlist list="hobbysMap" name="hobbys"></s:checkboxlist>

  

    <s:checkboxlist list="#request.requstMaps" name="hobbyrequest"></s:checkboxlist>

 

    <h2>property标签</h2>

    ${radioMap1}

    <s:property value="radioMap1" default="11111"/>

    <s:set value="xiaoming" var="username" scope="request"></s:set>

    <s:property value="#request.username" />

</body>

</html>

 

8.3. 控制标签

8.3.1.   if-elseif-else 标签

1.    功能说明:
替代 Java 语法中的if/else

2.    2.标签属性:


3.示例代码

欢迎${user.name} ,

<s:if test="user.role == 'admin'">系统管理员</s:if>

 <s:elseif test="user.role == 'member'">会员</s:elseif>

 <s:else>游客</s:else>

action的代码:

package com.ys.action;

 

import java.util.ArrayList;

import java.util.List;

 

import com.opensymphony.xwork2.ActionSupport;

import com.ys.entity.User;

 

publicclass ControllerAction extends ActionSupport{

   

    private User user

    public User getUser() {

        returnuser;

    }

    publicvoid setUser(User user) {

        this.user = user;

    }

    public String toControllerTag(){

        user = new User();

        user.setUsername("张三");

        return ActionSupport.SUCCESS;

    }

 

 

}

 

<h1>if elseif else标签</h1>

      <s:if test="user.username==null">

            用户名为空

      </s:if>

      <s:else>

           <s:property value="user.username"/>

      </s:else>

       <s:if test="user.password==null">

               密码为空

      </s:if>

      <s:else>

           <s:property value="user.password"/>

      </s:else>

 

8.3.2.  iterator 标签

1.功能说明:
替代 Java 语言中 foreach 的功能
2.标签属性:

 

3.示例代码

<s:iterator value="products"> <s:property value="name"/>,<s:property value="price"/> <br /> </s:iterator>

package com.ys.action;

 

import java.util.ArrayList;

import java.util.List;

 

import com.opensymphony.xwork2.ActionSupport;

import com.ys.entity.User;

 

publicclass ControllerAction extends ActionSupport{

   

    private List<User> userList = new ArrayList<User>();

   

    public List<User> getUserList() {

        returnuserList;

    }

    publicvoid setUserList(List<User> userList) {

        this.userList = userList;

    }

    public String toControllerTag(){

        for(inti=1;i<20;i++){

            User user = new User();

            user.setUsername("username"+i);

            user.setAge(i);

            user.setPassword("pwd"+i);

            userList.add(user);

        }

        return ActionSupport.SUCCESS;

    }

}

<h1>iterator标签</h1>

  <s:iterator value="userList" id="tempUser" >

      <s:property value="username"/>

      <s:property value="password"/>

      <s:property value="age"/>

    <br/>

  </s:iterator>

 注意事项:在遍历集合时,可以直接通过属性名获取到其内容

 

9.     数据校验

9.1. 什么是数据校验

 Struts2支持设置字段的规则来验证表单传过来的数据

客户端校验  过滤正常用户的误操作,通过JS代码完成

服务器端校验,整个应用阻止非法数据的最后防线

 

9.2. struts校验方式

 

9.2.1.  手动完成输入校验

  <s:fielderror/>

对action指定方法进行校验

   校验指定的方法通过重写validateXxx()方法实现,validateXxx()只会校验action中

   方法名为Xxx的方法。其中Xxx的第一个字母要大写。

action代码:

package com.ys.action;

 

import com.opensymphony.xwork2.ActionSupport;

 

publicclass ValidationAction extends ActionSupport {

 

    private String username;

    private String password;

 

    public String getUsername() {

        returnusername;

    }

    publicvoid setUsername(String username) {

        this.username = username;

    }

 

    public String getPassword() {

        returnpassword;

    }

    publicvoid setPassword(String password) {

        this.password = password;

    }

   

    //重写validate方法

    //在该方法进行数据校验

    @Override

    publicvoid validate() {

        if(username==null|| "".equals(username)){

            //错误信息

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

        }

        if(password==null|| "".equals(password)){

            //错误信息

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

        }

        System.out.println("校验");

    }

 

    public String login() {

        System.out.println("username:"+username+",password:"+password);

       return  ActionSupport.SUCCESS;

    }

}

 

页面代码:

<!-- 显示所有的错误信息 -->

 <s:fielderror></s:fielderror>

 <!-- 显示对应表单的错误信息 -->

  <s:form action="loginValidate.action" method="post">

      <s:textfield name="username" errorPosition="bottom"></s:textfield>

      <s:textfield name="password" errorPosition="bottom" cssErrorStyle="color:red;"></s:textfield>

      <s:submit value="提交"></s:submit>

  </s:form>

 

9.2.2.  编写校验规则文件

验证的xml文件的规范在xwork-core-xxx.jar包下的:xwork-validator-1.0.3.dtd

 该文件需要和action类放在同一个包下,文件的取名应遵守

 ActionClassName-validation.xml规则,其中ActionClassName为action

 的简单类名,-validation为固定写法。

校验文件的元素介绍

<validators>:根元素

<field>:指定action中要校验的属性,name属性指定将被验证的表单字段的名字

<field-validator>:指定校验器, type 指定验证规则

<param>:子元素可以向验证程序传递参数

<message>:子元素为校验失败后的提示信息,如果需要国际化,可以为message

          指定key属性,key的值为属性文件中的key。

系统提供的校验器

 

required (必填校验器,要求被校验的属性值不能为null)

requiredstring (必填字符串校验器,要求被校验的属性值不能为null,并且长度大于0,默认情况下会对字符串去前后空格)

stringlength(字符串长度校验器,要求被校验的属性值必须在指定的范围内,否则校验失败,minLength参数指定最小长度,maxLength参数指定最大长度,trim参数指定校验field之前是否去除字符串前后的空格)

regex(正则表达式校验器,检查被校验的属性值是否匹配一个正则表达式,expression参数指定正则表达式,caseSensitive参数指定进行正则表达式匹配时,是否区分大小写,默认值为true)

int(整数校验器,要求field的整数值必须在指定范围内,min指定最小值,max指定最大值)

double(双精度浮点数校验器,要求field的双精度浮点数必须在指定范围内,min指定最小值,max指定最大值)

fieldexpression(字段OGNL表达式校验器,要求field满足一个ognl表达式,expression参数指定ognl表达式,该逻辑表达式基于ValueStack进行求值,返回true时校验通过,否则不通过)

email(邮件地址校验器,要求如果被校验的属性值非空,则必须是合法的邮件地址)

url(网址校验器,要求如果被校验的属性值非空,则必须是合法的url地址)

date(日期校验器,要求field的日期值必须在指定范围内,min指定最小值,max指定最大值)

conversion(转换校验器,指定在类型转换失败时,提示的错误信息)

visitor(用于校验action中复合类型的属性,它指定一个校验文件用于校验复合类型属性中的属性)

expression(OGNL表达式校验器,它是一个非字段校验器, expression参数指定ognl表达式,该逻辑表达式基于ValueStack进行求值,返回true时校验通过,否则不通过,该校验器不可用在字段校验器风格的配置中)

示例代码:

页面代码:

<!-- 显示所有的错误信息 -->

 <s:fielderror></s:fielderror>

 <!-- 显示对应表单的错误信息 -->

  <s:form action="loginValidate.action" method="post">

      <s:textfield name="username" errorPosition="bottom"></s:textfield>

      <s:textfield name="password" errorPosition="bottom" cssErrorStyle="color:red;"></s:textfield>

      <s:submit value="提交"></s:submit>

  </s:form>

action代码:

package com.ys.action;

 

import com.opensymphony.xwork2.ActionSupport;

 

publicclass ValidationFileAction extends ActionSupport {

 

    private String username;

    private String password;

 

    public String getUsername() {

        returnusername;

    }

 

    publicvoid setUsername(String username) {

        this.username = username;

    }

 

    public String getPassword() {

        returnpassword;

    }

 

    publicvoid setPassword(String password) {

        this.password = password;

    }

 

    public String loginValidate() {

       System.out.println("username:"+username+",password:"+password);

       return ActionSupport.SUCCESS;

       

    }

}

 

校验文件代码:
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.3//EN" "xwork-validator-1.0.3.dtd" >

<validators>

   <!-- 配置对应的字段约束 -->

   <!-- name:表单的name属性对应的值 -->

  <field name="username">

    <!-- type属性值在如下文件找:

      /com/opensymphony/xwork2/validator/validators/default.xml

     -->

    <field-validator type="requiredstring">

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

    </field-validator>

    <field-validator type="stringlength">

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

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

        <message>用户名的长度必须在${minLength}${maxLength}</message>

    </field-validator>

  </field>

</validators>

 

 

9.2.3.  基于Annotation的输入校验

10.struts2国际化

10.1.  什么是国际化

可以为不同语言环境的用户,提供不同语言界面。struts2中对国际化进行了封装,我们只需要根据其提供的API进行访问就可以。

10.2.  国际化配置

10.2.1.          全局国际化信息文件

 在struts.xml中配置相应的常量

<constant name="struts.custom.i18n.resources" value="messages"></constant>   messages.properties 在classpath

注意事项:

 配置全局的国际化文件时,value值为资源文件的文件名,不带语言版本。

 如果该资源文件放在具体的包中是,value的值必须带上包名。

 

 

资源文件存放的目录及文件名如下:

struts.xml配置文件中的配置如下:

 <constantname="struts.custom.i18n.resources" value="messages,i18nmessages,com.ys.i18n.pageckagei18n"></constant>

使用国际化资源:

 <s:text name="username.tip"></s:text>

   <s:text name="username"></s:text>

   <s:text name="password"></s:text>

   <s:text name="tip"></s:text>

     <s:form action="login.action" method="post">

        <s:textfield name="username"  key="username"></s:textfield>

        <s:textfield name="password" key="password"></s:textfield>

        <s:submit value="提交"></s:submit>

    </s:form>

 

使用国际化信息

         1.在Action中使用  :this.getText("msg");

   

示例代码:

public String login() {

        String text = this.getText("username.tip");

        System.out.println("内容为:" + text);

        return ActionSupport.SUCCESS;

    }

 

         2.在jsp中使用  :<s:textname="msg" />

示例代码:

<body>

   <s:text name="username.tip"></s:text>

   <s:text name="username"></s:text>

   <s:text name="password"></s:text>

   <s:text name="tip"></s:text>

     <s:form action="login.action" method="post">

        <s:textfield name="username"  key="username"></s:textfield>

        <s:textfield name="password" key="password"></s:textfield>

        <s:submit value="提交"></s:submit>

    </s:form>

</body>

 

         3.在配置文件中(校验xml) : <messagekey="agemsg"></message>

示例代码:

<validators>

  <field name="username">

    <field-validator type="requiredstring">

      <message  key="username.notnull"/>

    </field-validator>

  </field>

</validators>

 

 

配置国际化时需要有不同语言版本的内容(properites文件)

baseName_语言的简写_国家地区的简写.properites

例如:

中国:messages_zh_CN.properties

美国:messages_en_US.properties

 

10.2.2.          Action范围信息文件

数据只能在对应Action中使用,在Action类所在包创建 Action类名.properties

 --------- 无需配置

中文;Action类名_zh_CN.properties

英文;Action类名_en_US.properties

10.2.3.          package范围信息文件

数据对包(包括子包)中的所有Action 都有效, 在包中创建package.properties

----- 无需配置

中文;package_zh_CN.properties

英文;package_en_US.properties

 

11.struts2的类型转换器

11.1.  Struts2内置的类型转换器

对于大部分常用类型,开发者根本无需创建自己的转换器,Struts2内置了常见数据类型多种转换器

boolean 和 Boolean,char和 Character,int 和 Integer,long 和 Long

float 和 Float,double 和 Double

数组  可以将多个同名参数,转换到数组中

集合  支持将数据保存到 List或者 Map 集合

11.2.  自定义类型转换器

实现TypeConverter接口

 

继承StrutsTypeConverter类来实现自定义类型转换器

示例代码:

package com.ys.converter;

 

import java.text.ParseException;

import java.text.SimpleDateFormat;

import java.util.Date;

import java.util.Map;

 

import org.apache.struts2.util.StrutsTypeConverter;

 

public class DateConverter extends StrutsTypeConverter{

        

         private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

 

         @Override

         public Object convertFromString(Map context, String[] values, Class toClass) {

                   System.out.println("类型转换器执行--->convertFromString");

                   for (String string : values) {

                            System.out.println("value为:"+string);

                   }

                   //非空判断

                   if(values!=null && values[0]!=null && !"".equals(values[0])){

                            try {

                                     Date parse = format.parse(values[0]);

                                     return parse;

                            } catch (ParseException e) {

                                     e.printStackTrace();

                            }

                   }

                   return null;

         }

 

         @Override

         public String convertToString(Map context, Object o) {

                   System.out.println("类型转换器执行--->convertToString");

                   return null;

         }

 

        

 

}

 

 

 

 

11.3.  注册类型转换器

11.3.1.          全局类型转换器

在classpath下放置xwork-conversion.properties文件 。

在properties文件中的内容为:待转换的类型=类型转换器的全类名

java.util.Date=com.ys.converter.DateConverter

 

 

11.3.2.          局部类型转换器

在Action类所在的包下放置ActionClassName-conversion.properties文件,

ActionClassName是Action的类名,后面的-conversion.properties是固定写法。

在properties文件中的内容为:属性名称=类型转换器的全类名

 

12.struts2拦截器

Struts2 拦截器在访问某个 Action 方法之前或之后实施拦截,Struts2 拦截器是可插拔的, 拦截器是 AOP 的一种实现

 

拦截器栈(Interceptor Stack): 将拦截器按一定的顺序联结成一条链. 在访问被拦截的方法时, Struts2拦截器链中的拦截器就会按其之前定义的顺序被依次调用。

 

12.1.  拦截器的生命周期

init: 该方法将在拦截器被创建后立即被调用, 它在拦截器的生命周期内只被调用一次. 可以在该方法中对相关资源进行必要的初始化

interecept: 每拦截一个动作请求, 该方法就会被调用一次. (拦截器的核心方法)

destroy: 该方法将在拦截器被销毁之前被调用, 它在拦截器的生命周期内也只被调用一次

 

12.2.  自定义拦截器

自定义拦截器的步骤:

自定义拦截器

   1.实现Interceptor接口

   2.继承AbstractInterceptor抽象类

在 struts.xml 文件中配置自定义的拦截器

 

注意事项:

因为struts2中如文件上传,数据验证,封装请求参数到action等功能都是由系统默认的defaultStack中的拦截器实现的,所以我们定义的拦截器需要引用系统默认的defaultStack,这样应用才可以使用struts2框架提供的众多功能。

如果希望包下的所有action都使用自定义的拦截器,可以通过<default-interceptor-ref name=“permissionStack”/>把拦截器定义为默认拦截器。注意:每个包只能指定一个默认拦截器。另外,一旦我们为该包中的某个action显式指定了某个拦截器,则默认拦截器不会起作用。

 

示例代码:

自定义Interceptor:

package com.ys.interceptor;

 

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpSession;

 

import org.apache.struts2.ServletActionContext;

 

import com.opensymphony.xwork2.ActionInvocation;

import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

 

public class NoLoginInterceptor extends AbstractInterceptor {

 

         @Override

         public String intercept(ActionInvocation invocation) throws Exception {

                   System.out.println("noLoginInterceptor---------");

                   HttpServletRequest request = ServletActionContext.getRequest();

                   HttpSession session = request.getSession();

                   Object object = session.getAttribute("loginUser");

                   if(object==null){//用户未登录,跳回登录页面

                            return "login";

                   }else{

                            /*String invoke =

                            System.out.println("invoke:"+invoke);*/

                            return invocation.invoke();

                            //return invoke;

                   }

         }

 

}

 

配置拦截器:

 

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "struts-2.3.dtd" >

<struts>

    <!-- 配置国际化的资源文件为xxxx -->

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

       

          <!-- 配置拦截器 -->

          <interceptors>

              <interceptor name="myInterceptor" class="com.ys.interceptor.MyInterceptor"></interceptor>

              <!-- 配置未登录的拦截器 -->

              <interceptor name="noLoginInterceptor" class="com.ys.interceptor.NoLoginInterceptor"></interceptor>

              <!-- 拦截器栈 -->

              <interceptor-stack name="myInterceptorStack">

                  <interceptor-ref name="myInterceptor"></interceptor-ref>

                  <interceptor-ref name="defaultStack"></interceptor-ref>

              </interceptor-stack>

          </interceptors>

   

         <action name="login" class="com.ys.action.LoginAction" method="login">

            <result name="input">/login.jsp</result>

            <result name="success" type="chain">index</result>

           

            <interceptor-ref name="myInterceptorStack"></interceptor-ref>

             <!-- 引入自定义的拦截器

                  注意事项:引用了自定义的拦截器之后,原来默认的拦截器会失效,

                  如果需要使用需要手动引入

            

            <interceptor-ref name="myInterceptor"></interceptor-ref>

                         在此引用默认的拦截器

            <interceptor-ref name="defaultStack"></interceptor-ref>  -->

         </action>

         <!-- 首页的Action -->

         <action name="index" class="com.ys.action.IndexAction" method="index">

            <result name="success">/index.jsp</result>

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

            <interceptor-ref name="noLoginInterceptor"></interceptor-ref>

            <interceptor-ref name="myInterceptor"></interceptor-ref>

            <interceptor-ref name="defaultStack"></interceptor-ref>

         </action>

    </package>

</struts>

 

配置拦截器:

在<package>中定义拦截器以及拦截器栈

然后在对应的action中引人定义的拦截器即可

 

注意事项:放行拦截器调用ActionInvocation的invoke()方法,该方法会链式调用其他拦截器

 

12.3.  配置拦截器对action中的某些方法进行拦截

编写拦截器继承MethodFilterInterceptor类

package com.ys.interceptor;

 

import com.opensymphony.xwork2.ActionInvocation;

import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;

 

public class MyMethodInterceptor extends MethodFilterInterceptor {

 

         @Override

         protected String doIntercept(ActionInvocation invocation) throws Exception {

                   System.out.println("拦截了");

                   return invocation.invoke();

         }

}

在struts.xml中配置拦截器

 <interceptor name="myMethodInterceptor" class="com.ys.interceptor.MyMethodInterceptor">

                  <!-- 不拦截方法 -->

                  <param name="excludeMethods">find</param>

                  <!-- 拦截方法 -->

                  <param name="includeMethods">add,delete</param>

              </interceptor>

    <action name="*" class="com.ys.action.MethodInterceptorAction" method="{1}">

             <result>/index.jsp</result>

             <interceptor-ref name="myMethodInterceptor"></interceptor-ref>

             <interceptor-ref name="defaultStack"></interceptor-ref>

         </action>

        

 

13.struts2文件上传下载

13.1.  springmvc的文件上传

commons-fileupload

commons-io

 

页面

<form action=””  method=”post” enctype=”multipart/form-data”>

  <input type=”file”  name=”uploadFile”/>

</form>

 

Controller

    public String upload(Multipart uploadFile){

        uploadFile.transferTo();

}

 

springmvc的核心配置文件中

配置文件上传解析器

13.2.  文件上传步骤

1.     在 Jsp 页面的文件上传表单里使用file 标签. 如果需要一次上传多个文件, 就必须使用多个 file 标签, 但它们的名字必须是相同的

2.     在 Action 中新添加 3 个和文件上传相关的属性. 这 3 个属性的名字必须是以下格式

 private File uploadImage; //上传的文件

private String uploadImageContentType;  //上传的文件的类型

private String uploadImageFileName;     //上传文件的名称

 uploadImage 是 jsp 页面上的 file 标签的名字.

          上传文件:<inputtype="file" name="uploadImage">

3.如果是上传单个文件,uploadImage属性的类型就是 java.io.File, 它代表被上传的文件, 第二个和第三个属性的类型是 String, 它们分别代表上传文件的文件名和文件类型

定义方式是分别是jsp页面file组件的名称+ContentType, jsp页面file组件的名称+FileName

4.        如果上上传多个文件, 可以使用数组或 List

 

单文件上传示例代码:

package com.ys.action;

 

import java.io.File;

 

import org.apache.commons.io.FileUtils;

 

import com.opensymphony.xwork2.ActionSupport;

 

publicclass FileUploadAction extends ActionSupport {

 

    // 文件上传必须要有的属性

   

    private File uploadFile//文件属性和表单中的file表单中的name属性一致

    private String uploadFileContentType;//类型名称为 File属性名+ ContentType

    private String uploadFileFileName;//文件名为File属性名+FileName

 

    public File getUploadFile() {

        returnuploadFile;

    }

    publicvoid setUploadFile(File uploadFile) {

        this.uploadFile = uploadFile;

    }

    public String getUploadFileContentType() {

        returnuploadFileContentType;

    }

    publicvoid setUploadFileContentType(String uploadFileContentType) {

        this.uploadFileContentType = uploadFileContentType;

    }

    public String getUploadFileFileName() {

        returnuploadFileFileName;

    }

    publicvoid setUploadFileFileName(String uploadFileFileName) {

        this.uploadFileFileName = uploadFileFileName;

    }

    @Override

    public String execute() throws Exception {

       

        //保存到D:/upload文件夹中

        //commons-io包下有一个工具类:把源文件复制到目标文件

        //构建目标文件

        File destFile = new File("D:/upload/",uploadFileFileName);

        FileUtils.copyFile(uploadFile, destFile);

       

        System.out.println("文件名:"+this.uploadFileFileName);

        System.out.println("文件类型:"+this.uploadFileContentType);

        System.out.println("文件上传成功。。。。。。。");

 

        return ActionSupport.SUCCESS;

    }

}

 

 <s:form action="fileupload.action" method="post" enctype="multipart/form-data">

      <s:file name="uploadFile"></s:file>

      <s:submit value="提交"></s:submit>

   </s:form>

 

多文件上传:

package com.ys.action;

 

import java.io.File;

import java.util.List;

 

import org.apache.commons.io.FileUtils;

 

import com.opensymphony.xwork2.ActionSupport;

 

/**

 * 多文件上传

 */

public class MutipartFileUploadAction extends ActionSupport {

 

         //属性的类型为集合或者数组都ok

         private List<File> uploadFile;

         private List<String> uploadFileContentType;

         private List<String> uploadFileFileName;

 

         public List<File> getUploadFile() {

                   return uploadFile;

         }

 

         public void setUploadFile(List<File> uploadFile) {

                   this.uploadFile = uploadFile;

         }

 

         public List<String> getUploadFileContentType() {

                   return uploadFileContentType;

         }

 

         public void setUploadFileContentType(List<String> uploadFileContentType) {

                   this.uploadFileContentType = uploadFileContentType;

         }

 

         public List<String> getUploadFileFileName() {

                   return uploadFileFileName;

         }

 

         public void setUploadFileFileName(List<String> uploadFileFileName) {

                   this.uploadFileFileName = uploadFileFileName;

         }

 

         @Override

         public String execute() throws Exception {

                   for(int i=0;i<uploadFile.size();i++){

                             File destFile = new File("d:/upload/"+uploadFileFileName.get(i));

                             FileUtils.copyFile(uploadFile.get(i) , destFile);

                   }

                  

                  

     for (String filename : uploadFileFileName) {

                   System.out.println("上传的文件名为:"+filename);

         }

                   System.out.println("文件上传成功。。。。。。。。。。。");

                   return ActionSupport.SUCCESS;

         }

 

}

 

<body>

    <s:fielderror></s:fielderror>

    <s:actionerror/>

   <s:form action="multipartfileupload.action" method="post" enctype="multipart/form-data">

      <s:file name="uploadFile"></s:file>

      <s:file name="uploadFile"></s:file>

      <s:file name="uploadFile"></s:file>

      <s:submit value="提交"></s:submit>

   </s:form>

</body>

 

 

13.3.  定义文件上传错误指向的页面

显示文件上传的错误信息:  <s:actionerror/>

 

 

13.4.  设置文件上传的大小限制

在struts.xml中配置静态常量,改变文件上传的默认大小限制。

  <!-- 配置文件上传的大小 -->

   <constant name="struts.multipart.maxSize" value="20971520"></constant>

 

 

控制每一个上传文件的大小以及上传文件的类型

         在fileupload拦截器中,通过其属性进行控制.

                   maximumSize---每一个上传文件大小

                   allowedTypes--允许上传文件的mimeType类型.

                   allowedExtensions--允许上传文件的后缀名.

 

示例代码:

 

13.5.  struts2文件下载

struts2提供了stream结果类型,该结果类型就是专门用于支持文件下载功能的

contentType----下载文件的mimeType类型

contentDisposition---进行下载操作以及下载文件名

inputStream--下载文件对应的流

 

示例代码:

  <a href="${pageContext.request.contextPath}/downloadfile.action?filename=download.txt">下载download.txt</a>

   <br/>

   <a href="${pageContext.request.contextPath}/downloadfile.action?filename=struts2-01.docx">下载struts2-01.docx</a>

   <br/>

   <a href="${pageContext.request.contextPath}/downloadfile.action?filename=小明.txt">下载小明.txt</a>

package com.ys.action;

 

import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.InputStream;

import java.io.UnsupportedEncodingException;

import java.net.URLEncoder;

 

import com.opensymphony.xwork2.ActionSupport;

 

publicclass DownloadAction extends ActionSupport {

 

    private String filename;

 

    public String getFilename() {

        returnfilename;

    }

    publicvoid setFilename(String filename) {

        this.filename = filename;

    }

   

    //下载文件的名字

    public String getDownloadFileName() throws UnsupportedEncodingException{

        //处理中文文件名

        return URLEncoder.encode(this.filename,"utf-8");

    }

   

    //下载文件对应的流

    public InputStream getInputStream() throws FileNotFoundException{

        System.out.println("获取下载文件的流。。。。。。。。");

        //下载的文件

        File downloadFile = new File("D:/upload/",this.filename);

        FileInputStream fis = new FileInputStream(downloadFile);

       

        returnfis;

    }

    @Override

    public String execute() throws Exception {

        System.out.println("文件下载。。。。。。。。。");

        return ActionSupport.SUCCESS;

    }

 

}

 

<!-- 配置下载的action -->

          <action name="downloadfile" class="com.ys.action.DownloadAction">

              <result name="success" type="stream">

                  <!--下载文件对应的流 -->

                  <param name="inputStream">${inputStream}</param>

                  <!-- 下载的行为以及下载的文件名 -->

                  <param name="contentDisposition">attachment;filename=${downloadFileName}</param>

              </result>

          </action>

 

 

14.struts2对json的支持

1.     导入struts2-json-plugin-2.3.24.jar

2.     struts.xml中package 继承 json-default

3.     action的返回结果类型为json

 

示例代码:

   <package name="default" namespace="/" extends="json-default">

          <action name="getJson" class="com.ys.action.JsonAction">

             <result name="success" type="json"></result>

          </action>

    </package>

package com.ys.action;

 

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

 

import com.opensymphony.xwork2.ActionSupport;

import com.ys.entity.User;

 

publicclass JsonAction extends ActionSupport {

   

    private Map<String,String> maps = new HashMap<String,String>();

   

   

    public Map<String, String> getMaps() {

        System.out.println("getMaps");

        returnmaps;

    }

    publicvoid setMaps(Map<String, String> maps) {

        System.out.println("setMaps");

        this.maps = maps;

    }

   

    @Override

    public String execute() throws Exception {

        System.out.println("加载json数据。");

        maps.put("1", "aaaaa");

        maps.put("2", "bbbbb");

        maps.put("3", "ccccc");

        maps.put("4", "ddddd");

        return ActionSupport.SUCCESS;

    }

 

}

 

 

 

15.OGNL表达式

15.1.  OGNL的简介

OGNL(Object Graph Navigating Language)即对象导航图语言,是表达式语言的一种。通常用来绑定Java 对象的属性,用一个表达式就可以读取和设置对应Java 对象的属性,所以可以用来沟通Web 组件和业务逻辑的模型部分。它是Jakarta“属性存取语言”项目和JSTL 的表达式语言的良好替代,常用的标号有#,%,$

 

15.2.   ValueStack

15.2.1.          什么是ValueStack

它是一个接口com.opensymphony.xwork2.util.ValueStack。

我们使用它是将其做为一个容器,用于携带action数据到页面.

在在页面上通过ognl表达式获取数据。

 

15.3.   #的作用

1.     访问 OGNL 上下文和 Action 上下文, #相当于ActionContext.getContext()
下表有几个 ActionContext 中有用的属性:
parameters:包含当前 HTTP 请求参数的 Map#parameters.id[0]作用相当于
       request.getParameter("id")
request:包含当前HttpServletRequest 的属性(attribute)的 Map
       #request.userName 相当于request.getAttribute("userName")
session:包含当前 HttpSession 的属性(attribute)的 Map
       #session.userName 相当于session.getAttribute("userName")
application:包含当前应用的 ServletContext 的属性(attribute)的 Map
       #application.userName 相当于application.getAttribute("userName")
attr:用于按 request > session > application 顺序访问其属性(attribute)
       #attr.userName 相当于按顺序在以上三个范围(scope)内读取 userName
属性,直到找到为止
2. 用于过滤和投影(projecting)集合

#request.books.{?#this.price<100};

?:显示所有满足条件的对象信息

^:显示满足条件的第一个对象信息

$:显示满足条件的最后一个对象信息

示例代码:

<s:iterator value="#request.users.{?#this.role=='admin'}">

<tr>

<td><s:property value="name"/></td>

<td><s:property value="password"/></td>

<td><s:property value="role"/></td>

</tr>

</s:iterator>

3.  构造 Map,如#{'foo1':'bar1', 'foo2':'bar2'}。

<s:set name="foobar" value="#{'foo1':'bar1', 'foo2':'bar2'}" />

<p>The value of key "foo1" is <s:property value="#foobar['foo1']" /></p>

 

15.4.   %的作用

1. 在标志的属性为字符串类型时,计算 OGNL 表达式的值。
2.国际化时,读取资源文件的数据

%{}

15.5.   $的作用${}

1.    用于在国际化资源文件中,引用 OGNL 表达式

2.    在 Struts 2 配置文件中,引用 OGNL 表达式

示例代码:

 <action name="downloadfile" class="com.ys.action.DownloadAction">

              <result name="success" type="stream">

                  <!--下载文件对应的流 -->

                  <param name="inputStream">${inputStream}</param>

                  <!-- 下载的行为以及下载的文件名 -->

                  <param name="contentDisposition">attachment;filename=${downloadFileName}</param>

              </result>

          </action>

3.在验证框架引用变量

示例代码

<field-validator type="stringlength">

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

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

        <message>用户名的长度必须在${minLength}${maxLength}</message>

 </field-validator>

 

16.struts2注解的使用

导入jar包:struts2-convention-plugin-2.3.24.jar

 

16.1.  Struts2使用注解开发需要遵循一些规范

   1、Action要必须继承ActionSupport父类。

   2、Action所在的包名必须以  .action 结尾。

16.2.  action中常用的注解

  1@ParentPackage:对应xml配置文件中的package的父包,一般需要继承struts-default

   2@Namespace:对应配置文件中的nameSpace,命名空间。

3、写在方法前边的注解:

@Action,这个注解对应<action>节点

 4action中最常用的results

       @Result

注意事项:拦截器还的在配置文件中进行配置

示例代码:

package com.ys.action;

 

import org.apache.struts2.convention.annotation.Action;

import org.apache.struts2.convention.annotation.InterceptorRef;

import org.apache.struts2.convention.annotation.Namespace;

import org.apache.struts2.convention.annotation.ParentPackage;

import org.apache.struts2.convention.annotation.Result;

 

import com.opensymphony.xwork2.ActionSupport;

 

/**

 *

 * 使用注解的步骤: 1.导入jar struts2-convention-plugin-2.3.24.jar 2.编写Action注意事项:

 * 1.Action类必须继承ActionSupport 2.Action类必须在.action的包下

 *

 */

@ParentPackage(value = "struts-default") // 继承什么包

@Namespace(value = "/annotation") // 命名空间

publicclass AnnotationAction extends ActionSupport {

 

    private String username;

    private String password;

 

    public String getUsername() {

        returnusername;

    }

 

    publicvoid setUsername(String username) {

        this.username = username;

    }

 

    public String getPassword() {

        returnpassword;

    }

 

    publicvoid setPassword(String password) {

        this.password = password;

    }

 

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

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

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

            ) // 说明这是一个Action处理方法

    public String login() {

        System.out.println(username+" : "+password);

        return ActionSupport.SUCCESS;

    }

}

 

17.三大框架整合

struts2-spring-plugin-2.3.24.jar

 

17.1.  整合spring4和hibernate3

17.2.  struts2的action交给spring管理

导入jar包struts2-spring-plugin-2.3.24.jar

在struts.xml的配置文件中加上如下代码:

 <!-- action的创建权交给spring -->

   <constant name="struts.objectFactory" value="spring"></constant>


 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值