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;
}
※取不到登入者的帳號,可以這樣運用



沒有留言:
張貼留言