Struts的封装方法、注入方式详解

访问Servlet的API的方式

在使用Struts2的框架过程中,发现Strusts和Servlet的API是解耦合的,在实际开发过程中,会经常使用到Servlet的API,例如登录,将用户信息保存到Session中,有时想页面输出一些内容,用到response对象,涉及Sservet的API的访问

完全解耦合

这种方式只能获取request、session、application的数据的Map集合,无法操作这些对象的本身的方法。
代码:
jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
    <form action="${pageContext.request.contextPath}/login.action" method="post">
      用户名:<input type="text" name = "userName"/><br>
      密码:<input type="password" name = "password"/><br>
      <input type="submit" value="登录">
    </form>
  </body>
</html>

编写核心过滤器(web.xml)

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!--配置核心过滤器-->
    <filter>
        <filter-name>struts</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>struts</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

Login.Class

package net.zjitc;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import java.util.Map;
/**
 * 完全解耦合的方式访问Servlet的API
 * @version 1.0
 * @autho ban
 * @date 2019/4/15 12:26
 */
public class Login extends ActionSupport {
    @Override
    public String execute() throws Exception{
        //接收参数,完全解耦合的方式是看不到request对象。
        //利用Strusts中的对象ActionContext对象
        ActionContext context = ActionContext.getContext();
        //调用AcionContext中的方法
        Map<String, Object> map = context.getParameters();
        //通过map获取数据
        for ( String key : map.keySet()){
            String [] values = (String[]) map.get(key);
            System.out.println(key + ":" + Arrays.toString(values));
        }
        return NONE;
    }
}

struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
	"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <package name="login" extends="struts-default" namespace="/">
        <action name="login" class="net.zjitc.Login">
		</action>
	</package>
</struts>

向域中的对象保存数据

Action类的编写

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import java.util.Arrays;
import java.util.Map;
/**
 * 完全解耦合的方式访问Servlet的API
 * @version 1.0
 * @autho ban
 * @date 2019/4/15 12:26
 */
public class Login extends ActionSupport{
    @Override
    public String execute() throws Exception{
        //接收参数,完全解耦合的方式是看不到request对象的。
        //获取ActionContext的实例
        ActionContext context = ActionContext.getContext();
        //调用AcionContext中的getParameters()方法,类似与request的getParameterMap()方法
        Map<String, Object> map = context.getParameters();
        //通过map获取数据
        for ( String key : map.keySet()){
            String [] values = (String[]) map.get(key);
            System.out.println(key + ":" + Arrays.toString(values));
        }

        //向域对象保存数据
        //相当于request.setArrribute();
        context.put("reqName","reqValue");
        //相当于session.setArribute();
        context.getSession().put("sessName","sessValue");
        //相当于Applicateion.setArribute();
        context.getApplication().put("appName","appValue");
        return SUCCESS;
    }
}

hello.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>数据:</h1>
${reqName}
${sessName}
${appName}
</body>
</html>

原生(推荐使用)

这种方式可以获取request、session、application的数据的Map集合,也可以操作这些对象的本身的方法。
Action类的编写

import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.ServletActionContext;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Map;
/**
 * 原生的方式访问Servlet的API
 * @version 1.0
 * @autho ban
 * @date 2019/4/15 12:26
 */
public class Login extends ActionSupport{
    @Override
    public String execute() throws Exception{
        //接收参数,完全解耦合的方式是看不到request对象的。
        //通过ServletActionContext获取request对象。
        HttpServletRequest request = ServletActionContext.getRequest();
        Map<String, String[]> map = request.getParameterMap();
        //通过map获取数据
        for ( String key : map.keySet()){
            String [] values = (String[]) map.get(key);
            System.out.println(key + ":" + Arrays.toString(values));
        }
        return NONE;
    }
}

向域对象中保存数据

import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.ServletActionContext;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Map;
/**
 * 原生的方式访问Servlet的API
 * @version 1.0
 * @autho ban
 * @date 2019/4/15 12:26
 */
