JavaWeb學習day10(基礎加強)

第1章 設置環境

安裝操作系統,安裝備份(鏡像):

  • JDK: 設置環境變量
  • Eclipse:解壓即可
    • Eclipse自身解壓目錄不包括中文
    • 代碼工作空間目錄不包括中文
  • Tomcat:解壓不要包含中文目錄
  • MySql:安裝: 選擇編碼utf8

設置Eclipse

  • 1_關聯TOMCAT
    • 開發過程中,環境發生變化(重新關聯tomcat),
    • 刪除servers窗口下的tomcat
    • Project Explorer 窗口下的server
    • 重新關聯window—>preferences–>servers—>runtime–>tomcat

第2章 自定義註解

2.1 什麼是註解?

註解和接口,類一樣,都是屬於數據類型.

2.2 註解作用

  • 1_編譯檢查
  • 2_配置 (後期使用最多)
  • 3_生成幫助文檔

2.3 註解的特點

  • 註解可以在變量,方法,類之上加載

  • 註解可以有屬性也可以沒有屬性

    • @Override
    • @Test(timeout=1000):執行時間超過一秒報錯
  • 註解有作用範圍(源碼,編譯期間,運行期間)

    • 源碼期間有效: String類之上@Author,@Since,@See
      作用:使用命令javadoc命令將當前的源碼生成幫助文件, 可以識別String類上的相關的註解
    • 編譯期間有效: @Override @Deprecated @Suppresswarning
      作用:告訴編譯器部分信息
    • 運行期間有效: @Test
      作用:當我們再當前代碼上以Junit方式運行時,Junit會運行方法上包含@Test註解的方法

2.4 回顧JDK中出現的3種註解

@Override @Deprecated @Suppresswarning

  • @override:此註解的含義是申明當前的方法是重寫父類的方法
  • @Suppresswarning:抑制編譯器發生警告信息
    @Suppresswarning{“unused”,“rawtypes”} 屬性一變量未使用,屬性二語句沒有加泛型
  • @Deprecated:聲明以下的方法是過時的方法,不建議大家使用

2.5 自定義註解

  • 格式:
  public @interface 註解名稱{
     public  屬性類型  屬性名稱1();
     public  屬性類型  屬性名稱2()  default  默認值;
  }
  • 自定義註解屬性支持的類型:

    • 基本數據類型(4類8種),String,Class,Annotation(註解類型),枚舉類型,
      以及以上類型的一維數組類型
  • 註解作用: 配置作用

    • 配置:開發的時候部分信息不希望寫死在程序中,例如數據庫的用戶名和密碼,可以將用戶名和密碼存放在.txt , .properties , .xml文件中,利用程序來讀取文件中的內容
  • 框架:一大堆工具類組合,目的:加速項目開發

    • 後期的學習中,框架部分hibernate,spring,struts2很多信息需要配置,提供了2種形式配置 (xml,註解)
  • 什麼時候用註解來做配置?

    • 如果配置信息不會發生的修改,例如servlet路徑,建議使用註解的形式
    • 如果配置信息需要發生頻繁的修改,例如數據庫的用戶名和密碼信息,
      建議採用傳統方法 (.txt , .properties , .xml)
<students>
  <stu>
   <stuNum>s002</stuNun>
   <stuPhone>
      <stuHomePhone>124324</stuHomePhone>
      <stuCmpPhone>12342143</stuCmpPhone>
   </stuPhone>
  </stu>
</students>
  • 測試使用自定義註解
@MyAnno01(timeout=100,c=java.util.Date.class,strs={"aaa","bbb"})
public void test01(){
}
  • 通過反射讀取字節碼上的註解信息
    md.isAnnotationPresent(MyTest.class)

2.6 案例:模擬Junit

  • 1_自定義註解@MyTest
    • 通過元註解@Rentention @Target聲明當前註解作用域以及目標對象,如果沒有聲明,在運行期間是無法獲取到註解的信息
  • 2_定義UserDao
    • 創建4個方法addUser delUser uptUser getUser ,在前三個方法上加載註解
  • 3_定義類MyJunit ,模擬JUnit
    • 將UserDao.class文件加載到內存,
    • 獲取到字節碼文件上所有的方法
    • 遍歷方法,判斷每個方法上是否加載了@MyTest註解
  • 如果當前方法上設置@MyTest,執行當前的方法

註解要求:
聽懂,實現上課代碼.
開發中地位:類似dom4j解析XML文件. XML文件的解析程序員不會去解析,配置XML文件
後期的開發中不會自定義註解,反射讀取註解信息.

第3章 使用動態代理解決網站的字符集編碼問題

3.1 設計模式

軟件開發過程中,遇到相似問題,將問題的解決方式抽取模型(套路)
單例,工廠,適配器,裝飾者,動態代理

