Struts2 框架的意义
• 更便捷的开发
1.自动封装表单提交数据:属性驱动、模型驱动
属性驱动:表单中提交的数据,无需 request.getparameter 方法,数据自动置于属性之中,可以直接使用。
模型驱动:表单提交的数据提交到实体类对象之中,只需调用类方法就可以将数据持久化到数据库之中。
极大地提高了效率和简洁性。
2.便捷的实现上传文件:FileUpload
3.使网站通用于国内外:国际化(实现国际通用标准)
4.通过配置完成表单验证:校验器
表单校验分为两块:(1)JS页面通过JS语句实现一次校验;(2)数据随后传到后台,后台进行二次校验,后台可通过配置文件的方式完成,十分规范。
1.安全的线程机制:每个action都是独立的
JSP 采用 Servlet 开发时,Servlet 是单例模式,线程并不安全,为避免线程混乱,Struts2 的 action 对每一个请求都会产生一个实例,因此,线程安全。
2.防止数据重复提交:token令牌机制
1.面向切面编程:拦截器
页面提交注册 regist.action 请求,Servlet_A 接收注册请求,并将请求转发到注册页面,在注册页面填写好了注册信息之后,点击注册按钮,将消息提交给 Servlet_B,Servlet_B 对用户信息进行验证并保存到数据库,最终跳转到注册成功页面。
注册功能流程图,传统的 Struts2 开发的模式
页面提交注册 regist.action 请求,通过过滤器实现验证、判断和拦截,根据请求的不同跳转至相应页面,比如,注册成功页面。注册信息填写完毕之后,点击提交按钮,数据通过同一过滤器实现拦截和验证,最终,将数据保存到数据库,并跳转到注册成功页面。
换言之,之前的核心控制器 Servlet 被 过滤器给替换掉了。
采用 Struts2 实现 过滤器 的 步骤
XML配置入口页面和过滤器
过滤器由Java编写跳转逻辑
JSP 文件实现 页面表单和按钮 等
• 更便捷的开发
1.自动封装表单提交数据:属性驱动、模型驱动
属性驱动:表单中提交的数据,无需 request.getparameter 方法,数据自动置于属性之中,可以直接使用。
模型驱动:表单提交的数据提交到实体类对象之中,只需调用类方法就可以将数据持久化到数据库之中。
极大地提高了效率和简洁性。
2.便捷的实现上传文件:FileUpload
3.使网站通用于国内外:国际化(实现国际通用标准)
4.通过配置完成表单验证:校验器
表单校验分为两块:(1)JS页面通过JS语句实现一次校验;(2)数据随后传到后台,后台进行二次校验,后台可通过配置文件的方式完成,十分规范。
5.强大的标签库:Struts2标签库、OGNL标签库
(此外,EL表达式与JSTL表达式也可以使用。)
• 更科学的管理
1.使用xml文件管理程序文件对应关系
• 更安全的操作1.安全的线程机制:每个action都是独立的
JSP 采用 Servlet 开发时,Servlet 是单例模式,线程并不安全,为避免线程混乱,Struts2 的 action 对每一个请求都会产生一个实例,因此,线程安全。
2.防止数据重复提交:token令牌机制
防止因为网络或者别的原因,数据重复提交。
3.异常处理机制:通过配置来完成,更便于管理
• 先进的编程思路1.面向切面编程:拦截器
拦截器是过滤器的高级实现,遵从 DRY 规则,即 Donot Repeat Yourself,拦截器可以软性的加入代码,避免代码重复,实现更高层次的解耦。自动封装、上传文件、数据校验与转换都是基于拦截器实现的。
采用 Servlet 和 Struts2 实现注册功能流程图
注册功能流程图,传统的 Servlet 开发的模式页面提交注册 regist.action 请求,Servlet_A 接收注册请求,并将请求转发到注册页面,在注册页面填写好了注册信息之后,点击注册按钮,将消息提交给 Servlet_B,Servlet_B 对用户信息进行验证并保存到数据库,最终跳转到注册成功页面。
注册功能流程图,传统的 Struts2 开发的模式
页面提交注册 regist.action 请求,通过过滤器实现验证、判断和拦截,根据请求的不同跳转至相应页面,比如,注册成功页面。注册信息填写完毕之后,点击提交按钮,数据通过同一过滤器实现拦截和验证,最终,将数据保存到数据库,并跳转到注册成功页面。
换言之,之前的核心控制器 Servlet 被 过滤器给替换掉了。
采用 Struts2 实现 过滤器 的 步骤
XML配置入口页面和过滤器
过滤器由Java编写跳转逻辑
JSP 文件实现 页面表单和按钮 等
package filt_Pack_001;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import strus_Pack_001.MyUser;
public class Ctrl_Filter_Cls_001 implements Filter {
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1,
FilterChain arg2) throws IOException, ServletException {
// TODO Auto-generated method stub
// 获取 HttpServletRequest 对象
HttpServletRequest hsr = (HttpServletRequest)arg0;
// 1 接收用户请求的地址
String url = hsr.getServletPath();
// 2 判断用户请求的地址,并执行相应的程序
// 在过滤器中编写跳转 需要有返回 return
if(url.equals("/hsr.action")){
// 如果接收到的请求是注册的,就跳转到注册界面
hsr.getRequestDispatcher("register.jsp").forward(arg0, arg1);;
return;
}else if (url.equals("/saveUser.action")) {
// 获取表单数据
String username = hsr.getParameter("username");
String pwd0 = hsr.getParameter("pw0");
String pwd1 = hsr.getParameter("pw1");
// 验证密码的一致性
if(pwd0.equals(pwd1)){
// 相等则封装到 user 对象之中去
MyUser us = new MyUser();
us.setUsernameString(username);
us.setPassword(pwd1);
// 执行 相关 DAO 持久化操作
// 注册成功就跳转到注册成功页面
hsr.getRequestDispatcher("end.jsp").forward(arg0, arg1);
// 在过滤器中编写跳转 需要有返回 return
return;
}
else {
// 如果跳转不成功 就返回原来的注册页面
hsr.getRequestDispatcher("register.jsp").forward(arg0, arg1);
return;
}
}
// 3 跳转到相应的结果页面 ,让过滤器执行 以完成核心过滤器的执行
arg2.doFilter(arg0, arg1);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}
package strus_Pack_001;
public class MyUser {
private int id;
private String username;
private String password;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsernameString() {
return username;
}
public void setUsernameString(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<filter>
<filter-name>Ctrl_Filter_Cls_001</filter-name>
<filter-class>filt_Pack_001.Ctrl_Filter_Cls_001</filter-class>
</filter>
<filter-mapping>
<filter-name>Ctrl_Filter_Cls_001</filter-name>
<!-- 配置过滤器 过滤掉所有的请求 -->
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
<h3> 恭喜您注册成功! </h3>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=utf-8"
import = "java.util.*"
pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
</head>
<body>
<!-- 链接 为 register。action -->
<a href="hsr.action">注册</a>
</body>
</html>
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
<!-- 编写表单数据 -->
<form action="saveUser.action" method="post">
<input type="text" name="username">
<input type="password" name="pw0">
<input type="password" name="pw1">
<input type="submit" value="提交">
</form>
</body>
</html>