public class Login extends ActionSupport{
    @Override
    public String execute() throws Exception{
        //接收参数,完全解耦合的方式是看不到request对象的。
        //通过ServletActionContext获取request对象。
        HttpServletRequest request = ServletActionContext.getRequest();
        Map<String, String[]> map = request.getParameterMap();
        //通过map获取数据
        for ( String key : map.keySet()){
            String [] values = (String[]) map.get(key);
            System.out.println(key + ":" + Arrays.toString(values));
        }
        //向域对象中保存数据
        //向request中保存数据
        request.setAttribute("reqName","reqValue");
        //向Session中保存数据
        request.getSession().setAttribute("sessName","sessValue");
        //向Application中保存数据
        ServletActionContext.getServletContext().setAttribute("appName","appValue");
        return SUCCESS;
    }

接口注入

Action类的编写

import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.interceptor.ServletRequestAware;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Map;
/**
 * 接口注入的方式访问Servlet的API,首先要你的Action类实现ServletRequestAware接口
 * @version 1.0
 * @autho ban
 * @date 2019/4/15 12:26
 */
public class Login extends ActionSupport implements ServletRequestAware {

    private HttpServletRequest request;

    @Override
    public String execute() throws Exception{
        //接收参数,完全解耦合的方式是看不到request对象的。
        //通过ServletActionContext获取request对象。
        Map<String, String[]> map = request.getParameterMap();
        //通过map获取数据
        for ( String key : map.keySet()){
            String [] values = (String[]) map.get(key);
            System.out.println(key + ":" + Arrays.toString(values));
        }
        return super.execute();
    }

    @Override
    public void setServletRequest(HttpServletRequest httpServletRequest) {
        this.request = request;
    }
}

向域中对象保存数据

import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.util.ServletContextAware;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Map;
/**
 * 接口注入的方式访问Servlet的API,首先要你的Action类实现ServletRequestAware接口
 * @version 1.0
 * @autho ban
 * @date 2019/4/15 12:26
 */
public class Login extends ActionSupport implements ServletRequestAware, ServletContextAware {

    private HttpServletRequest request;
    private ServletContext context;

    @Override
    public String execute() throws Exception{
        //接收参数,完全解耦合的方式是看不到request对象的。
        //通过ServletActionContext获取request对象。
        Map<String, String[]> map = request.getParameterMap();
        //通过map获取数据
        for ( String key : map.keySet()){
            String [] values = (String[]) map.get(key);
            System.out.println(key + ":" + Arrays.toString(values));
        }
        //向域对象中保存数据
        //向request中保存数据
        request.setAttribute("reqName","reqValue");
        //向Session中保存数据
        request.getSession().setAttribute("sessName","sessValue");
        //向Application中保存数据,需要这个类实现ServletContextAware接口
        context.setAttribute("appName","appValue");
        return super.execute();
    }

    @Override
    public void setServletRequest(HttpServletRequest httpServletRequest) {
        this.request = request;
    }

    @Override
    public void setServletContext(ServletContext context) {
        this.context = context;
    }
}

Servlet是单例的,多个程序访问同一个Servelt只会创建一个Servlet实例。Action是多例的,不存在线程安全问题。

结果页面的配置

全局结果页面

  • 什么是全局结果页面
    一个包(package)下的所有Action的页面跳转都有效
  • 全局结果页面的配置(< global-results>标签)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
	"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <package name="login" extends="struts-default" namespace="/">
		<global-results>
			<result>/hello.jsp</result>
		</global-results>
        <action name="login" class="net.zjitc.Login"></action>
	</package>
</struts>

局部结果页面

