Tomcat和Servlet的版本對應和API可參考這篇
還有一個我覺得比較有用的spec在這,目前只看到3.0的,點進去後,選3.0,然後Maintenance Release的旁邊有個Download page,進去後還有個Download按鈕,再進去選接受,然後下載
另外還有高手翻譯好的版本在這裡
安裝好Tomcat後,Eclipse如下操作:
1.
2.Dynamic web module version為Servlet版本
3.保持預設即可
4.Context root在這裡可以改,預設和專案名稱一樣,最下面的web.xml最好是勾起來
5.完成圖,TestServlet是專案名稱,如果有勾web.xml就會出現在最下面,src為寫java的地方
6.在專案名稱按右鍵-->Properties,如下選擇後,可以修改Context root
7A-1.在src按右鍵New-->Class後,如下設定(也可以New-->Servlet用畫面設定,在下面的7B)
7A-2.完成後是個空的class,覆寫兩個方法
7A-3.覆寫doGet和doPost
7B-1.紅框的部分和7A-1一樣,綠框為預設的,一般都是繼承這個類別
7B-2.Description可打可不打,URL mappings預設是和Class name一樣,可以修改,也可以新增,像我新增了一個/ooo
7B-3.紅框的建構子大部分都用不到,Inherited abstract methods必須勾起來,下面的12個方法才能勾,看要覆寫哪個就勾哪個,上面的Interfaces是說,如果還有要implements的,可以在這Add
※Finish後,3.0之前(不含3.0)的會在web.xml加剛剛的資訊;3.0之後(含)會變成annotation
8.兩個方法修改如下:
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("-----Request-----"); System.out.println("Method=" + req.getMethod()); System.out.println("CharacterEncoding1=" + req.getCharacterEncoding()); System.out.println("ContentType=" + req.getContentType()); req.setCharacterEncoding("UTF-8"); System.out.println("CharacterEncoding2=" + req.getCharacterEncoding()); System.out.println("RequestURL=" + req.getRequestURL()); System.out.println("Scheme=" + req.getScheme()); System.out.println("ServerName=" + req.getServerName()); System.out.println("ServerPort=" + req.getServerPort()); System.out.println("ContextPath=" + req.getContextPath()); System.out.println("ServletPath=" + req.getServletPath()); System.out.println("pathInfo=" + req.getPathInfo()); System.out.println("RequestURI=" + req.getRequestURI()); System.out.println("QueryString=" + req.getQueryString()); System.out.println("\r\nParameterNames Start"); Enumeration<String> name = req.getParameterNames(); while (name.hasMoreElements()) { String n = name.nextElement(); System.out.println(n); System.out.println(req.getParameter(n) + "\r\n"); } System.out.println("ParameterNames End"); String[] sArray = req.getParameterValues("xxx"); if (sArray != null) { for (String s : sArray) { System.out.println(s); } } System.out.println("-----Response-----"); System.out.println("Status=" + resp.getStatus()); System.out.println("CharacterEncoding1=" + resp.getCharacterEncoding()); // resp.setCharacterEncoding("Big5"); System.out.println("設定contentType前=" + resp.getContentType()); resp.setContentType("text/html;charset=Big5"); System.out.println("設定contentType後=" + resp.getContentType()); System.out.println("CharacterEncoding2=" + resp.getCharacterEncoding()); PrintWriter out = resp.getWriter(); out.println("<html>"); out.println("<head>"); out.println("<title>first Servlet</title>"); out.println("</head>"); out.println("<body>"); out.println("Hello 第一支 Servlet!"); out.println("</body>"); out.println("</html>"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); }
※System.out.println會出現在eclipse的Console
※PrintWriter的println會印在網頁上
9.在WebContext按右鍵New-->JSP File-->檔名叫login.jsp-->Finish,內容如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <form action="xxx" method="get"> <input type="text" name="username" value="user" /><br /> <input type="password" name="password" value="pass" /><br /> <input type="radio" name="ooo" value="aaa" />apple<br /> <input type="radio" name="ooo" value="bbb" />banana<br /> <input type="radio" name="ooo" value="ppp" />pineapple<br /> <input type="checkbox" name="xxx" value="ttt" />tiger<br /> <input type="checkbox" name="xxx" value="rrr" />rabit<br /> <input type="checkbox" name="xxx" value="lll" />lion<br /> <input type="hidden" name="hid" value="中文" /><br /> <input type="text" name="reon" readonly="readonly" value="read" /><br /> <input type="text" name="died" disabled="disabled" value="disable" /><br /> <input type="reset" /><br /> <input type="submit" /> </form> </body> </html>
※先不要在WEB-INF下創建,它是個特殊的資料夾,使用者進不去的資料夾
10.Web.xml
<welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list>
※這是預設的welcome-file,表示伺服器啟動完畢後會run第一個網頁,沒有就run第二個,以此類推,都沒有就是404
開啟server後,網址是http://localhost:8080/TestServletXXX/,不管有沒有對應到,都是這個,沒有對應到就是404,對應到畫面會變,但網址不變,而我的jsp叫login.jsp,所以對應不到可以在後面加上login.jsp也是ok,只是差在網址不一樣
※在第5張圖點web.xml或Deployment Descriptor:TestServlet就可以開啟web.xml,因為web.xml又叫佈署描述檔
※在tomcat資料夾下的webapps\examples\WEB-INF\web.xml可以複製
<display-name>TestServlet</display-name> <welcome-file-list> <welcome-file>login.jsp</welcome-file> </welcome-file-list> <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>
※預設的welcome-file我都沒有,所以修改成一行
※當瀏覽器傳xxx進來時就會找到ooo,然後會去找servlet的servlet-name是ooo的servlet-class就連到後端了
※結果:
-----Request-----
Method=GET
CharacterEncoding1=null
ContentType=null
CharacterEncoding2=UTF-8
RequestURL=http://localhost:8080/TestServletXXX/xxx
Scheme=http
ServerName=localhost
ServerPort=8080
ContextPath=/TestServletXXX
ServletPath=/xxx
pathInfo=null
RequestURI=/TestServletXXX/xxx
QueryString=username=user&password=pass&hid=%E4%B8%AD%E6%96%87&reon=read
ParameterNames Start
username
user
password
pass
hid
中文
reon
read
ParameterNames End
-----Response-----
Status=200
CharacterEncoding1=ISO-8859-1
設定contentType前=null
設定contentType後=text/html;charset=Big5
CharacterEncoding2=Big5
※如果改成post,結果如下:
-----Request-----
Method=POST
CharacterEncoding1=null
ContentType=application/x-www-form-urlencoded
CharacterEncoding2=UTF-8
RequestURL=http://localhost:8080/TestServletXXX/xxx
Scheme=http
ServerName=localhost
ServerPort=8080
ContextPath=/TestServletXXX
ServletPath=/xxx
pathInfo=null
RequestURI=/TestServletXXX/xxx
QueryString=null
...以下和Get一樣
※中文會變成%xx,等同java.net.URLEncoder.encode("中文", "UTF-8"),相反的是
java.net.URLDecoder.decode("%E4%B8%AD%E6%96%87", "UTF-8")
※pathInfo目前是null,它顯示的是jsp的action,xxx對應servlet的路徑,它會顯示後面的路徑,
假設action="xxx/ooo/aaa",那麼pathInfo就是/ooo/aaa,但現在是完全對應,所以目前這樣打會404,後面會再說
※所以RequestURI是ContextPath+ServletPath+pathInfo
※QueryString是get時就是網址後面?後面的部分(不包括?),而post就是null
※注意事項
1.req.getParameterValues是針對checkbox用的,用req.getParameterNames抓出每一個name時,只會抓到第1個補充:還有getHeader(String)、getHeaders(String)(這個把它想像成getHeaderValues會比較好,官網命名的太爛)、getHeaderNames
2.jsp的action上面沒有「/」開頭
「xxx」是http://localhost:8080/TestServletXXX/xxx
「/xxx」是http://localhost:8080/xxx
也就是少了ContextPath
3.Servlet 3的新功能可以不用web.xml,用annotation的方式也可以,但兩者是可以並存的,所以第4張圖最好是勾起來,annotation如下設定就好了
@WebServlet(urlPatterns = { "/xxx" }) public class HelloServlet extends HttpServlet { // ...
也就是多個@WebServlet就搞定了,name可以不打
4.前端disabled的是沒有辦法傳到後端的,有經驗的應該都知道
5.Servlet Reloading:也就是改完程式後,不用重起server就會抓到新的程式碼的設定(要注意Console有跑才是有抓到)
Tomcat官網的左邊
左邊Documentation的Tomcat x.0
左邊Reference的Configuration
左邊Containers的Context
Common Attributes有個reloadable,預設是false
可以寫在context.xml(tomcat6以上(含)才有)的<Context>裡或者server.xml的<Host>裡面有可以放<Context>
我自己沒有在<Host>寫,但不知哪時被tomcat加上去了,如下:
<Context docBase="TestServlet" path="/TestServletXXX" reloadable="true" source="org.eclipse.jst.jee.server:TestServlet" />但這是針對一個專案設定
6.看Servlet API
javax.servlet.Servlet是介面
javax.servlet.GenericServlet是抽象類別,實作了Servlet,較重要的方法有init()、destroy() service(ServletRequest, ServletResponse)
javax.servlet.http.HttpServlet是抽象類別,繼承了GenericServlet
重要方法:
doGet(HttpServletRequest, HttpServletResponse) 瀏覽器、link、表單
doPost(HttpServletRequest, HttpServletResponse) 表單
doOptions(HttpServletRequest, HttpServletResponse):詢問server有哪些方法,也就是doXXX,這個沒那麼重要
service(ServletRequest, ServletResponse):這是覆寫的
service(HttpServletRequest req, HttpServletResponse resp):這是重載
當瀏覽器進來覆寫的service會收到,然後給重載的service,然後判斷是doXXX,最後將http資訊傳給它
javax.servlet.ServletRequest、javax.servlet.ServletResponse是介面
javax.servlet.http.HttpServletRequest、javax.servlet.http.HttpServletResponse是介面: resp有404、500...等狀態碼
servlet container(tomcat)實作了介面,所以可以直接用它的方法
繼承圖
所以一般都是繼承HttpServlet並覆寫doGet和doPost,測試時也有人繼承GenericServlet並覆寫service方法
※url-pattern 匹配規則
1.「/」開頭,「/*」結尾
2.副檔名匹配: *.xxx
3.空,只剩 url-pattern 標籤:context 不會有 index 頁面
4.「/」,當什麼都匹配不到,就會自動進來,但 context 還是 index 頁面
5.嚴格匹配:從頭到尾都一樣才可以
以上的 5 條, url-pattern 可以寫多個,但要注意以下兩點:
1.不可以將前兩條合成一個 /xxx/ooo/*.abc,伺服器可以啟動,但匹配不到
可以寫兩個 url-pattern,如 /xxx/ooo/* 和 *.abc,不過意思不一樣
2.「/*」什麼都匹配的到,不會有 index 頁面
「*」:伺服器無法啟動
.context 就是設定 context path 的路徑,可以為空
.http://localhost:8080/servletContext/ --> 只要沒配空或「/*」就會連到 index 頁面,tomcat 有個 conf/web.xml,如果伺服器沒有寫 welcome-file-list,就會以這裡為主,先找到先用
沒有留言:
張貼留言