其实学习框架,就是为了可以很好的很快的完成我们的需求,而学习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>