※編碼
.HttpServletRequest是接收html、jsp的編碼,又分成get和post編碼.HttpServletResponse是回傳給瀏覽器的,所以以ie來說,檢視-->編碼會是resp.setContentType("text/html;charset=Big5");的值
※HttpServletResponse
要注意resp.setContentType設定Big5,那麼getContentType和getCharacterEncoding()都是Big5可是setCharacterEncoding("Big5"),只有getCharacterEncoding()是Big5,另外一個是null
至少我試tomcat8是這樣
※HttpServletRequest
※post編碼
jsp的<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> 也可以寫成 <%@ page language="java" contentType="text/html" pageEncoding="UTF-8"%> 但如果寫成 <%@ page language="java" contentType="text/html; charset=Big5" pageEncoding="UTF-8"%> 那瀏覽器最終的結果就是Big5可參考良葛格的網頁
pageEncoding是指這支jsp用的編碼(在Eclipse裡改好存檔後,按右鍵Properties就可以知道),而contentType的charset是給瀏覽器用的,當然可以不一樣
charset和pageEncoding如果其中一個沒有編碼,那沒打編碼的會和有打編碼的一樣
如果兩個都沒打,那就是ISO8859-1
※以上的說法,我是用tomcat7和8的最後一版測的,瀏覽器有沒有差我不知道,我用IE11和Chrome 結果都一樣
req.setCharacterEncoding("UTF-8");兩個編碼要一樣,這樣用戶傳中文進來才不會亂碼(當然也要支援中文,如果傳ISO-8859-1是一定亂碼的)
1.使用req.setCharacterEncoding(和前端一樣的編碼名稱),這行以下的部分只要使用req.getParameter就會使用指定的編碼
2.使用new String(req.getParameter("hid").getBytes("ISO-8859-1"), 和前端一樣的編碼名稱),這是針對這一次的,所以不會影響到之後的編碼,
因為預設是ISO-8859-1,所以可拿來轉換
3.用Eclipse生成jsp會有<meta http-equiv="Content-Type" content="text/html; charset=Big5">
這是HTML的寫法,但副檔是jsp的話,這行有寫沒寫都沒差,除非副檔名是html
※get編碼
使用req.setCharacterEncoding()沒有用,還是會亂碼,要注意指的是req抓取的部分,如下:System.out.println("中文:" + req.getParameter("hid"));
這時「中文」兩個字不會出亂碼,只有req取前端的資料會出亂碼
使用 new String(req.getParameter("hid").getBytes("ISO-8859-1", 和前端一樣的編碼名稱)
因為預設是ISO-8859-1(tomcat7不知哪個版本之後~第9版改成UTF-8了),所以可拿來轉換
Tomcat官網的左邊
左邊Documentation的Tomcat x.0
左邊Reference的Configuration
左邊Connectors的HTTP
Common Attributes有個URIEncoding
在這裡
按照這樣的找法,會發現6的預設值是ISO-8859-1,7~9是UTF-8(還有但書,自己看)
這個設定要在server.xml的Connector,找到沒有註解的,我找到的只有兩個,要選protocol="HTTP/1.1"的(因為剛剛找的就是HTTP)
把它改成URIEncoding="ISO-8859-1"會和6一樣,所以就不會有亂碼了,這個設定我試的結果,不會影響post
我有把它改成new String(req.getParameter("hid").getBytes("UTF-8", 和前端一樣的編碼名稱),但沒有用,不知道為什麼
良葛格也有寫,但他沒說為什麼
現在的網頁大部分都用UTF-8了,所以在7~9全部都設UTF-8就不會感受到get和post的不同了
還有一個屬性是useBodyEncodingForURI,預設是false
這個設定表示get的設定要不要和post一樣
按照上面的找法找到Configuration後,左邊web.xml的Filter,6~9都有Set Character Encoding Filter
它說可以用filter,名稱是org.apache.catalina.filters.SetCharacterEncodingFilter,所以在web.xml多一些設定,如下:
<filter> <filter-name>xxx</filter-name> <filter-class>org.apache.catalina.filters.SetCharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>Big5</param-value> </init-param> </filter> <filter-mapping> <filter-name>xxx</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
※這個設定post很ok,但get還是要設URIEncoding,而且編碼要和web.xml、jsp一樣才可以
※filter後面會再介紹
※web-fragment.xml
類似web.xml的功能有三種第一篇有講到annotation,還有一種叫web-fragment.xml,都是Servlet3.0增加的而web.xml的<web-app>有一個屬性叫metadata-complete,意思是設定web.xml是否完整,預設是false,表示不完整,所以可以參考web-fragment.xml、annotation的設定,如果設定一樣,以web.xml為主,如果設定為true,那web-fragment.xml、annotation就沒作用了
優先順序是web.xml-->web-fragment.xml-->annotation
良葛格這篇寫的很好
Eclipse可以用滑鼠創建,File-->New-->Other,如下:
Project name取個名字
Dynamic Web project membership裡面的專案名稱是指目前創的這個Web Fragment要給哪一個專案用
Finish即可
在TestServlet專案右鍵-->Properties 如下操作後可看到剛剛創的Web Fragment
上面的紅框是剛剛建的,下面的紅框是抓到的
裡面的內容基本上和web.xml一樣,但一般來說url-pattern一樣會報錯,下面的三種對應會說,可是在這裡,我如果設一樣,不會報錯,它抓到的會是web.xml
※三種對應
<servlet-mapping> <servlet-name>ooo</servlet-name> <url-pattern>/xxx</url-pattern> </servlet-mapping>
※這幾種對應,jsp都不用「/」開頭,也不是真的錯,是路徑不一樣,第一篇有講過
※第一篇的對應是完全對應,也就是jsp的action是xxx就會對應到
※第二種是前置路徑對應/xxx/*(不一定要用「*」),只要是xxx開頭的就對應的到,
沒有/xxx/*/ooo這種寫法
※最後一種是副檔名對應*.xxx(一定要有「.」),只要是.xxx結尾的就對應的到,
沒有.xxx這種寫法
※如果都針測到,以第一種優先,第二種次之,最後是第三種,還有一個是全部處理的「/*」,它的優先權最高,比完全對應還高,如果想測試,可再寫一隻Servlet,如下:
<servlet> <servlet-name>ooo</servlet-name> <servlet-class>controller.HelloServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>ooo</servlet-name> <url-pattern>/xxx/*</url-pattern> </servlet-mapping> <servlet> <servlet-name>aaa</servlet-name> <servlet-class>controller.LoadOnStartup</servlet-class> </servlet> <servlet-mapping> <servlet-name>aaa</servlet-name> <url-pattern>/xxx/ooo</url-pattern> </servlet-mapping>
※裡面印出一些東西就知道run的是哪一支了,只會run一支哦!並不是優先權最高run完,然後run優先權低的
※要注要url-pattern不能和其他servlet完全一樣,如果這兩支用一樣的,就會出「The servlets named [ooo] and [aaa] are both mapped to the url-pattern [/xxx] which is not permitted」的錯
※這次的結果是*優先明確打出來的ooo
※生命週期
1.Servlet Reloading2..Load on Startup
3.Init Parameter
4.Synchronization
5.initial & Destory
Servlet container替我們建立servlet實體;並且,由其控制呼叫init、service、destroy等方法,以管理servlet的生命週期
Servlet container一般執行步驟
當Servlet第一次被客戶端請求時,它會載入該Servlet,建立實體
呼叫Servlet的init(),以進行Servlet初始化工作
呼叫Servlet的service(),處理所有請求
當container關閉時,會呼叫每一個Servlet的destroy()
重載入上一篇有講設定了,這裡寫一支程式測一下
※隨便寫一支Servlet如下:
int i = 0; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { i++; PrintWriter out = resp.getWriter(); out.println("a=" + i); }
※這樣子i的值會一直增加,不管有沒有換瀏覽器都會,甚至關掉都會一直增加
※但如果修改了Servlet後又會重新開始
※load-on-startup
<servlet> <servlet-name>ooo</servlet-name> <servlet-class>controller.HelloServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet>
※根據文件的101、102頁表示要打0以上(包括0)的整數,數字越小越優先載入
※只要有設就表示在server啟動時就會載入,不然就會等拜訪時才會載入
※如果多支都設一樣的數字不會錯,只是順序就不一定了
※Init Parameter
※可以定義初始的參數,web.xml如下設定
<servlet> <servlet-name>ooo</servlet-name> <servlet-class>controller.HelloServlet</servlet-class> <init-param> <param-name>p1</param-name> <param-value>xxx</param-value> </init-param> <init-param> <param-name>p2</param-name> <param-value>20</param-value> </init-param> </servlet>
※定義了p1和p2,可以很多
@Override public void init(ServletConfig config) throws ServletException { Enumeration<String> en = config.getInitParameterNames(); while(en.hasMoreElements()){ System.out.println("有參:" + en.nextElement()); } System.out.println("有參:" + config.getInitParameter("p1")); } @Override public void init() throws ServletException { Enumeration<String> en = getInitParameterNames(); while(en.hasMoreElements()){ System.out.println("無參:" + en.nextElement()); } System.out.println("無參:" + getInitParameter("p1")); }
※取值時,寫在init裡,但init有兩個,一個有參(Servlet)、一個無參(GenericServlet),都可以取的到值,但兩個都寫只會run到有參的
※如果名稱亂打,取不到,當然就是null
※annotation這樣子用
@WebServlet( urlPatterns = { "/ooo" }, loadOnStartup = 1, initParams = { @WebInitParam(name = "p1", value = "xxx"), @WebInitParam(name = "p2", value = "20") } )
沒有留言:
張貼留言