  • 什么是局部结果页面
    只在当前Action中的页面跳转有效
  • 局部结果页面的配置(在< action>标签下配置)
<action name="login" class="net.zjitc.Login">
    <result>/hello.jsp</result>
</action>

关于result标签

result标签用于配置页面的跳转,

属性名作用
name逻辑视图的名称,默认值为“success"
type页面跳转的类型

有哪些页面跳转的类型呢?
你可以在struts的jar包中的根目录下的default.properties文件中找到<package name="struts-default" abstract="true">下的<result-types>标签。这个标签定义了页面跳转的类型。
在这里插入图片描述

数据封装

User.java

import java.util.Date;
public class User {
    private String username;
    private String password;
    private Date birthday;
    private int age;
    //创建每个属性的get和set方法
}

struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
	"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <package name="user" extends="struts-default" namespace="/">
        <action name="userAction" class="net.zjitc.action.UserAction"></action>
	</package>
</struts>

属性驱动

提供属性set方法

这种方法在修改单个属性数据时可能会使用到,一般情况下不常用。
index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
    <form action="${ pageContext.request.contextPath }/userAction.action" method="post">
      用户名:<input type="text" name = "username"/><br>
      密码:<input type="password" name = "password"/><br>
      出生日期:<input type="date" name="birthday"><br>
      年龄:<input type="text" name="age"><br>
      <input type="submit" value="注册">
    </form>
  </body>
</html>

userAction.java

import com.opensymphony.xwork2.ActionSupport;
import java.util.Date;
public class UserAction extends ActionSupport {
    private String username;
    private String password;
    private Date birthday;
    private int age;

    @Override
    public String execute() throws Exception {
        //接收数据
        System.out.println(username);
        System.out.println(password);
        System.out.println(birthday);
        System.out.println(age);
        //封装数据
        return NONE;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public void setPassword(String password) {
        this.password = password;
    }
}

页面中提供表达式

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
    <form action="${ pageContext.request.contextPath }/userAction.action" method="post">
      用户名:<input type="text" name="user.username"/><br>
      密码:<input type="password" name="user.password"/><br>
      出生日期:<input type="date" name="user.birthday"><br>
      年龄:<input type="text" name="user.age"><br>
      <input type="submit" value="注册">
    </form>
  </body>
</html>

userAction.java

public class UserAction extends ActionSupport {
    //提供一个对象,并提供该对象的set和get方法,其中必须要有get方法
    private User user;
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
    @Override
    public String execute() throws Exception {
        System.out.println(user);
        return NONE;
    }
}

这种封装方法,是由拦截器来完成数据的封装,拦截器需要创建一个对象,通过get方法获得同一个对象,将获得的对象封装到创建的对象中,这也是为什么必须要提供对象的get方法。
这种封装方法,可以同时向多个对象封装数据。
注意:jsp中的<inpu>标签的name的格式是固定的 对象名.属性名 对象名代表的是我们提供的对象,属性名则是对象中存在的属性,这些要一一对应

模型驱动

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
    <form action="${ pageContext.request.contextPath }/userAction.action" method="post">
      用户名:<input type="text" name = "username"/><br>
      密码:<input type="password" name = "password"/><br>
      出生日期:<input type="date" name="birthday"><br>
      年龄:<input type="text" name="age"><br>
      <input type="submit" value="注册">
    </form>
  </body>
</html>

UserAction.java

public class UserAction extends ActionSupport implements ModelDriven<User> {
    //提供对象
    private User user;
    //实例化对象
    public UserAction() {
        user = new User();
    }
    //模型驱动需要使用的方法
    @Override
    public User getModel() {
        return user;
    }

    @Override
    public String execute() throws Exception {
        System.out.println(user);
        return NONE;
    }
}

这种方法,只要实现一个ModelDriven接口就行可以了,但只能向一个对象封装数据。在实际开发中这种中方式最常用。

复杂数据的封装

封装到List集合中

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
  <form action="${pageContext.request.contextPath}/productAction.action" method="post">
    物品名称:<input type="text" name="products[0].name">&nbsp;&nbsp;&nbsp;
    物品价格:<input type="text" name="products[0].price"><br>
    
    物品名称:<input type="text" name="products[1].name">&nbsp;&nbsp;&nbsp;
    物品价格:<input type="text" name="products[1].price"><br>
    
