摘要:擴(kuò)展了反射機(jī)制的,以幫助程序員快速的構(gòu)造自定義注解處理器。返回該程序元素上存在的所有注解。在中,可以使用注解將一個繼承于的類標(biāo)注為可以處理用戶請求的。
大家好,我是樂字節(jié)的小樂,上次給大家?guī)砹薐ava注解-元數(shù)據(jù)、注解分類、內(nèi)置注解和自定義注解|樂字節(jié),這次接著往下講注解處理器和servlet3.0
使用注解的過程中,很重要的一部分就是創(chuàng)建于使用注解處理器。Java SE5擴(kuò)展了反射機(jī)制的API,以幫助程序員快速的構(gòu)造自定義注解處理器。
1、注解處理器類庫java.lang.reflect.AnnotatedElementJava使用Annotation接口來代表程序元素前面的注解,該接口是所有Annotation類型的父接口。除此之外,Java在java.lang.reflect 包下新增了AnnotatedElement接口,該接口代表程序中可以接受注解的程序元素,該接口主要有如下幾個實(shí)現(xiàn)類:
Class:類定義
Constructor:構(gòu)造器定義
Field:累的成員變量定義
Method:類的方法定義
Package:類的包定義
java.lang.reflect 包下主要包含一些實(shí)現(xiàn)反射功能的工具類,實(shí)際上,java.lang.reflect 包所有提供的反射API擴(kuò)充了讀取運(yùn)行時Annotation信息的能力。當(dāng)一個Annotation類型被定義為運(yùn)行時的Annotation后,該注解才能是運(yùn)行時可見,當(dāng)class文件被裝載時被保存在class文件中的Annotation才會被虛擬機(jī)讀取。
AnnotatedElement 接口是所有程序元素(Class、Method和Constructor)的父接口,所以程序通過反射獲取了某個類的AnnotatedElement對象之后,程序就可以調(diào)用該對象的如下四個個方法來訪問Annotation信息:
①
②Annotation[] getAnnotations():返回該程序元素上存在的所有注解。
③boolean is AnnotationPresent(Class annotationClass):判斷該程序元素上是否包含指定類型的注解,存在則返回true,否則返回false.
④Annotation[] getDeclaredAnnotations():返回直接存在于此元素上的所有注釋。與此接口中的其他方法不同,該方法將忽略繼承的注釋。(如果沒有注釋直接存在于此元素上,則返回長度為零的一個數(shù)組。)該方法的調(diào)用者可以隨意修改返回的數(shù)組;這不會對其他調(diào)用者返回的數(shù)組產(chǎn)生任何影響。
2、解析實(shí)例public class ParseCoder { public static void main(String[] args) { String coderName="名稱:"; String coderType="類型:"; String coderProvider="廠家信息如下 "; Field [] fields=Coder.class.getDeclaredFields(); for(Field field:fields){ if(field.isAnnotationPresent(Programmer.class)){ Programmer pro=(Programmer)field.getAnnotation(Programmer.class); coderName=coderName+pro.value(); System.out.println(coderName); }else if(field.isAnnotationPresent(ProgrammerType.class)){ ProgrammerType type=(ProgrammerType)field.getAnnotation(ProgrammerType.class); coderType=coderType+type.type().toString(); System.out.println(coderType); }else if(field.isAnnotationPresent(ProgrammerProductor.class)){ ProgrammerProductor fruitProvider=(ProgrammerProductor)field.getAnnotation(ProgrammerProductor.class); coderProvider+="編號:"+fruitProvider.id()+" 名稱:"+fruitProvider.name()+" 地址:"+fruitProvider.address(); System.out.println(coderProvider); } } } }二、 Servlet3.0 1、@WebServlet
使用注解達(dá)到零配置,開發(fā)servlet項(xiàng)目,使用@WebServlet將一個繼承于javax.servlet.http.HttpServlet的類定義為Servlet組件。在Servlet3.0中,可以使用@WebServlet注解將一個繼承于javax.servlet.http.HttpServlet的類標(biāo)注為可以處理用戶請求的Servlet。
@WebServlet注解的相關(guān)屬性
Servlet的訪問URL是Servlet的必選屬性,可以選擇使用urlPatterns或者value定義。如一個Servlet可以描述成:
@WebServlet(name="ServletDemo",value="/ServletDemo")。
也定義多個URL訪問:如
@WebServlet(name="ServletDemo",urlPatterns={"/ServletDemo","/ServletDemo2"})
或者:
@WebServlet(name="AnnotationServlet",value={"/ServletDemo","/ServletDemo2"})
initParams可以用來指定當(dāng)前Servlet的初始化參數(shù),它是一個數(shù)組, 里面每一個@WebInitParam表示一個參數(shù)。
@WebServlet(value="/servlet/init-param", initParams={@WebInitParam(name="param1", value="value1")})
測試實(shí)例如下
/** * 使用@WebServlet將一個繼承于javax.servlet.http.HttpServlet的類定義為Servlet組件。 如@WebServlet有很多的屬性: 1、asyncSupported: 聲明Servlet是否支持異步操作模式。 2、description: Servlet的描述。 3、displayName: Servlet的顯示名稱。 4、initParams: Servlet的init參數(shù)。 5、name: Servlet的名稱。 6、urlPatterns:Servlet的訪問URL。 7、value: Servlet的訪問URL。 Servlet的訪問URL是Servlet的必選屬性,可以選擇使用urlPatterns或者value定義。 如@WebServlet(name="TestServlet",value="/TestServlet"),也定義多個URL訪問: 如@WebServlet(name="TestServlet",urlPatterns={"/TestServlet","/Test"}) 或@WebServlet(name="TestServlet",value={"/TestServlet","/Test"}) */ @WebServlet(name="/TestServlet",urlPatterns={"/test"}) public class TestServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.getWriter().print("hello servlet3"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
初始化參數(shù)
@WebServlet(value="/init", initParams={@WebInitParam(name="param1", value="sxt")}) public class TestInit extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Enumeration2、@WebFilterparamNames = this.getServletConfig().getInitParameterNames(); String paramName; while (paramNames.hasMoreElements()) { paramName = paramNames.nextElement(); response.getWriter().append(paramName + " = " + this.getServletConfig().getInitParameter(paramName)); } response.getWriter().close(); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
/** * 使用注解標(biāo)注過濾器:@WebFilter將一個實(shí)現(xiàn)了javax.servlet.Filter * 接口的類定義為過濾器,屬性filterName聲明過濾器的名稱,可選 * 屬性urlPatterns指定要過濾 的URL模式,也可使用屬性value來聲明. * (指定要過濾的URL模式是必選屬性), * 可以指定多種過濾模式@WebFilter(filterName="TestFilter", * urlPatterns={"/User","/index.jsp"}) * @author Administrator */ @WebFilter(filterName="TestFilter",urlPatterns="/*") public class TestFilter implements Filter { @Override public void destroy() { System.out.println("過濾器銷毀"); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("執(zhí)行過濾操作"); chain.doFilter(request, response); } @Override public void init(FilterConfig arg0) throws ServletException { System.out.println("過濾器初始化"); } }3、@MultipartConfig
使用注解@MultipartConfig將一個Servlet標(biāo)識為支持文件上傳。Servlet3.0將multipart/form-data的POST請求封裝成Part,通過Part對上傳的文件進(jìn)行操作。
注意:Servlet3沒有提供直接獲取文件名的方法,需要從請求頭中解析出來
1)、頁面制作
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>文件上傳
2)、編寫Servlet
/** * Servlet3.0將multipart/form-data的POST請求封裝成Part, * 通過Part對上傳的文件進(jìn)行操作,Servlet3沒有提供直接獲取文件名的方法, * 需要從請求頭中解析出來,獲取請求頭,請求頭的格式: * 火狐和google瀏覽器下:form-data; name="file"; filename="snmp4j--api.zip" * @author Administrator */ @WebServlet(name = "TestUpload", urlPatterns = "/upload") @MultipartConfig public class TestUpload extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); // 存儲路徑 String savePath = request.getServletContext().getRealPath("/WEB-INF/upload"); // 獲取上傳的文件集合 Collection4、@WebListenerparts = request.getParts(); //上傳單個文件 if (parts.size()==1) { //通過文件名獲取文件 Part part = request.getPart("file"); //從請求頭中獲取文件 String header = part.getHeader("content-disposition"); //獲取文件名 String fileName = getFileName(header); //把文件寫到指定路徑 part.write(savePath+File.separator+fileName); }else{ for (Part part : parts) {//循環(huán)處理上傳的文件 //請求頭的格式:form-data; name="file"; filename="snmp4j--api.zip" String header = part.getHeader("content-disposition"); //獲取文件名 String fileName = getFileName(header); if(!fileName.equals("")){ //把文件寫到指定路徑 part.write(savePath+File.separator+fileName); } } } PrintWriter out = response.getWriter(); out.println("上傳成功"); out.flush(); out.close(); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doGet(req,resp); } /** * 獲取文件名 * 火狐和google瀏覽器下:form-data; name="file"; filename="snmp4j--api.zip" * @param header * @return */ private String getFileName(String header) { String[] headArr = header.split(";")[2].split("="); //獲取文件名,兼容各種瀏覽器的寫法 return headArr[1].substring(headArr[1].lastIndexOf("")+1).replaceAll(""", ""); } }
Servlet3.0提供@WebListener注解將一個實(shí)現(xiàn)了特定監(jiān)聽器接口的類定義為監(jiān)聽器。將實(shí)現(xiàn)了ServletContextListener接口的MyServletContextListener標(biāo)注為監(jiān)聽器。
@WebListener public class TestListener implements ServletContextListener { @Override public void contextDestroyed(ServletContextEvent event) { System.out.println("ServletContext銷毀"); } @Override public void contextInitialized(ServletContextEvent event) { System.out.println("ServletContex初始化"); System.out.println(event.getServletContext().getServerInfo()); } }
有關(guān)注解就介紹到這里了,感謝各位老板的光顧和學(xué)習(xí)。
請繼續(xù)關(guān)注樂字節(jié),后續(xù)不斷更新Java干貨資料和視頻。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/75610.html
摘要:注解有以下幾個知識點(diǎn)元數(shù)據(jù)注解的分類內(nèi)置注解自定義注解注解處理器本文先介紹前面?zhèn)€知識點(diǎn)元數(shù)據(jù)注解的分類內(nèi)置注解自定義注解。注解相當(dāng)于是一種嵌入在程序中的元數(shù)據(jù),可以使用注解解析工具或編譯器對其進(jìn)行解析,也可以指定注解在編譯期或運(yùn)行期有效。 大家好,我是樂字節(jié)的小樂,上次說過了Java多態(tài)的6大特性|樂字節(jié),接下來我們來看看Java編程里的注解。showImg(https://segme...
摘要:上一篇小樂給大家說了樂字節(jié)新特性之,接下來小樂繼續(xù)給大家說一說新特性之和重復(fù)注解與類型注解。內(nèi)部類與方法相關(guān)的內(nèi)部類這是一個靜態(tài)類。也是一個靜態(tài)類。 上一篇小樂給大家說了《樂字節(jié)-Java8新特性之Date API》,接下來小樂繼續(xù)給大家說一說Java8新特性之Base64和重復(fù)注解與類型注解。 一、Base64 在Java 8中,內(nèi)置了Base64編解碼相關(guān)的特性。Java 8中使用...
摘要:注解全解析什么是注解注解有什么作用注解是怎么干活的如何自定義注解什么是注解注解即元數(shù)據(jù),一種描述數(shù)據(jù)的數(shù)據(jù),可以說注解就是源代碼的元數(shù)據(jù)是一種應(yīng)用于類方法參數(shù)變量構(gòu)造器及包聲明中的特殊修飾符不能影響程序代碼的運(yùn)行,無論增加刪除注解,代碼都始 注解全解析 什么是注解? 注解有什么作用? 注解是怎么干活的? 如何自定義注解? 什么是注解 注解即元數(shù)據(jù),一種描述數(shù)據(jù)的數(shù)據(jù),可以說注解就...
摘要:依賴于對請求的支持。使用解析兼容的沒有構(gòu)造器參數(shù),也沒有要設(shè)置的參數(shù),這樣,在應(yīng)用上下文中,將其聲明為就會非常簡單。默認(rèn)是沒有限制的整個請求的容量。 Spring MVC 高級的技術(shù) 本章內(nèi)容: Spring MVC配置的替代方案 處理文件上傳 在控制器中處理異常 使用flash屬性 稍等還沒結(jié)束 說明 如果你有幸能看到。后面的章節(jié)暫時不更新了,改變學(xué)習(xí)方式了。重要理解思想,這本書...
摘要:注意當(dāng)多個父接口中存在相同的默認(rèn)方法時,子類中以就近原則繼承。定義靜態(tài)默認(rèn)方法這是版簡易計算器接口默認(rèn)方法使用定義接口并提供默認(rèn)打印方法定義接口默認(rèn)方法支持方法形參這是數(shù)值運(yùn)算基本接口。。。 總概 JAVA8 已經(jīng)發(fā)布很久,而且毫無疑問,java8是自java5(2004年發(fā)布)之后的最重要的版本。其中包括語言、編譯器、庫、工具和JVM等諸多方面的新特性。 Java8 新特性列表如下:...
閱讀 1086·2023-04-25 23:40
閱讀 3788·2021-11-22 15:22
閱讀 3687·2021-10-09 09:44
閱讀 3495·2021-09-23 11:52
閱讀 1363·2021-09-22 15:43
閱讀 862·2021-09-10 10:51
閱讀 2298·2021-09-06 15:02
閱讀 3286·2021-09-06 15:02