在学习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