JavaWeb学习笔记九 过滤器、注解
過(guò)濾器Filter
filter是對(duì)客戶(hù)端訪(fǎng)問(wèn)資源的過(guò)濾,符合條件放行,不符合條件不放行,并且可以對(duì)目標(biāo)資源訪(fǎng)問(wèn)前后進(jìn)行邏輯處理。
步驟:
例子,過(guò)濾器實(shí)現(xiàn)類(lèi):
package com.yyb.filter;import java.io.IOException; import javax.servlet.*;/*** Created by Administrator on 2017/7/28.*/ public class FilterDemo implements Filter {@Override//Filter創(chuàng)建的時(shí)候執(zhí)行init方法public void init(FilterConfig filterConfig) throws ServletException {//1、獲得web.xml中filter 的名稱(chēng)<filter-name>FilterDemo</filter-name> System.out.println(filterConfig.getFilterName());//2、獲得當(dāng)前filter的初始化參數(shù)System.out.println(filterConfig.getInitParameter("aaa"));//3、獲得servletContext filterConfig.getServletContext();System.out.println("init ....");}@Override//doFilter是Filter的核心過(guò)濾的方法/** request: 內(nèi)部封裝是客戶(hù)端http請(qǐng)求的內(nèi)容* response: 代表是響應(yīng)* FilterChain: 過(guò)濾器鏈對(duì)象*/public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {System.out.println("quick1 running....");//放行請(qǐng)求 chain.doFilter(request, response);}@Override//Filter對(duì)象銷(xiāo)毀的時(shí)候執(zhí)行destory方法public void destroy() {System.out.println("destroy...");} }web.xml
<filter><filter-name>FilterDemo</filter-name><filter-class>com.yyb.filter.FilterDemo</filter-class></filter><filter-mapping><filter-name>FilterDemo</filter-name><url-pattern>/*</url-pattern></filter-mapping>Filter的API詳解
filter生命周期及其與生命周期相關(guān)的方法,Filter接口有三個(gè)方法,并且這個(gè)三個(gè)都是與Filter的生命相關(guān)的方法:
- init(Filterconfig):代表filter對(duì)象初始化方法,filter對(duì)象創(chuàng)建時(shí)執(zhí)行。
- doFilter(ServletRequest,ServletResponse,FilterCha):代表filter執(zhí)行過(guò)濾的核心方法,如果某資源在已經(jīng)被配置到這個(gè)filter進(jìn)行過(guò)濾的話(huà),那么每次訪(fǎng)問(wèn)這個(gè)資源都會(huì)執(zhí)行doFilter方法。
- destory():代表是filter銷(xiāo)毀方法,當(dāng)filter對(duì)象銷(xiāo)毀時(shí)執(zhí)行該方法。
Filter對(duì)象的生命周期
- Filter何時(shí)創(chuàng)建:服務(wù)器啟動(dòng)時(shí)就創(chuàng)建該filter對(duì)象
- Filter何時(shí)銷(xiāo)毀:服務(wù)器關(guān)閉時(shí)filter銷(xiāo)毀
init(FilterConfig):其中參數(shù)config代表該Filter對(duì)象的配置信息的對(duì)象,內(nèi)部封裝是該filter的配置信息。
destory()方法:filter對(duì)象銷(xiāo)毀時(shí)執(zhí)行。
doFilter方法:doFilter(ServletRequest,ServletResponse,FilterChain),其中的參數(shù)ServletRequest/ServletResponse是每次在執(zhí)行doFilter方法時(shí)web容器負(fù)責(zé)創(chuàng)建一個(gè)request和一個(gè)response對(duì)象作為doFilter的參數(shù)傳遞進(jìn)來(lái)。該request與response就是在訪(fǎng)問(wèn)目標(biāo)資源的service方法時(shí)的request和response。FilterChain是過(guò)濾器鏈對(duì)象,通過(guò)該對(duì)象的doFilter方法可以放行該請(qǐng)求。chain對(duì)象根據(jù)配置的filter-mapping順序依次執(zhí)行filter。
Filter的配置
<filter><filter-name>FilterDemo</filter-name><filter-class>com.yyb.filter.FilterDemo</filter-class></filter><filter-mapping><filter-name>FilterDemo</filter-name><url-pattern>/*</url-pattern></filter-mapping>url-pattern配置
- 完全匹配?
/Servlet1,只有訪(fǎng)問(wèn)Servlet1時(shí)才執(zhí)行
- 目錄匹配 /aaa/bbb/*?
/user/*:訪(fǎng)問(wèn)前臺(tái)的資源進(jìn)入此過(guò)濾器
/admin/*:訪(fǎng)問(wèn)后臺(tái)的資源時(shí)執(zhí)行此過(guò)濾器
- 擴(kuò)展名匹配 *.abc *.jsp
注意:url-pattern可以使用servlet-name替代,也可以混用。
<filter-mapping><filter-name>FilterDemo</filter-name><!--<url-pattern>/*</url-pattern>--><servlet-name>FilterTest</servlet-name><servlet-name>FilterTest1</servlet-name></filter-mapping>dispatcher:訪(fǎng)問(wèn)的方式
- REQUEST:默認(rèn)值,代表直接訪(fǎng)問(wèn)某個(gè)資源時(shí)執(zhí)行filter
- FORWARD:轉(zhuǎn)發(fā)時(shí)才執(zhí)行filter
- INCLUDE: 包含資源時(shí)執(zhí)行filter
- ERROR:發(fā)生錯(cuò)誤時(shí) 進(jìn)行跳轉(zhuǎn)時(shí)執(zhí)行filter
例子:web.xml
<filter><filter-name>FilterDemo</filter-name><filter-class>com.yyb.filter.FilterDemo</filter-class></filter><filter-mapping><filter-name>FilterDemo</filter-name><url-pattern>/*</url-pattern><dispatcher>REQUEST</dispatcher></filter-mapping>在FilterTest中,添加轉(zhuǎn)發(fā)代碼??request.getRequestDispatcher("/index.jsp").forward(request, response);?,此時(shí)當(dāng)訪(fǎng)問(wèn)FilterTest時(shí),過(guò)濾器只會(huì)執(zhí)行依次,而不是兩次。轉(zhuǎn)發(fā)時(shí)不會(huì)執(zhí)行過(guò)濾器。
但是重定向會(huì)執(zhí)行兩次,在FilterTest中,添加轉(zhuǎn)發(fā)代碼??response.sendRedirect(request.getContextPath()+"/index.jsp");?,可以看到執(zhí)行結(jié)果。
Filter的作用
- 公共代碼的提取
- 可以對(duì)request和response中的方法進(jìn)行增強(qiáng)(裝飾者模式/動(dòng)態(tài)代理)
- 進(jìn)行權(quán)限控制
使用filter解決參數(shù)中文亂碼
package com.ithiema.web.filter;import java.io.IOException; import java.io.UnsupportedEncodingException;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 javax.servlet.http.HttpServletRequestWrapper;public class EncodingFilter implements Filter{@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {//request.setCharacterEncoding("UTF-8");//在傳遞request之前對(duì)request的getParameter方法進(jìn)行增強(qiáng)/** 裝飾者模式(包裝)* * 1、增強(qiáng)類(lèi)與被增強(qiáng)的類(lèi)要實(shí)現(xiàn)統(tǒng)一接口* 2、在增強(qiáng)類(lèi)中傳入被增強(qiáng)的類(lèi)* 3、需要增強(qiáng)的方法重寫(xiě) 不需要增強(qiáng)的方法調(diào)用被增強(qiáng)對(duì)象的* *///被增強(qiáng)的對(duì)象HttpServletRequest req = (HttpServletRequest) request;//增強(qiáng)對(duì)象EnhanceRequest enhanceRequest = new EnhanceRequest(req);chain.doFilter(enhanceRequest, response);}@Overridepublic void destroy() {}@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}}class EnhanceRequest extends HttpServletRequestWrapper{private HttpServletRequest request;public EnhanceRequest(HttpServletRequest request) {super(request);this.request = request;}//對(duì)getParaameter增強(qiáng) @Overridepublic String getParameter(String name) {String parameter = request.getParameter(name);//亂碼try {parameter = new String(parameter.getBytes("iso8859-1"),"UTF-8");} catch (UnsupportedEncodingException e) {e.printStackTrace();}return parameter;} }注解
注解就是符合一定格式的語(yǔ)法 @xxxx,是給jvm看的,給機(jī)器看的。注解在目前而言最主流的應(yīng)用是代替配置文件。
關(guān)于配置文件與注解開(kāi)發(fā)的優(yōu)缺點(diǎn):
- 優(yōu)點(diǎn):開(kāi)發(fā)效率高,成本低
- 缺點(diǎn):耦合性大,并且不利于后期維護(hù)
jdk5提供的注解
@Override:告知編譯器此方法是覆蓋父類(lèi)的
@Deprecated:標(biāo)注過(guò)時(shí)
@SuppressWarnings:壓制警告
不同的注解只能在不同的位置使用(方法上、字段上、類(lèi)上)
自定義注解
怎樣去編寫(xiě)一個(gè)自定義的注解,使用@interface關(guān)鍵字。
public @interface MyAnno {//注解的屬性 String name();int age() default 28; }怎樣去使用注解
@MyAnno(name="",age=20)public void show(){}@MyAnno(name="")public void show1(){}注意:如果屬性的名字是value,并且注解的屬性值只有一個(gè),那么在使用注解時(shí)可以省略value。注解屬性類(lèi)型只能是以下幾種:基本類(lèi)型;String;枚舉類(lèi)型;注解類(lèi)型;Class類(lèi)型?;以上類(lèi)型的一維數(shù)組類(lèi)型。
public @interface MyAnno2 {//String value();String[]value(); } //@MyAnno2("aa")//public void show2(){//}@MyAnno3({"name","age"})public void show3(){}
怎樣去解析注解-----使用反射知識(shí)
介入一個(gè)概念,元注解。代表修飾注解的注解,作用是限制定義的注解的特性。
@Retention
- SOURCE: 注解在源碼級(jí)別可見(jiàn),在字節(jié)碼文件中就沒(méi)有了。
- CLASS:注解在字節(jié)碼文件級(jí)別可見(jiàn)
- RUNTIME:注解在整個(gè)運(yùn)行階段都可見(jiàn)
@Target?代表注解修飾的范圍:類(lèi)上使用,方法上使用,字段上使用
- FIELD:字段上可用此注解
- METHOD:方法上可以用此注解
- TYPE:類(lèi)/接口上可以使用此注解
注意:要想解析使用了注解的類(lèi) ,那么該注解的Retention必須設(shè)置成Runtime,注解解析的實(shí)質(zhì)是從注解中解析出屬性值
字節(jié)碼對(duì)象存在于獲得注解相關(guān)的方法
isAnnotationPresent(Class<? extends Annotation> annotationClass) : 判斷該字節(jié)碼對(duì)象身上是否使用該注解了 getAnnotation(Class<A> annotationClass) :獲得該字節(jié)碼對(duì)象身上的注解對(duì)象?
轉(zhuǎn)載于:https://www.cnblogs.com/ginb/p/7249442.html
總結(jié)
以上是生活随笔為你收集整理的JavaWeb学习笔记九 过滤器、注解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 如何使用PHP自动备份数据库
- 下一篇: JavaSE----基础语法(方法)