SSH学习-Struts2消息传递机制

在学习Struts2的过程中,有消息传递机制的概念,所谓消息传递,就是指浏览器和服务器之间的数据传递,包含浏览器从服务器获取数据,以及服务器接受浏览器发送的数据两部分。在Struts2中,浏览器获取服务端的数据,需要使用EL表达式。而服务器要接受浏览器发送的数据,有两种方式,一种是基本属性传递方式,另一种是域模型传递方式。接下来使用'Hello Struts2'和注册的业务,来简单的学习Struts2的消息传递机制。

浏览器从服务端获取数据

要实现浏览器从服务器获取数据,需要实现以下几步:

step1 在控制器中增加属性,并添加get方法

step2 在控制器execute方法中给属性赋值

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">
    
<!-- dtd文件导入的作用:决定了xml文件可以使用什么标签 -->    
   
<!-- struts根标签,其他还有比较常用的package,action,result等子标签 -->    
<!-- package标签,name属性用处不是很大,namespace代表匹配请求路径,extends类似Java继承,继承struts-default.xml -->
<!-- action标签,name代表请求路径,class为处理请求的类,会返回一个String类型结果,给result标签使用 -->
<!-- result标签,name属性值就是action返回的String名字,作用是返回结果处理 -->
<struts>
  <package name="demo" namespace="/hello" extends="struts-default">
    <!-- 没写具体方法时,默认执行类里名字为execute的方法,如果在action里配置method="",就读取对应的自定义方法 -->
    <action name="helloStruts" class="com.boe.Filter.Hello"> 
       <!-- result属性值配置name属性的话,就是默认进行转发,如果是其他的,需要配置 -->
       <result name="success">
         /WEB-INF/helloStruts.jsp
       </result>
    </action>
  </package>  
  
</struts>    

控制器中添加了属性message:

package com.boe.Filter;

/**
 * 处理类
 * @author yangchaolin
 */
public class Hello {
    
    //测试浏览器从服务器获取数据,增加一个属性,并配置get方法
    String message;
        
    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    //写默认execute方法
    public String execute() {
        System.out.println("success");
        //给属性赋值
        message="hello my struts2";
        System.out.println(message);
        return "success";
    }

}

step3 JSP中通过EL表达式获取属性message的值,底层其实调用了get方法来获取属性值,因此第一步需要给控制器属性添加get方法。

<%@page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>第一个struts程序</title>
</head>
<body style="font-family:'微软雅黑';font-size:20px;">
     <h1>Hello Struts2</h1>
     <!-- 使用EL表达式从服务端获取数据 -->
     <h1>${message}</h1>
</body>
</html>

测试结果

网页端:

控制台:

由于在控制器中添加了message属性,并设置了get方法,在execute方法中进行了赋值,jsp中通过EL表达式就可以获取message的内容'hello my struts2',其中使用EL表达式不需要导包,但是使用JSTL表达式时需要导包,并在JSP中配置标签库,不能搞混了。

服务端接受浏览器发送的数据

前面介绍有两种方式可以获取,两种方式没有优劣之分,只是在不同的业务场景需求下有不同的应用。接下来使用两种方式,来获取浏览器发送的数据,实现模拟登录。

(1)基本属性提交方式

实现基本属性提交方式,按照如下步骤来实现:

step1 在控制器中声明,与form表单name属性名一致的bean属性,就是form表单中提交的数据对应的name属性值,需要和控制器中的bean属性名一致

JSP中form表单配置:

<%@page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>基本属性提交方式-登录</title>
</head>
<body style="font-family:'微软雅黑';font-size:20px;">
    <!-- 使用JSTL标签 -->
    <!-- 标签的作用主要用来产生字符串类型的url-->
    <!-- 另外还有一个问题,如果在注释里写了c标签,不加引号,编译会提示标签未结束 -->
    <c:url var="url" value="/login/login.action"></c:url>
    <form action="${url}" method="post"><!-- 使用url标签,路径会默认在前面加上项目名,否则action里写路径就需要加上项目名 -->
       <div>
         <label>用户名:</label>
         <input type="text" name="username" />
       </div>
       <div>
         <label>密码:</label>
         <input type="password" name="password" />
       </div>
       <div>
         <input type="submit" value="登录" />
       </div>
    </form>
