其实学习框架,就是为了可以很好的很快的完成我们的需求,而学习struts2只是为了替代之前用的servlet这一层,框架使开发更加简单,所以作为一个小菜鸟,特别感谢那些超级无敌变态开发的框架供我们使用,当然说那些使超级无敌变态并不是说他们很变态,是他们的思想太强大了。
言归正传,这次使用的拦截器是struts2框架的核心之处,希望学习struts2框架的小伙伴重视起来哦。一起共勉。
1:第一步依旧是导包哦,使用别人的框架,第一步,就记住导入自己使用的核心包即可。
2:配置web.xml过滤器,这些都是死东西,记住会写即可。
1 <?xml version="1.0" encoding="UTF-8"?>
2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
3 <display-name>struts2_login20170307</display-name>
4 <welcome-file-list>
5 <welcome-file>index.html</welcome-file>
6 <welcome-file>index.htm</welcome-file>
7 <welcome-file>index.jsp</welcome-file>
8 <welcome-file>default.html</welcome-file>
9 <welcome-file>default.htm</welcome-file>
10 <welcome-file>default.jsp</welcome-file>
11 </welcome-file-list>
12
13 <!-- 引入struts2的核心过滤器 -->
14 <filter>
15 <!-- 过滤器的名称 -->
16 <filter-name>struts2</filter-name>
17 <!-- 过滤器类 -->
18 <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
19 </filter>
20 <filter-mapping>
21 <!-- 过滤器名称 -->
22 <filter-name>struts2</filter-name>
23 <!-- 过滤器映射 -->
24 <url-pattern>/*</url-pattern>
25 </filter-mapping>
26 </web-app>
3:第三步,想要登陆就必须设计号数据表,当然你首先要设计好数据库。字段如下所示:
4:设计好数据表之后就可以创建实体类User.java,源码如下所示:
1 package com.bie.po;
2
3 import java.io.Serializable;
4
5 /**
6 * @author BieHongLi
7 * @version 创建时间:2017年3月5日 上午9:40:09
8 *
9 */
10 public class User implements Serializable{
11
12 private static final long serialVersionUID = 1L;
13 private Integer id;
14 private String name;
15 private String password;
16 private String email;
17 private String phone;
18 public Integer getId() {
19 return id;
20 }
21 public void setId(Integer id) {
22 this.id = id;
23 }
24 public String getName() {
25 return name;
26 }
27 public void setName(String name) {
28 this.name = name;
29 }
30 public String getPassword() {
31 return password;
32 }
33 public void setPassword(String password) {
34 this.password = password;
35 }
36 public String getEmail() {
37 return email;
38 }
39 public void setEmail(String email) {
40 this.email = email;
41 }
42 public String getPhone() {
43 return phone;
44 }
45 public void setPhone(String phone) {
46 this.phone = phone;
47 }
48 @Override
49 public String toString() {
50 return "User [id=" + id + ", name=" + name + ", password=" + password + ", email=" + email + ", phone=" + phone
51 + "]";
52 }
53
54
55 }
5:完成了实体类,就可以如以前学习的那样,写dao层,service层,当然servlet层被action层替换了。这里先写dao层吧,首先创建工具类BaseDao.java,源码如下所示:
package com.bie.dao;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ResourceBundle;
/**
* @author BieHongLi
* @version 创建时间:2017年3月5日 上午9:32:14
* 数据交互层dao层
*/
public class BaseDao {
private static String driver="com.mysql.jdbc.Driver";
private static String url="jdbc:mysql:///test";
private static String user="root";
private static String password="123456";
/***
* 连接数据库的方法
* @return
* @throws ClassNotFoundException
* @throws SQLException
*/
public static Connection getCon() throws ClassNotFoundException, SQLException{
Class.forName(driver);//加载数据库驱动
System.out.println("测试加载数据库成功");
Connection con=DriverManager.getConnection(url, user, password);
System.out.println("测试数据库链接成功");
return con;
}
/***
* 关闭数据库的方法
* @param con
* @param ps
* @param rs
*/
public static void close(Connection con,PreparedStatement ps,ResultSet rs){
if(rs!=null){//关闭资源,避免出现异常
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(ps!=null){
try {
ps.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(con!=null){
try {
con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/***
* 同意增删改的方法
* @param sql
* @param arr
* @return
*/
public static boolean addUpdateDelete(String sql,Object[] arr){
Connection con=null;
PreparedStatement ps=null;
try {
con=BaseDao.getCon();//第一步 :连接数据库的操作
ps=con.prepareStatement(sql);//第二步:预编译
//第三步:设置值
if(arr!=null && arr.length!=0){
for(int i=0;i<arr.length;i++){
ps.setObject(i+1, arr[i]);
}
}
int count=ps.executeUpdate();//第四步:执行sql语句
if(count>0){
return true;
}else{
return false;
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
public static void main(String[] args) {
try {
BaseDao.getCon();
System.out.println("测试数据库链接成功");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
6:建议再创建一个工具类,过滤编码的UTFFilter.java
1 package com.bie.dao;
2
3 import java.io.IOException;
4
5 import javax.servlet.Filter;
6 import javax.servlet.FilterChain;
7 import javax.servlet.FilterConfig;
8 import javax.servlet.ServletException;
9 import javax.servlet.ServletRequest;
10 import javax.servlet.ServletResponse;
11 import javax.servlet.annotation.WebFilter;
12 import javax.servlet.http.HttpServletRequest;
13
14 /**
15 * @author BieHongLi
16 * @version 创建时间:2017年2月21日 上午11:08:49
17 *
18 */
19 @WebFilter("/*")
20 public class UTFFilter implements Filter{
21
22 @Override
23 public void destroy() {
24 // TODO Auto-generated method stub
25
26 }
27
28 @Override
29 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
30 FilterChain filterChain)throws IOException, ServletException {
31 //将servletRequest转发为HttpServletRequest
32 HttpServletRequest request=(HttpServletRequest)servletRequest;
33 request.setCharacterEncoding("utf-8");
34 filterChain.doFilter(servletRequest, servletResponse);
35 }
36
37 @Override
38 public void init(FilterConfig arg0) throws ServletException {
39 // TODO Auto-generated method stub
40
41 }
42
43
44 }
7:接着写service层的接口和实现类;
1 package com.bie.dao;
2
3 import java.util.List;
4
5 import com.bie.po.User;
6
7 /**
8 * @author BieHongLi
9 * @version 创建时间:2017年3月5日 上午9:39:21
10 *
11 */
12 public interface UserDao {
13
14 /***
15 * 登陆的方法
16 * @param user
17 * @return
18 */
19 public User selectLogin(User user);
20
21 /***
22 * 用户查询的方法
23 * @param sql
24 * @param arr
25 * @return
26 */
27 public List<User> selectUser(String sql,Object[] arr);
28 }
1 package com.bie.dao.impl;
2
3 import java.sql.Connection;
4 import java.sql.PreparedStatement;
5 import java.sql.ResultSet;
6 import java.sql.SQLException;
7 import java.util.ArrayList;
8 import java.util.List;
9
10 import com.bie.dao.BaseDao;
11 import com.bie.dao.UserDao;
12 import com.bie.po.User;
13
14 /**
15 * @author BieHongLi
16 * @version 创建时间:2017年3月5日 上午9:39:35
17 *
18 */
19 public class UserDaoImpl implements UserDao{
20
21 @Override
22 public User selectLogin(User user) {
23 Connection con=null;
24 PreparedStatement ps=null;
25 ResultSet rs=null;
26 try {
27 con=BaseDao.getCon();//1:获取数据库的连接
28 //2:书写sql语句
29 String sql="select * from user where name=? and password=? ";
30 ps=con.prepareStatement(sql);//3:预编译
31 //4:设置值
32 ps.setString(1, user.getName());
33 ps.setString(2, user.getPassword());
34 rs=ps.executeQuery();//5:执行sql语句
35 User users;
36 if(rs.next()){
37 users=new User();
38 //从数据库中获取值设置到实体类的setter方法中
39 users.setId(rs.getInt("id"));
40 users.setName(rs.getString("name"));
41 users.setPassword(rs.getString("password"));
42 users.setEmail(rs.getString("email"));
43 users.setPhone(rs.getString("phone"));
44 //user.setIsAdmin(rs.getString("isAdmin"));
45
46 //return user;
47 }
48 } catch (ClassNotFoundException e) {
49 e.printStackTrace();
50 } catch (SQLException e) {
51 e.printStackTrace();
52 }finally{
53 //关闭资源,避免出现异常
54 BaseDao.close(con, ps, rs);
55 }
56 return user;
57 }
58
59 @Override
60 public List<User> selectUser(String sql, Object[] arr) {
61 Connection con=null;
62 PreparedStatement ps=null;
63 ResultSet rs=null;
64 try {
65 con=BaseDao.getCon();//第一步连接数据库
66 ps=con.prepareStatement(sql);//第二步:预编译
67 if(arr!=null){
68 for(int i=0;i<arr.length;i++){
69 ps.setObject(i+1, arr[i]);
70 }
71 }
72 //第四步执行sql
73 rs=ps.executeQuery();
74 List<User> list=new ArrayList<User>();
75 while(rs.next()){
76 User user=new User();
77 user.setId(rs.getInt("id"));
78 user.setName(rs.getString("name"));
79 user.setPassword(rs.getString("password"));
80 user.setEmail(rs.getString("email"));
81 user.setPhone(rs.getString("phone"));
82
83 //System.out.println(user);//测试数据
84 list.add(user);
85 }
86 return list;
87 } catch (ClassNotFoundException e) {
88 e.printStackTrace();
89 } catch (SQLException e) {
90 e.printStackTrace();
91 }finally{
92 //关闭资源,避免出现异常
93 BaseDao.close(con, ps, rs);
94 }
95
96 return null;
97 }
98
99
100 }
8:接着写service层的接口和实现类,接口UserService.java和实现类UserServiceImpl.java;
1 package com.bie.service;
2
3 import java.util.List;
4
5 import com.bie.po.User;
6
7 /**
8 * @author BieHongLi
9 * @version 创建时间:2017年2月23日 下午1:58:59
10 *
11 */
12 public interface UserService {
13
14 /***
15 * 用户查询的信息
16 * @param user
17 * @return
18 */
19 public List<User> selectUser(User user);
20
21 /***
22 * 用户登陆的功能
23 * @param user
24 * @return
25 */
26 public User login(User user);
27 }
1 package com.bie.service.impl;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import com.bie.dao.UserDao;
7 import com.bie.dao.impl.UserDaoImpl;
8 import com.bie.po.User;
9 import com.bie.service.UserService;
10
11 /**
12 * @author BieHongLi
13 * @version 创建时间:2017年2月23日 下午1:59:36
14 *
15 */
16 public class UserServiceImpl implements UserService{
17
18 private UserDao dao=new UserDaoImpl();
19
20 @Override
21 public List<User> selectUser(User user) {
22 //sql语句
23 //String sql="select * from user ";
24 StringBuilder sql=new StringBuilder("select * from user where 1=1 ");
25 List<Object> list=new ArrayList<Object>();
26 if(user!=null){
27 //按照姓名查询
28 if(user.getName()!=null && !user.getName().equals("")){
29 sql.append(" and name = ? ");
30 list.add(user.getName());
31 }
32 //按照email查询
33 if(user.getEmail()!=null && !user.getEmail().equals("")){
34 sql.append(" and email = ? ");
35 list.add(user.getEmail());
36 }
37
38 }
39 return dao.selectUser(sql.toString(), list.toArray());
40 }
41
42
43 @Override
44 public User login(User user) {
45 if(user!=null && user.getName()!=null && user.getPassword()!=null){
46 return dao.selectLogin(user);
47 }
48 return null;
49 }
50
51
52 }
9:开始写登陆页面login.jsp页面和用户信息显示list.jsp页面
1 <%@ page language="java" contentType="text/html; charset=UTF-8"
2 pageEncoding="UTF-8"%>
3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
4 <html>
5 <head>
6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
7 <title>登陆的页面</title>
8 </head>
9 <body>
10
11 <form action="${pageContext.request.contextPath }/user_login.action" method="post">
12 账号:<input type="text" name="user.name"/><br>
13 密码:<input type="password" name="user.password"/><br/>
14 <input type="submit" name="登陆"/>
15
16 </form>
17 </body>
18 </html>
1 <%@ page language="java" contentType="text/html; charset=UTF-8"
2 pageEncoding="UTF-8"%>
3 <%@ taglib prefix="s" uri="/struts-tags"%>
4 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
5 <html>
6 <head>
7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
8 <title>信息列表展示的页面</title>
9 </head>
10 <body>
11
12 <table cellpadding="10" cellspacing="10" align="center">
13 <tr>
14 <th>编号</th>
15 <th>姓名</th>
16 <th>密码</th>
17 <th>邮件</th>
18 <th>电话</th>
19 </tr>
20
21 <s:iterator var="user" value="#request.listUser" status="lu">
22 <tr>
23 <td>
24 <s:property value="#lu.count"/>
25 </td>
26 <td>
27 <s:property value="#user.name"/>
28 </td>
29 <td>
30 <s:property value="#user.password"/>
31 </td>
32 <td>
33 <s:property value="#user.email"/>
34 </td>
35 <td>
36 <s:property value="#user.phone"/>
37 </td>
38 </tr>
39 </s:iterator>
40
41
42 </table>
43
44 </body>
45 </html>
10:登陆页面点击登陆就到了struts.xml页面,struts.xml页面会到action页面,所以现在写struts.xml页面的源码;
1 <?xml version="1.0" encoding="UTF-8" ?>
2 <!DOCTYPE struts PUBLIC
3 "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
4 "http://struts.apache.org/dtds/struts-2.0.dtd">
5
6 <struts>
7 <!-- 配置包 -->
8 <package name="user" extends="struts-default">
9 <!-- 拦截器写到最上面 ,拦截器配置-->
10 <interceptors>
11 <interceptor name="loginCheck" class="com.bie.interceptor.UserCheckInterceptor"></interceptor>
12 <interceptor-stack name="myStack">
13 <!-- 默认的defaultStack -->
14 <interceptor-ref name="defaultStack"></interceptor-ref>
15 <interceptor-ref name="loginCheck"></interceptor-ref>
16 </interceptor-stack>
17 </interceptors>
18 <!-- 【执行拦截器】第一种写法,当前包下所有的action都执行myStack栈,如果只想一个执行,下面是第二种写法 -->
19 <default-interceptor-ref name="myStack"></default-interceptor-ref>
20
21 <!-- 全局配置,需要写到上面 -->
22 <global-results>
23 <result name="error">error.jsp</result>
24 </global-results>
25
26 <action name="user_*" class="com.bie.action.UserAction" method="{1}">
27 <!--第二种写法,只是在这一个Action中执行myStack栈
28 <interceptor-ref name="defaultStack"></interceptor-ref>
29 <interceptor-ref name="loginCheck"></interceptor-ref>
30 -->
31 <!--
32 第三种写法:执行用户栈(与第二种写法一样,只在当前action中执行自定义栈)
33 <interceptor-ref name="loginCheck"></interceptor-ref>
34 -->
35
36
37 <!-- 登陆失败跳转到登陆页面 -->
38 <result name="input">login.jsp</result>
39
40 <!-- 登陆成功,跳转到显示信息页面,但是需要先过action -->
41 <result name="loginSuccess" type="redirectAction">user_list</result>
42
43 <!-- 列表展示 -->
44 <result name="list">list.jsp</result>
45 </action>
46 </package>
47 </struts>
11:struts.xml页面的action会和UserAction.java的方法进行匹配,所以现在写UserAction.java,然后就可以完成登陆功能;
1 package com.bie.action;
2
3 import java.util.List;
4
5 import com.bie.po.User;
6 import com.bie.service.UserService;
7 import com.bie.service.impl.UserServiceImpl;
8 import com.opensymphony.xwork2.ActionContext;
9 import com.opensymphony.xwork2.ActionSupport;
10
11 /**
12 * @author BieHongLi
13 * @version 创建时间:2017年3月7日 上午10:31:34
14 *
15 */
16 public class UserAction extends ActionSupport{
17
18 private static final long serialVersionUID = 1L;
19 //----------1:封装请求数据------------
20 private User user;
21 public User getUser() {
22 return user;
23 }
24 public void setUser(User user) {
25 this.user = user;
26 }
27 //-----------2:调用service方法------------
28 private UserService service=new UserServiceImpl();
29
30 //-----------3:登陆的action方法----------------------
31 public String login() throws Exception {
32 try {
33 User userInfo=service.login(user);
34 //判断,如果为空,返回失败input
35 if(userInfo==null){
36 //登录失败
37 return "input";
38 }
39 //如果登陆成功,数据保存到session中
40 ActionContext.getContext().getSession().put("userInfo", "userInfo");
41
42 return "loginSuccess";
43 } catch (Exception e) {
44 return "ERROR";
45 }
46 }
47
48 //-----------4:列表,处理显示数据的方法-------------
49 public String list(){
50 try {
51 //查询全部
52 List<User> list=service.selectUser(user);
53 //保存到request中
54 ActionContext.getContext().getContextMap().put("listUser", list);
55
56 return "list";
57 } catch (Exception e) {
58 return "ERROR";
59 }
60 }
61
62 }
12:最后就再创建一个包interceptor包,这里面写过滤器,这是过滤器的核心,也是struts2的核心技术,所以需要重点掌握哦;源码如下所示:(注意:UserCheckInterceptor会和struts.xml的过滤器配置进行交互,最后完成拦截器的功能)
1 package com.bie.interceptor;
2
3 import com.opensymphony.xwork2.ActionContext;
4 import com.opensymphony.xwork2.ActionInvocation;
5 import com.opensymphony.xwork2.ActionProxy;
6 import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
7
8 /**
9 * @author BieHongLi
10 * @version 创建时间:2017年3月7日 下午1:28:00
11 * 拦截业务处理方法
12 */
13 public class UserCheckInterceptor extends AbstractInterceptor{
14
15
16 private static final long serialVersionUID = 1L;
17
18 //步骤:1:首先拿到当前执行的方法名,2:然后进行判断 ,只要当前方法名不是login,就需要进行验证
19 @Override
20 public String intercept(ActionInvocation invocation) throws Exception {
21 //获取ActionContext对象
22 ActionContext ac=invocation.getInvocationContext();
23 //获取action对象的代理对象
24 ActionProxy proxy=invocation.getProxy();
25 //获取当前执行的方法名
26 String methodName=proxy.getMethod();
27 //判断是否登陆
28 if(!"login".equals(methodName)){
29 //先获取当前登陆的用户
30 Object obj=ac.getSession().get("userInfo");
31 if(obj == null){
32 //当前用户没有登陆
33 return "input";
34 }else{
35 //当前用户有登陆
36 return invocation.invoke();
37 }
38 }else{
39 //当前用户正在登陆
40 return invocation.invoke();
41 }
42 }
43
44
45 }
演示效果如下所示:
革命尚未成功,拦截器我都学会了,努力!!!
13:Struts2的国际化:
第一,创建配置文件中文msg.properties文件,配置如下:
username=\u8D26\u53F7
password=\u5BC6\u7801
submit=\u63D0\u4EA4
title=\u6807\u9898
第二,创建配置文件英文msg_en_US.properties文件,配置如下所示:
username=UserName
password=Password
submit=OnSubmit
title=Title
然后找到default.properties搜索i18n:找到struts.custom.i18n.resources复制到配置文件上:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<!-- 通过常量加载资源文件,value值当存在多个的时候使用都好隔开 -->
<constant name="struts.custom.i18n.resources" value="com.bie.lesson08.config.msg"></constant>
<package name="adminPackage" extends="struts-default">
<!-- 拦截器配置 -->
<interceptors>
<interceptor name="loginCheck" class="com.bie.lesson08.utils.AdminInterceptor"></interceptor>
<interceptor-stack name="myStack">
<!-- 默认的拦截器配置 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="loginCheck"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 执行拦截器 ,当前包下所有的action都执行mystack栈-->
<default-interceptor-ref name="myStack"></default-interceptor-ref>
<!-- 错误放到全局的位置 -->
<global-results>
<result name="error">error.jsp</result>
</global-results>
<action name="admin_*" class="com.bie.lesson08.action.AdminAction" method="{1}">
<!-- 1:第一步,登陆失败跳转的页面,登陆失败跳转到login.jsp -->
<result name="input">login.jsp</result>
<!-- 登陆成功跳转的页面,登陆成功跳转到list.jsp,前提是查询出数据再跳转哦 -->
<!-- 2,第二步,登陆成功重定向到这个查询数据的页面,之后再进行跳转到显示数据的页面 -->
<result name="success" type="redirectAction">admin_list</result>
<!-- 3,第三步,当查询出数据,跳转到显示数据的页面 -->
<result name="list">/WEB-INF/list.jsp</result>
<!-- 登陆错误跳转的页面,登陆错误跳转的错误的页面,错误放到全局 -->
<!-- <result name="error">error.jsp</result> -->
</action>
</package>
</struts>
然后去jsp页面开始使用struts2的国际化,使用如<s:text name="title"></s:text>:
1 <%@ page language="java" contentType="text/html; charset=UTF-8"
2 pageEncoding="UTF-8"%>
3 <%@ taglib prefix="s" uri="/struts-tags"%>
4 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
5 <html>
6 <head>
7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
8 <!-- struts的国际化,name是key值 -->
9 <title><s:text name="title"></s:text></title>
10 </head>
11 <body>
12
13 <form action="${pageContext.request.contextPath }/admin_login.action" method="post">
14 账号:<input type="text" name="admin.adminName"/><br>
15 密码:<input type="password" name="admin.adminPassword"/><br/>
16 <input type="submit" name="登陆"/>
17
18 </form>
19
20 </body>
21 </html>