web.xml
<web-app> <context-param> <param-name>abc</param-name> <param-value>111</param-value> </context-param> <context-param> <param-name>def</param-name> <param-value>222</param-value> </context-param> </web-app>
@WebServlet( urlPatterns = { "/xxx" }, loadOnStartup = 1, initParams = { @WebInitParam(name = "p1", value = "xxx"), @WebInitParam(name = "p2", value = "20") } ) // @WebInitParam(name = "bbb", value = "bbb") public class TestServletContextParam extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/plain; charset=Big5"); PrintWriter out = resp.getWriter(); out.println("Context Params"); ServletContext sc = getServletContext(); Enumeration<String> contextParams = sc.getInitParameterNames(); while (contextParams.hasMoreElements()) { String key = contextParams.nextElement(); out.println("key=" + key); out.println("value=" + sc.getInitParameter(key)); } out.println("this Servlet Params"); Enumeration<String> thisServletParams = getInitParameterNames(); while (thisServletParams.hasMoreElements()) { String key = thisServletParams.nextElement(); out.println("key=" + key); out.println("value=" + getInitParameter(key)); } } }
※結果:
Context Params
key=abc
value=111
key=def
value=222
this Servlet Params
key=p1
value=xxx key=p2 value=20
※上面是ServletContext的,下面是本身自己的
※再寫一支Servlet寫法一樣,但不要用annotation,web.xml也不要設定(只要設定路徑即可),這時會發現取得到ServletContext,而TestServletContextParam的初始化參數取不到
※註解那行寫了不會錯,但沒作用,API有寫說要配合@WebFilter或@WebServlet的
※annotation好像沒有設定ServletContext初始化參數的寫法
※HttpServletResponse方法
.父介面是ServletResponse※注意事項
BufferedReader in1 = req.getReader(); ServletInputStream in2 = req.getInputStream(); PrintWriter out1 = resp.getWriter(); ServletOutputStream out2 = resp.getOutputStream();
※會出例外,如:IllegalStateException: getReader() has already been called for this request
※in1和in2只能出現一個; out1和out2只能出現一個
※ContentType
resp.setContentType("text/html"); PrintWriter out1 = resp.getWriter(); resp.setContentType("image/gif"); ServletOutputStream out2 = resp.getOutputStream(); PrintWriter out = resp.getWriter(); ServletContext sc = req.getServletContext(); out.println(sc.getMimeType("*.jpg") + "<br />"); out.println(sc.getMimeType("abc.txt"));
※ContentType不知道要打什麼,可以用ServletContext的MimeType,給副檔名就會印出來了
※也可以打開Servers的web.xml,裡面可以複製
※而最好的方式是在Servers點兩下就會跳出如下的畫面,可以看出副檔是body、htm、html的mimeType都是text/html
※BufferSize
System.out.println("預設的BufferSize=" + resp.getBufferSize()); resp.setBufferSize(16 * 1024); System.out.println("設定後的BufferSize=" + resp.getBufferSize());
※單位是Byte,所以預設的會印出8192,最後印出16384
※主要是連網站有個緩衝,緩衝滿了會重新連線,所以如果感覺太慢了,可以適當的加大這個數字
※reset
PrintWriter out = resp.getWriter(); System.out.println("xxxA"); out.println("xxxB"); resp.reset(); System.out.println("oooA"); out.println("oooB"); resp.reset(); out.println("oooC");
※reset了兩次,所以只會印出oooC,是指out,控制台都能印出
※ContentLength
resp.setContentType("text/plain; charset=UTF-8"); resp.setContentLength(3); PrintWriter out = resp.getWriter(); out.println("一");
※回傳給網頁的大小,單位為B,而我印了一個中文字,且編碼是UTF-8,所以印的出「一」,但如果小於3,什麼都不會印出,如果打的是abcdef,那只會印出「abc」,有些人不知道為什麼,認為UTF-8是2個Byte,我這一篇可以證明
※sendError
resp.sendError(HttpServletResponse.SC_BAD_REQUEST); resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "xxx");
※sendError是個overloading,差在有沒有說明而已,
第一行的標頭會印出「HTTP Status 400 - 」,第二行會印出「HTTP Status 400 - xxx」
※resp.setStatus
1xx:Informational2xx:Successful
3xx:Redirection
4xx:Client Error
5xx:Server Error
維基百科有說明,我將它貼到這來,裡面有連結,可以連到這裡,才有上面那段
HTTP/1.1 200 OK
Date: Mon, 23 May 2005 22:38:34 GMT
Content-Type: text/html; charset=UTF-8
Content-Encoding: UTF-8
Content-Length: 138
Last-Modified: Wed, 08 Jan 2003 23:11:55 GMT
Server: Apache/1.3.3.7 (Unix) (Red-Hat/Linux)
ETag: "3f80f-1b6-3e1cb03b"
Accept-Ranges: bytes
Connection: close
<html>
<head>
<title>An Example Page</title>
</head>
<body>
Hello World, this is a very simple HTML document.
</body>
</html>
※最上面是Status Line
再來是Response Header
最後是Response Content,也就是HTML
Header還有很多可看另一頁,注意有分request和response
※setXXXHeader
setHeader(String, String); setIntHeader(String, int); setDateHeader(String, long); addHeader(String, String); addIntHeader(String, int); addDateHeader(String, long); containsHeader(String);
※設定標頭,可以設字串、數字、日期,使用set會蓋掉前面的;使用add會增加到原來的之後,containsHeader看名字叫知道了
※setHeader("text/html", "charset=utf-8");有沒有charset我忘了,因為很麻煩,所以有setContentType
※Refresh
<head> <meta http-equiv="Refresh" content="3"> </head> res.setHeader("Refresh", "3"); res.setHeader("Refresh", "3; URL=http://www.xxx.ooo");
※上面是HTML的寫法,下面是Servlet的寫法
※過程如下圖的上面,下面是待會要說的sendRedirect
※如果沒有URL,兩個都一樣,都是Servlet直接回傳
※sendRedirect
res.sendRedirect(String)是res.setStatus(resp.SC_MOVED_TEMPORARILY); // 302
+
res.setHeader("Location", location);
因為太麻煩,所以才有sendRedirect
sendRedirect(String):絕對、相對路徑(「/」的用意和form action的觀念一樣)都可以
setHeader:只能用絕對路徑
Object account = session.getAttribute("account"); if(account == null){ session.setAttribute("location", req.getRequestURI()); resp.sendRedirect(req.getContextPath() + "/login.jsp"); return; }
※取不到登入者的帳號,可以這樣運用
沒有留言:
張貼留言