    物品名称:<input type="text" name="products[2].name">&nbsp;&nbsp;&nbsp;
    物品价格:<input type="text" name="products[2].price"><br>
    
    物品名称:<input type="text" name="products[3].name">&nbsp;&nbsp;&nbsp;
    物品价格:<input type="text" name="products[3].price"><br>
    
    物品名称:<input type="text" name="products[4].name">&nbsp;&nbsp;&nbsp;
    物品价格:<input type="text" name="products[4].price"><br>
    <input type="submit" value="提交">
  </form>
  </body>
</htm

<input>的name属性名格式是固定的 List名称[组序号].属性名 "组序号”必须是数字,"List名称"要与Action类中提供的List名一致

<struts>
    <package name="product" extends="struts-default" namespace="/">
        <action name="productAction" class="action.ProductAction"></action>
    </package>
</struts>

Product.java

/**
 * 商品实体类
 * @version 1.0
 * @autho ban
 * @date 2019/4/16 9:45
 */
public class Product {
    private String name;
    private Double price;
    public String getName() {return name;}
    public void setName(String name) { this.name = name;}
    public double getPrice() {return price; }
    public void setPrice(double price) {this.price = price;}
    @Override
    public String toString() {
        return "Product{" +
                "name='" + name + '\'' +
                ", price=" + price +
                '}';
    }
}

ProductAction.java

import com.opensymphony.xwork2.ActionSupport;
import domain.Product;
import java.util.List;
/**
 * 将数据封装到List集合中
 * @version 1.0
 * @autho ban
 * @date 2019/4/16 9:43
 */
public class ProductAction extends ActionSupport {
    private List<Product> products;
    // 提供集合的set和get方法:
    public void setProducts(List<Product> products) {this.products = products;}
    public List<Product> getProducts() {return products;}
    @Override
    public String execute() throws Exception {
        if (products.isEmpty()){
            System.out.println("Sorry,products list is Null!");
        }else {
            for (Product product : products) {
                System.out.println(product);
            }
            System.out.println("OK,No error!");
        }
        return NONE;
    }
}

封装到Map集合中

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
  <form action="${pageContext.request.contextPath}/productAction.action" method="post">
    物品名称:<input type="text" name="map['one'].name">&nbsp;&nbsp;&nbsp;
    物品价格:<input type="text" name="map['one'].price"><br>
    物品名称:<input type="text" name="map['two'].name">&nbsp;&nbsp;&nbsp;
    物品价格:<input type="text" name="map['two'].price"><br>
    物品名称:<input type="text" name="map['three'].name">&nbsp;&nbsp;&nbsp;
    物品价格:<input type="text" name="map['three'].price"><br>
    物品名称:<input type="text" name="map['four'].name">&nbsp;&nbsp;&nbsp;
    物品价格:<input type="text" name="map['four'].price"><br>
    物品名称:<input type="text" name="map['five'].name">&nbsp;&nbsp;&nbsp;
    物品价格:<input type="text" name="map['five'].price"><br>
    <input type="submit" value="提交">
  </form>
  </body>
</html>

ProductAcion.java

import com.opensymphony.xwork2.ActionSupport;
import domain.Product;
import java.util.Map;
/**
 * 将数据封装到Map集合中
 * @version 1.0
 * @autho ban
 * @date 2019/4/16 9:43
 */
public class ProductAction extends ActionSupport {
    private Map<String,Product> map;

    public Map<String, Product> getMap() {return map;}
    public void setMap(Map<String, Product> map) {this.map = map;}

    @Override
    public String execute() throws Exception {
        if (map.isEmpty()){
            System.out.println("Sorry,map is Null!");
        }else {
            for (String key : map.keySet()) {
                Product product = map.get(key);
                System.out.println(key + ":" + product);
            }
            System.out.println("OK,No error!");
        }
        return NONE;
    }
}

注意:无论是LIst还是Map都需要set和get方法

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值