3.2 谷歌汽車場景

  • java設計了汽車開發約定
    interface ICar{ start run stop}
    class GoogleCar implements ICar{}

  • 希望在將谷歌Car接入到生態圈平臺時,增強汽車啓動功能

  • 裝飾者模式

    • 場景:二次開發的時候,無法獲取到源碼,無法使用繼承前提下,要對已經存在對象上的功能進行增強.
    • 前提: 可以獲取到被裝飾的對象GoogleCar實現的所有接口
    • 實現思路: 自定定義裝飾類實現ICar接口,爲自定義裝飾類傳遞被裝飾的對象
    • 弊端:如果被實現的接口中的方法過多,裝飾類中的方法過多冗餘
  • 動態代理模式

    • 原理:通過虛擬機在內存中創建類似MyCar.class文件
    • 要創建MyCar.class文件告訴虛擬機:
      • 1_被創建的字節碼文件上應該有多少方法
      • 2_被創建的字節碼上的方法如何來實現
  • 字節碼加載器:

    • jdk有一些程序,專業將各種字節碼文件加載到內存.這類程序簡稱爲字節碼加載器
    • 如何將字節碼文件class文件加載到內存?
      底層實現過程,利用IO流技術,獲取到文件中的數據加載到內存
    • 字節碼加載器:3種
      引導類加載器,擴展類加載器,應用類加載器

public class TestClassLoader {
	public static void main(String[] args) {
		
		//獲取String類的加載器
		ClassLoader classLoader = String.class.getClassLoader();
		System.out.println(classLoader);
		//由於String.class ,int.class等字節碼文件需要頻繁的被加載內存,速度必須快,底層用其他語言來實現c c++
		
		//獲取ext(extendtion)包下的某個類的字節碼加載器   ExtClassLoader:擴展類加載器
		ClassLoader classLoader2 = sun.net.spi.nameservice.dns.DNSNameService.class.getClassLoader();
		System.out.println(classLoader2);
	
		//應用類:程序員實現的所有的類都屬於應用類
		//獲取應用類加載器 AppClassLoader
		ClassLoader classLoader3 = TestClassLoader.class.getClassLoader();
		System.out.println(classLoader3);
	}
}

3.3 案例:動態代理解決全站亂碼問題

步驟

  • 1_new DynamicWeb Project -->Index.html
<h1>post方式提交中文</h1>
<form action="/day18_v3/ServletDemo" method="post">
	User:<input type="" name="username"/><br/>
	<input type="submit"/>
</form>

<h1>get方式提交中文</h1>
<form action="/day18_v3/ServletDemo" method="get">
	User:<input type="" name="username"/><br/>
	<input type="submit"/>
</form>
  • 2_ServletDemo
    • 無論是在post/get方法,執行以下語句不存在中文亂碼問題
String um=request.getParameter("username");
System.out.println(um);
  • 3_過濾器中,爲request上的getParameter()功能進行增強
    • 思路:
  判斷當前的請求是get/post  request.getMethod();
  如果是post, 設置一句話: request.setCharacterEncoding(“utf-8”);    ,放行
  如果是get,調用原先的String v=request.getParameter(name);
     將v進行轉碼,放行
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

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;

public class EncodingFilter implements Filter {

    public EncodingFilter() {
    }

	public void destroy() {
	}
	public void init(FilterConfig fConfig) throws ServletException {
	}
	
	
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		//將request對象轉換爲HttpServletRequest
		final HttpServletRequest req=(HttpServletRequest)request;
		//讓JDK在內存中生成代理對象:增強了req對象上的getParameter(name);API
		HttpServletRequest myReq=(HttpServletRequest)Proxy.newProxyInstance(EncodingFilter.class.getClassLoader(), req.getClass().getInterfaces(), new InvocationHandler() {
			
			@Override
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				
				Object obj=null;
				
				if(method.getName().equalsIgnoreCase("getParameter")){
					//獲取本次請求方式
					String md=req.getMethod();
					if("get".equalsIgnoreCase(md)){
						//get方式的請求
						//調用req對象上的getParameter方法
						String v=(String)method.invoke(req, args);
						//轉碼
						String vv=new String(v.getBytes("iso-8859-1"),"utf-8");
						return vv;
						
					}else{
						//post方式的請求
						req.setCharacterEncoding("utf-8");
						obj=method.invoke(req, args);
					}
					
					
				}else{
					obj=method.invoke(req, args);
				}
				return obj;
			}
		});
		//打印代理對象哈希碼
		System.out.println(myReq.hashCode());
		//將代理對象放行
		chain.doFilter(myReq, response);
	}
}
發佈了73 篇原創文章 · 獲贊 67 · 訪問量 4519
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章