</body>
</html>

struts.xml中添加进入登录页面和提交表单的配置:

<!-- 登录,提交用户名和密码,采用基本属性提交方式 -->
  <package name="login" namespace="/login" extends="struts-default">
    <!-- 进入登录页面,没有业务逻辑处理 -->
    <action name="toLogin">
      <result name="success">
        /WEB-INF/login.jsp
      </result>
    </action> 
    <!-- 验证用户名和密码 -->
    <action name="login" class="com.boe.Filter.Login">
      <result name="success">
        /WEB-INF/msg.jsp
      </result>
    </action>
  </package>

step2 控制器中针对bean属性,增加set方法,增加set方法的作用是可以将传递的参数注入到bean属性

package com.boe.Filter;

/**
 * 获取登录提交的参数,采用基本类型传递方式
 * @author yangchaolin
 *
 */
public class Login {
    
    //bean属性名字必须和form中的name属性值一致
    String username;
    String password;
    
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    
    //execute方法
    public String execute() {
        //测试能否获取浏览器发送过来的数据
        System.out.println(username+":"+password);
        return "success";
    }

}

step3 struts2接收到浏览器发送的数据后,会自动将表单数据注入到bean属性中,JSP中可以使用EL表达式直接获取bean属性值

<%@page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>获取登录后结果</title>
</head>
<body style="font-family:'微软雅黑';font-size:20px;">
     <h1>Hello Struts2</h1>
     <!-- 使用EL表达式从服务端获取数据 -->
     <h2>"Hello!" ${username},采用基本属性方式</h2><!-- 使用基本属性提交的方式 -->
</body>
</html>

测试结果

网页显示:

控制台输出:

如图可看出,服务端能正常获取基本类型方式提交的数据。

(2)域模型方式提交

所谓域模型传递方式,其实跟以前SpringMVC的javabean方式获取参数类似,将浏览器的参数,根据名称set到实体类中。然后服务端从实体类中get属性值,后面再做逻辑判断。在处理发送重复数据时,优点明显,可以减少代码重用。以下为步骤:

当浏览器发送数据到服务端后,采用域模型的方式,值首先会注入到实体类中,后面控制器可以调用实体类属性值,当然这样会存在多个控制器可以共享实体类数据的情况,可能会导致数据不安全。

step1 对表单元素进行封装,生成实体类

package com.boe.Entity;
/**
 * 用户登录实体类,使用域模型传递方式
 * @author yangchaolin
 */
public class User {
    //属性名需要和form表单中的name属性值一致
   String username;
   String password;
   
    ...省略get set方法
    
    @Override
    public String toString() {
        return "User [username=" + username + ", password=" + password + "]";
    }
          
}

step2 在控制器中增加实体类属性

step3 对实体类属性添加set方法

step4 实现对象属性的注入

package com.boe.Filter;

import com.boe.Entity.User;

public class LoginWithEntity {
    
    private User user;
    
    //创建get set方法
    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }
    
    //默认execute方法
    public String execute() {
        //测试域模型传递方式
        System.out.println(user);
        return "success";
    }

}

struts.xml和JSP文件的配置省略,可以参考第一次的配置,做下修改即可。但是需要注意的是,JSP文件中EL表达式不能只写username和password,还需要写上控制器中声明的bean属性名user,因此完整写法为user.username和user.password。

测试结果

网页端显示:

控制台输出:

可以看出,采用域模型,服务端也可以获取浏览器发送的数据。

结论

(1)struts2消息传递就是指浏览器和服务端之间的数据传递

(2)浏览器获取服务端的数据使用EL表达式

(3)服务端获取浏览器发送数据,可以采用基本类型传递和域模型传递的方式

原文地址:https://www.cnblogs.com/youngchaolin/p/10805316.html