TMaize Blog

Struts2学习-03 页面配置 获取数据

配置结果页面

全局结果页面

多个action的方法的返回值相同,跳转的页面页相同,为了可以通过配置全局结果页面减少配置文件的书写

注意:先从里面的result的name匹配,没找到再找global-results里面的result的name

<!-- 配置在package里 -->
<global-results>
    <result name="error">/error.jsp</result>
</global-results>

局部结果页面

在action里面配置的result

注意:先从里面的result的name匹配,没找到再找global-results里面的result的name

<action name="s_*" class="com.day01.Test" method="{1}">
    <result name="add">/test1.jsp</result>
    <result name="delete">/test2.jsp</result>
    <allowed-methods>add,delete</allowed-methods>
</action>

result标签的type属性

转发操作不改变url地址,一次请求

重定向会改变url地址,多次请求

默认值dispatcher

已配置结果类型名 类名 描述
dispatcher org.apache.struts2.dispatcher.ServletDispatcherResult 默认结果类型,用来呈现JSP页面
chain com.opensymphony.xwork2.ActionChainResult 将action和另外一个action链接起来
freemarker org.apache.struts2.views.freemarker.FreemarkerResult 呈现Freemarker模板
httpheader org.apache.struts2.dispatcher.HttpHeaderResult 返回一个已配置好的HTTP头信息响应
redirect org.apache.struts2.dispatcher.ServletRedirectResult 将用户重定向到一个已配置好的URL
redirectAction org.apache.struts2.dispatcher.ServletActionRedirectResult 将用户重定向到一个已定义好的action
stream org.apache.struts2.dispatcher.StreamResult 将原始数据作为流传递回浏览器端,该结果类型对下载的内容和图片非常有用
velocity org.apache.struts2.dispatcher.VelocityResult 呈现Velocity模板
xslt org.apache.struts2.views.xslt.XSLTResult 呈现XML到浏览器,该XML可以通过XSL模板进行转换
plaintext org.apache.struts2.dispatcher.PlainTextResult 返回普通文本

在action里获得数据

由于Struts默认配置了字符编码,所以post提交表单时不会有乱码

  1. 使用ActionContext类

     //获取当前线程的ActionContext对象
     ActionContext actionContext = ActionContext.getContext();
    
     //在2.5之前是Map<String, Object>
     //Object[] obj = (Object[])map.get(key)
    
     //2.5
     //public class HttpParameters implements Map<String, Parameter>
     HttpParameters form = actionContext.getParameters();
     Parameter p = form.get("name");
     p.getValue()//一般情况
     getMultipleValues()//复选框
    

    完整代码

     ActionContext actionContext = ActionContext.getContext();
     HttpParameters httpParameters = actionContext.getParameters();
     for(String key:httpParameters.keySet()){
         Parameter parameter = httpParameters.get(key);
         for(String value:parameter.getMultipleValues()){
             System.out.println("name="+key+" value="+value);
         }
     }
    
  2. 使用ServletActionContext类

    直接调用里面的静态方法,得到HttpServletRequest和Servlet里面的操作一样

     HttpServletRequest request = ServletActionContext.getRequest();
     request.getParameter(arg0);
     request.getParameterValues(arg0);
    
  3. 使用接口注入方式

    Action类实现ServletRequestAware接口,设置setServletRequest方法来得到一个HttpServletRequest对象

在action中操作域对象

通过ServletActionContext来获取域对象

通过setAttribute方法来操作域对象

使用struts封装的方式获取数据

属性封装

直接把表单提交属性封装到Actiond的属性里面

由于直接封装到实体类中比较麻烦,先生成user的get/set方法,同时提交的表单的name要为user.name这种格式

因此又提供了模型驱动封装

注意:模型封装和属性驱动封装不能够同时使用

如果都用,那么属性封装无法得到值,模型驱动可以

框架底层是通过内省的方式实现的

实现步骤

  1. 在action成员变量位置定义变量,变量名和表单输入项的name要一样,一般是private

  2. 生成这些变量的get/set方法

  3. 提交数据到action中时,会自动封装到这些成员变量

模型驱动封装(开发中常用)

可以把数据直接封装到对象里面,前提条件是实体类中的属性值的名字和表单输入项的name要一样

实现步骤

  1. Action实现接口ModelDriven

  2. 实现接口里面的getModel方法,把创建对象返回

  3. 在Action里面创建实体类对象

     public class Test extends ActionSupport implements ModelDriven<User>{
    
         private User user;
    
         @Override
         public User getModel() {
             return user;
         }
     }
    

表达式封装

有时候也把表达式封装分类为属性封装

注意在form表单中的name值user.username的user要与action里的private User user一样 user.username的username要在User里面有同名属性且提供get/set

使用表达式封装和模型驱动封装都可以把数据封装到实体类对象里面。

使用模型驱动封装只能封装到一个实体类对象,使用表达式封装可以将数据封装到多个实体类对象中。 例如下面的代码

实现步骤

  1. 在action里声明实体类

  2. 生成实体类变量的get/set方法

  3. 在表单输入项的names属性值里面写表达式

     private User user;
     private Book book;
    
     //必须要有get
     public User getUser() {
         return user;
     }
    
     public void setUser(User user) {
         this.user = user;
     }
        
     public User getBook() {
         return book;
     }
    
     public void setBook(Book book) {
         this.book = book;
     }
    
     <input type="text" name="user.username">
     <input type="password" name="user.password">
     <input type="text" name="book.name">
    

封装数据到集合中

  1. 封装到List

     private List<User> list;
     //get/set方法
    
     <input type="text" name="list[0].username">
     <input type="number" name="list[0].age">
     <input type="text" name="list[1].username">
     <input type="number" name="list[1].age">
    
  2. 封装到Map(用的比较少)

    步骤,和封装到list相似

    声明map集合变量

    生成get/set方法

    在表单输入项的name属性值里面写表达式

     private Map<String,User> map;
     //get/set方法
    
     <input type="text" name="map['one'].username">
     <input type="number" name="map['one'].age">
     <input type="text" name="map['a'].username">
     <input type="number" name="map['a'].age">