一、自定義攔截器 1.架構 2.攔截器創建 3.攔截器api 4.攔截器配置 二、struts2標簽 1.標簽體系 2.struts2標簽結構 3.控制標簽 準備Action然後再到jsp練習struts2標簽 開始練習控制標簽: 4.數據標簽 5.表單標簽 6.非表單標簽 在action中添加錯誤 ...
一、自定義攔截器
1.架構
2.攔截器創建
//攔截器:第一種創建方式 //攔截器生命周期:隨項目的啟動而創建,隨項目關閉而銷毀 public class MyInterceptor implements Interceptor{}
//創建方式2: 繼承AbstractInterceptor -> struts2的體貼 //幫我們空實現了init 和 destory方法. 我們如果不需要實現這兩個方法,就可以只實現intercept方法 public class MyInterceptor2 extends AbstractInterceptor{}
//創建方式3:繼承MethodFilterInterceptor 方法過濾攔截器 //功能: 定製攔截器攔截的方法. // 定製哪些方法需要攔截. // 定製哪些方法不需要攔截 public class MyInterceptor3 extends MethodFilterInterceptor{}
3.攔截器api
//放行 String result = invocation.invoke();
//前處理 System.out.println("MyInterceptor3 的前處理!"); //放行 String result = invocation.invoke(); //後處理 System.out.println("MyInterceptor3 的後處理!");
//不放行,直接跳轉到一個結果頁面 //不執行後續的攔截器以及Action,直接交給Result處理結果.進行頁面跳轉 return "success";
4.攔截器配置
<package name="inter" namespace="/" extends="struts-default" > <interceptors> <!-- 1.註冊攔截器 --> <interceptor name="myInter3" class="cn.itcast.a_interceptor.MyInterceptor3"></interceptor> <!-- 2.註冊攔截器棧 --> <interceptor-stack name="myStack"> <!-- 自定義攔截器引入(建議放在20個攔截器之前) --> <interceptor-ref name="myInter3"> <!-- 指定哪些方法不攔截 <param name="excludeMethods">add,delete</param> --> <!-- 指定哪些方法需要攔截 --> <param name="includeMethods">add,delete</param> </interceptor-ref> <!-- 引用預設的攔截器棧(20個) --> <interceptor-ref name="defaultStack"></interceptor-ref> </interceptor-stack> </interceptors> <!-- 3.指定包中的預設攔截器棧 --> <default-interceptor-ref name="myStack"></default-interceptor-ref> <action name="Demo1Action_*" class="cn.itcast.a_interceptor.Demo1Action" method="{1}" > <!-- 為Action單獨指定走哪個攔截器(棧) <interceptor-ref name="myStack"></interceptor-ref>--> <result name="success" type="dispatcher" >/index.jsp</result> </action> </package>
<!-- 補充知識:定義全局結果集 --> <global-results> <result name="toLogin" type="redirect" >/login.jsp</result> </global-results>
二、struts2標簽
1.標簽體系
2.struts2標簽結構
3.控制標簽
準備Action然後再到jsp練習struts2標簽
public class Demo2Action extends ActionSupport { public String execute() throws Exception { List<String> list = new ArrayList<>(); list.add("tom"); list.add("jerry"); list.add("jack"); list.add("rose"); list.add("hqy"); ActionContext.getContext().put("list", list); return SUCCESS; } }
開始練習控制標簽:
<%@ taglib prefix="s" uri="/struts-tags" %> <!-- 遍歷標簽 iterator --> <!-- ------------------------------------- --> <s:iterator value="#list" > <s:property /><br> </s:iterator> <!-- ------------------------------------- --><hr> <s:iterator value="#list" var="name" > <s:property value="#name" /><br> </s:iterator> <!-- ------------------------------------- --><hr> <s:iterator begin="1" end="100" step="1" > <s:property />| </s:iterator> <!-- ------------------if else elseif------------------- --><hr> <s:if test="#list.size()==4"> list長度為4! </s:if> <s:elseif test="#list.size()==3"> list長度為3! </s:elseif> <s:else> list不3不4! </s:else>
4.數據標簽
<!-- ------------------property 配合ognl表達式頁面取值 ------------------- --><hr> <s:property value="#list.size()" /> <s:property value="#session.user.name" />
5.表單標簽
<!-- struts2表單標簽 --> <!-- 好處1: 內置了一套樣式. --> <!-- 好處2: 自動回顯,根據棧中的屬性 --> <!-- theme:指定表單的主題 xhtml:預設 simple:沒有主題 --> <s:form action="Demo3Action" namespace="/" theme="xhtml" > <s:textfield name="name" label="用戶名" ></s:textfield> <s:password name="password" label="密碼" ></s:password> <s:radio list="{'男','女'}" name="gender" label="性別" ></s:radio> <s:radio list="#{1:'男',0:'女'}" name="gender" label="性別" ></s:radio> <s:checkboxlist list="#{2:'抽煙',1:'喝酒',0:'燙頭'}" name="habits" label="愛好" ></s:checkboxlist> <s:select list="#{2:'大專',1:'本科',0:'碩士'}" headerKey="" headerValue="---請選擇---" name="edu" label="學歷" > </s:select> <s:file name="photo" label="近照" ></s:file> <s:textarea name="desc" label="個人簡介" ></s:textarea> <s:submit value="提交" ></s:submit> </s:form>
6.非表單標簽
在action中添加錯誤信息
this.addActionError("我是錯誤信息 哈哈哈");
取出錯誤信息
<s:actionerror/>
三、練習:登陸功能
核心代碼:
Action代碼:
public class UserAction extends ActionSupport implements ModelDriven<User> { private User user = new User(); private UserService us = new UserServiceImpl(); public String login() throws Exception { //1 調用Service 執行登陸操作 User u = us.login(user); //2 將返回的User對象放入session域作為登陸標識 ActionContext.getContext().getSession().put("user", u); //3 重定向到項目的首頁 return "toHome"; } @Override public User getModel() { return user; } }
Service層代碼:
public class UserServiceImpl implements UserService { private UserDao ud = new UserDaoImpl(); @Override public User login(User user) { //打開事務 HibernateUtils.getCurrentSession().beginTransaction(); //1.調用Dao根據登陸名稱查詢User對象 User existU = ud .getByUserCode(user.getUser_code()); //提交事務 HibernateUtils.getCurrentSession().getTransaction().commit(); if(existU==null){ //獲得不到=>拋出異常提示用戶名不存在 throw new RuntimeException("用戶名不存在!"); } //2 比對密碼是否一致 if(!existU.getUser_password().equals(user.getUser_password())){ //不一致=>拋出異常提示密碼錯誤 throw new RuntimeException("密碼錯誤!"); } //3 將資料庫查詢的User返回 return existU; } }
Dao層代碼:
public class UserDaoImpl implements UserDao { @Override public User getByUserCode(String user_code) { //HQL查詢 //1.獲得Session Session session = HibernateUtils.getCurrentSession(); //2 書寫HQL String hql = "from User where user_code = ? "; //3 創建查詢對象 Query query = session.createQuery(hql); //4 設置參數 query.setParameter(0, user_code); //5 執行查詢 User u = (User) query.uniqueResult(); return u; } }
四、練習:校驗登陸攔截器
核心代碼:
攔截器代碼:
public class LoginInterceptor extends MethodFilterInterceptor { //指定不攔截登陸方法. 其他方法都攔截 @Override protected String doIntercept(ActionInvocation invocation) throws Exception { //1.獲得session Map<String, Object> session = ActionContext.getContext().getSession(); //2.獲得登陸標識 Object object = session.get("user"); //3.判斷登陸標識是否存在 if(object == null){ //不存在=>沒登錄=>重定向到登錄頁面 return "toLogin"; }else{ //存在=>已經登陸=>放行 return invocation.invoke(); } } }
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"> <struts> <!-- 指定struts2是否以開發模式運行 1.熱載入主配置.(不需要重啟即可生效) 2.提供更多錯誤信息輸出,方便開發時的調試 --> <constant name="struts.devMode" value="true"></constant> <package name="crm" namespace="/" extends="struts-default" > <interceptors> <!-- 註冊攔截器 --> <interceptor name="loginInterceptor" class="cn.itheima.web.interceptor.LoginInterceptor"></interceptor> <!-- 註冊攔截器棧 --> <interceptor-stack name="myStack"> <interceptor-ref name="loginInterceptor"> <param name="excludeMethods">login</param> </interceptor-ref> <interceptor-ref name="defaultStack"></interceptor-ref> </interceptor-stack> </interceptors> <!-- 指定包中的預設攔截器棧 --> <default-interceptor-ref name="myStack"></default-interceptor-ref> <!-- 定義全局結果集 --> <global-results> <result name="toLogin" type="redirect" >/login.jsp</result> </global-results> <global-exception-mappings> <!-- 如果出現java.lang.RuntimeException異常,就將跳轉到名為error的結果 --> <exception-mapping result="error" exception="java.lang.RuntimeException"></exception-mapping> </global-exception-mappings> <action name="CustomerAction_*" class="cn.itheima.web.action.CustomerAction" method="{1}" > <result name="list" >/jsp/customer/list.jsp</result> <result name="toList" type="redirectAction"> <param name="actionName">CustomerAction_list</param> <param name="namespace">/</param> </result> </action> <action name="UserAction_*" class="cn.itheima.web.action.UserAction" method="{1}" > <result name="toHome" type="redirect" >/index.htm</result> <result name="error" >/login.jsp</result> </action> </package> </struts>
補充知識:檢查當前頁面的父頁面是否是自己,不是的話進行跳轉,解決頁面嵌套問題。
<script type="text/javascript"> window.onload=function(){ if(window.parent != window){// 如果是在框架中 //就讓框架頁面跳轉到登陸頁面 window.parent.location.href = "${pageContext.request.contextPath}/login.jsp"; } }; </script>