其實學習框架,就是為了可以很好的很快的完成我們的需求,而學習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>