æ¬ç³»åæç®ä»æåºç¡å¼å§ï¼è¯¦ç»ä»ç»j2eeå¼åææ¯çåçåç¸åºæ¡æ¶ï¼
    æ¬æä¾åæ¥èªå¦ä¸æç« ãJava Servlet ææ¯ç®ä»ãã
1 servlet ç®ä»
1.1 servlet çä½ç¨
å½ä½¿ç¨äº¤äºå¼ Web ç«ç¹æ¶ï¼æ¨æçå°çææå 容é½æ¯å¨æµè§å¨ä¸æ¾ç¤ºçãå¨è¿äºåºæ¯èåï¼æä¸ä¸ª Web æå¡å¨æ¥æ¶ä¼è¯ ä¸æ¥èªäºæ¨ç请æ±ï¼å¯è½è¦åæ¢å°å ¶ä»ä»£ç ï¼å¯è½ä½äºå ¶ä»æå¡å¨ä¸ï¼æ¥å¤ç该请æ±å访é®æ°æ®ï¼å¹¶çæå¨æµè§å¨ä¸æ¾ç¤ºçç»æã
servlet å°±æ¯ç¨äºè¯¥è¿ç¨çç½å®ï¼gatekeeperï¼ãå®é©»çå¨ Web æå¡å¨ä¸ï¼å¤çæ°æ¥ç请æ±åè¾åºçååºãå®ä¸è¡¨ç¤ºæ å ³ï¼å®é ä¸ä¹ä¸å®åºè¯¥ä¸è¡¨ç¤ºæå ³ãæ¨å¯ä»¥ä½¿ç¨ servlet ç¼åä¸ä¸ªæµï¼å°å 容添å å° Web 页é¢ä¸ï¼ä½é£é常ä¹ä¸æ¯ä¸ä¸ªå¥½åæ³ï¼å 为å®æé¼å±è¡¨ç¤ºä¸ä¸å¡é»è¾çæ··åçå¾åã
1.2 servlet çæ¿ä»£å
servlet ä¸æ¯æå¡äº Web 页é¢çæä¸æ¹å¼ã满足该ç®ççææ©ææ¯ä¹ä¸æ¯å ¬å ±ç½å ³æ¥å£ï¼CGIï¼ï¼ä½é£æ ·å°±è¦ä¸ºæ¯ä¸ªè¯·æ±æ´¾çä¸åçè¿ç¨ï¼å èä¼å½±åæçãè¿æä¸ç¨æå¡å¨æ©å±ï¼å¦ Netscape Server APIï¼NSAPIï¼ï¼ä½é£äºé½æ¯å®å ¨ä¸ç¨çãå¨ Microsoft çä¸çéï¼ææ´»å¨æå¡å¨é¡µé¢ï¼ASPï¼æ åãservlet 为ææè¿äºæä¾äºä¸ä¸ªæ¿ä»£åï¼å¹¶æä¾äºä¸äºå¥½å¤ï¼
å®ä»¬ä¸ Java è¯è¨ä¸æ ·æ¯ä¸å¹³å°æ å ³çã
å®ä»¬å 许æ¨å®å ¨è®¿é®æ´ä¸ª Java è¯è¨ APIï¼å æ¬æ°æ®è®¿é®åºï¼å¦ JDBCï¼ã
大å¤æ°æ åµä¸ï¼å®ä»¬å å¨å°æ¯ CGI æ´é«æï¼å 为 servlet 为请æ±æ´¾çæ°ç线ç¨ï¼èéä¸åçè¿ç¨ã
å¯¹äº servelet æä¸ä¸ªå¹¿æ³çè¡ä¸æ¯æï¼å æ¬ç¨äºææµè¡ç Web ååºç¨ç¨åºæå¡å¨ç容å¨ã
servlet æ¯å¯¹ä¸ä¸ç¼ç¨äººåå·¥å ·ç®±ç强大补å ã
1.3 ä½ä»ä¹æ¯ servletï¼
ä½ä¸ºä¸åä¸ä¸ç¼ç¨äººåï¼æ¨ç¢°å°ç大å¤æ° Java servlet é½æ¯ä¸ºååº Web åºç¨ç¨åºä¸ä¸æä¸ç HTTP 请æ±è设计çãå æ¤ï¼javax.servlet å javax.servlet.http å ä¸ç¹å®äº HTTP çç±»æ¯æ¨åºè¯¥å ³å¿çã
å¨å建ä¸ä¸ª Java servlet æ¶ï¼ä¸è¬éè¦åç±» HttpServletã该类ä¸çæ¹æ³å 许æ¨è®¿é®è¯·æ±åååºå è£ å¨ï¼wrapperï¼ï¼æ¨å¯ä»¥ç¨è¿ä¸ªå è£ å¨æ¥å¤ç请æ±åå建ååºã
å½ç¶ï¼HTTP åè®®ä¸æ¯ç¹å®äº Java çãå®åªæ¯ä¸ä¸ªè§èï¼å®ä¹æå¡è¯·æ±åååºç大è´å¼æ ·ãJava servlet ç±»å°é£äºä½å±çç»æå è£ å¨ Java ç±»ä¸ï¼è¿äºç±»æå å«ç便å©æ¹æ³ä½¿å ¶å¨ Java è¯è¨ç¯å¢ä¸æ´æäºå¤çãæ£å¦æ¨æ£ä½¿ç¨çç¹å® servlet 容å¨çé ç½®æ件ä¸æå®ä¹çï¼å½ç¨æ·éè¿ URL ååºä¸ä¸ªè¯·æ±æ¶ï¼è¿äº Java servlet 类就å°ä¹è½¬æ¢æä¸ä¸ª HttpServletRequestï¼å¹¶åéç» URL ææåçç®æ ãå½æå¡å¨ç«¯å®æå ¶å·¥ä½æ¶ï¼Java è¿è¡æ¶ç¯å¢ï¼Java Runtime Environmentï¼å°±å°ç»æå è£ å¨ä¸ä¸ª HttpServletResponse ä¸ï¼ç¶åå°å HTTP ååºéåç»ååºè¯¥è¯·æ±ç客æ·æºãå¨ä¸ Web åºç¨ç¨åºè¿è¡äº¤äºæ¶ï¼é常ä¼ååºå¤ä¸ªè¯·æ±å¹¶è·å¾å¤ä¸ªååºãææè¿äºé½æ¯å¨ä¸ä¸ªä¼è¯è¯å¢ä¸ï¼Java è¯è¨å°ä¹å è£ å¨ä¸ä¸ª HttpSession 对象ä¸ãå¨å¤çååºæ¶ï¼æ¨å¯ä»¥è®¿é®è¯¥å¯¹è±¡ï¼å¹¶å¨å建ååºæ¶åå ¶æ·»å äºä»¶ãå®æä¾äºä¸äºè·¨è¯·æ±çè¯å¢ã
容å¨ï¼å¦ Tomcatï¼å°ä¸º servlet 管çè¿è¡æ¶ç¯å¢ãæ¨å¯ä»¥é 置该容å¨ï¼å®å¶ J2EE æå¡å¨çå·¥ä½æ¹å¼ï¼èä¸æ¨å¿ é¡» é ç½®å®ï¼ä»¥ä¾¿å° servlet æ´é²ç»å¤é¨ä¸çãæ£å¦æ们å°çå°çï¼éè¿è¯¥å®¹å¨ä¸çåç§é ç½®æ件ï¼æ¨å¨ URLï¼ç±ç¨æ·å¨æµè§å¨ä¸è¾å ¥ï¼ä¸æå¡å¨ç«¯ç»ä»¶ä¹é´æ建äºä¸åº§æ¡¥æ¢ï¼è¿äºç»ä»¶å°å¤çæ¨éè¦è¯¥ URL 转æ¢ç请æ±ãå¨è¿è¡åºç¨ç¨åºæ¶ï¼è¯¥å®¹å¨å°å 载并åå§å servletï¼ç®¡çå ¶çå½å¨æã
å½æ们说 servlet å ·æçå½å¨ææ¶ï¼åªæ¯æå¨è°ç¨ servlet æ¶ï¼äºæ æ¯ä»¥ä¸ç§å¯é¢è§çæ¹å¼åççãæ¢è¨ä¹ï¼å¨ä»»ä½ servlet ä¸å建çæ¹æ³æ»æ¯æç¸åç次åºè¢«è°ç¨çãä¸é¢æ¯ä¸ä¸ªå ¸ååºæ¯ï¼
ç¨æ·å¨æµè§å¨ä¸è¾å ¥ä¸ä¸ª URLãWeb æå¡å¨é ç½®æ件确å®è¯¥ URL æ¯å¦æåä¸ä¸ªç±è¿è¡äºæå¡å¨ä¸ç servlet 容å¨æ管çç servletã
å¦æè¿æ²¡æå建该 servlet çä¸ä¸ªå®ä¾ï¼ä¸ä¸ªåºç¨ç¨åºåªæä¸ä¸ª servlet å®ä¾ï¼ï¼é£ä¹è¯¥å®¹å¨å°±å 载该类ï¼å¹¶å°ä¹å®ä¾åã
该容å¨è°ç¨ servlet ä¸ç init()ã
该容å¨è°ç¨ servlet ä¸ç service()ï¼å¹¶å¨å è£ ç HttpServletRequest å HttpServletResponse ä¸è¿è¡ä¼ éã
该 servlet é常访é®è¯·æ±ä¸çå ç´ ï¼ä»£è¡¨å ¶ä»æå¡å¨ç«¯ç±»æ¥æ§è¡æ请æ±çæå¡å¹¶è®¿é®è¯¸å¦æ°æ®åºä¹ç±»çèµæºï¼ç¶å使ç¨è¯¥ä¿¡æ¯å¡«å ååºã
å¦ææå¿ è¦ï¼å¨ servlet çæç¨çå½ç»ææ¶ï¼è¯¥å®¹å¨ä¼è°ç¨ servlet ä¸ç destroy() æ¥æ¸ é¤å®ã
1.4 å¦ä½âè¿è¡âservlet
âè¿è¡âservlet å°±åè¿è¡ Java ç¨åºä¸æ ·ãä¸æ¦é ç½®äºå®¹å¨ï¼ä½¿å®¹å¨äºè§£ servletï¼å¹¶ç¥éæäº URL ä¼è´ä½¿å®¹å¨è°ç¨è¯¥ servletï¼è¯¥å®¹å¨å°±å°æç §é¢å®ç次åºè°ç¨çå½å¨ææ¹æ³ãå æ¤ï¼è¿è¡ servlet 主è¦æ¯ææ£ç¡®é ç½®å®ï¼ç¶åå°æµè§å¨æåæ£ç¡®ç URLãå½ç¶ï¼servlet ä¸ç代ç æ£æ¯åç°æ趣çä¸å¡é»è¾çå°æ¹ãæ¨ä¸å¿ æ å¿ä½å±äºä»¶çè¿å±ï¼é¤éåçæç§é误ã
ä¸å¹¸çæ¯ï¼ç»å¸¸ä¼åç ä¸äºä»¤äººæ²®ä¸§çé误ï¼å°¤å ¶æ¯å¨è®¾ç½® servlet æ¶ãè´ä½¿ servlet åºç¨ç¨åºä»¤äººå¤´ççæ大åå å°±æ¯é ç½®æ件ãæ¨æ æ³ææå°è°è¯å®ä»¬ãæ¨åªè½éè¿è¯éæ³å¼æ¸ æ¥è¿äºé误ï¼æ¯å¦å°½åç ´è¯å¯è½ä¼æä¸ä¼å¨æµè§å¨ä¸çå°çé误æ¶æ¯ã
 2 servletå¼åä¾å
2.1 ä¸ä¸ªç®åçä¾å
2.1.1 è¿ä¸ªç®åç servlet è¦å®æçä»»å¡
第ä¸ä¸ª servlet å°å®ææå°éçå·¥ä½ï¼ä½æ¯å®å°æ´é²ç¼å servlet çææåºæ¬è¦æ±ãå®å°å¨æµè§å¨çªå£ä¸è¾åºä¸äºç®åçæ æ ¼å¼ææ¬ï¼
Hello, World!
2.1.2 声æç±»
servlet æ¯ä¸ä¸ªç±»ï¼å æ¤ï¼è®©æ们å建ä¸ä¸ªåºæ¬çãå¨ Eclipse ä¸ï¼è¦å¨ HelloWorld 项ç®ä¸å建ä¸ä¸ªå为 HelloWorldServlet çç±»ã该类å¦ä¸æ示ï¼
public class HelloWorldServlet extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter writer = response.getWriter();
writer.println("Hello, World!");
writer.close();
}
}
2.1.3 é ç½® Web åºç¨ç¨åº
å¨ Tomcat ä¸é ç½® Web åºç¨ç¨åºçæåä¸æ¥æ¯å建 web.xml æ件ï¼éè¦å°è¯¥æ件æ¾å¨é¡¹ç®ç WEB-INF ç®å½ä¸ãï¼æ³¨æï¼ä¸è¦ å°å ¶æ¾å¨ WEB-INF/src ç®å½ä¸ ââ 该ç®å½å°å å«å ¶ä»ä¸è¥¿ãï¼å¯¹äºè¿ä¸ªç®åä¾åï¼è¯¥æ件å°å¦ä¸æ示ï¼
<!DOCTYPE web-app PUBLIC '-//Sun Microsystems, Inc.//DTD
Web Application 2.3//EN' 'http://java.sun.com/dtd/web-app_2_3.dtd'>
<web-app>
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>HelloWorldServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
2.2 å¨ä½ servlet
2.2.1 ç®ä»
å¨ Web å¼ååæï¼è®¸å¤ä¸ä¸ç¼ç¨äººåé½ä¸å¾ä¸å¼æ¸ å½ä»ä»¬ç»§ç»æ¶ï¼å¦ä½è¾å¥½å°ä½¿ç¨ servletãææ®éçç»æä¹ä¸å°±æ¯å¨æå¡å¨ä¸æ´é² servletãæ¯ç§ç±»åç请æ±é½æä¸ä¸ªã
è¿å¾å¿«å°±åå¾ä»¤äººå¤´çï¼å æ¤ï¼ç¼ç¨äººåå¼å§å¨å ¶ servlet ä¸å å«æ¡ä»¶é»è¾ä½¿ä¹æ´å ·éåºæ§ï¼ä»¥ä¾¿å¤çå¤ç§ç±»åç请æ±ãä¸æ®µæ¶é´åï¼è¿ä¹äº§çäºä¸äºç³ç³ç代ç ãæä¸ç§æ´å¥½çæ¹å¼ï¼ç§°ä½å¨ä½ servletï¼action servletï¼ï¼å®å®ç°äºå为模å 2 çæ¦å¿µãæ®æäºè§£ï¼è¯¥ææ³æ¯ç± David M. Gearyï¼å ³äºä»çæ´å¤ä¿¡æ¯ï¼è¯·åé åèèµæï¼é¦æ¬¡åå°çï¼ä½æ¯å®å·²ç»è¾å¥½çç¨äºæµè¡ç servlet åºä¸äºï¼ä¾å¦ Jakarta Struts 项ç®ã
å¨å¨ä½ servlet ä¸ï¼å¹¶æ²¡ææ示 servlet è¡ä¸ºçæ¡ä»¶é»è¾ï¼èæ¯å ·æå¨ä½ï¼ç¼ç¨äººåå®ä¹çç±»ï¼ï¼servlet ææè¿äºç±»æ¥å¤çä¸åç±»åç请æ±ã大å¤æ°æ åµä¸ï¼è¿ä¸ªé¢å对象ï¼OOï¼çæ¹æ³è¦ä¼äºæ¥æå¤ä¸ª servletï¼æå¨ä¸ä¸ª servlet ä¸æå¤ä¸ª if æ¡ä»¶ã
2.2.2 æ们ç示ä¾å¨ä½ servlet æ§è¡çæä½
æ们ç示ä¾å¨ä½ servlet å°æ¯ä¸ä¸ªæç®åçãåºäºæµè§å¨çåºç¨ç¨åºçç½å®ï¼gatekeeperï¼ï¼è¯¥åºç¨ç¨åºå°å 许æ们å建ãåå¨ãæ¥ç以åå é¤ååå表项ãè¿äºè®°å½é¡¹çæ ¼å¼é½é常è¯å¥½ãæåï¼ä¸ºäºä½¿ç¨è¯¥åºç¨ç¨åºï¼ç¨æ·å°å¿ é¡»ç»å½å®ï¼ä½æ¯ï¼æ们ç¨åå°å¨ ç¨æ·åæ°æ® ä¸æ·»å è¿é¡¹åè½ã
2.2.3 表示
è¿æ¯ç«æ¯ä¸ç¯å ³äº servlet çæç¨ï¼å ä¹ä¸è¡¨ç¤ºæ å ³ãç¶èï¼è¥ä¸å¨å±å¹æå¤çå°ä¸äºç»æï¼æ们å®é ä¸å°±åªåç¥äºäºæ çé¨åå 容ãæ¨å½ç¶å¯ä»¥ç¼åæ ¹æ¬ä¸æ¶å表示ç servletï¼ä½æ¯å¤§å¤æ° Web åºç¨ç¨åºå¨æµè§å¨ä¸æ¾ç¤ºä¿¡æ¯ï¼è¿æå³çæ¨å¿ é¡»éæ©ä½¿ç¨ä¸ç§è¡¨ç¤ºæºå¶ãJavaServer Pages ææ¯å°±æ¯ä¸ç§å ¸åçå¤éæ¹æ¡ï¼å¹¶å¾å°äºå¹¿æ³éç¨ã
éè¿ JSP ææ¯ï¼æ¨å¯ä»¥å建å¨æ Web 页é¢ãå®ä»¬æ¯æéæ HTMLï¼æå ¶ä»æ è®°ï¼å¦ XMLï¼åå¨æ代ç å ç´ ï¼èæ£å¦ååæéå«çï¼å¨æ代ç å ç´ å¯ä»¥å¨æå建å 容ãå¨å¹åï¼å¯ä»¥éè¿è¯¸å¦ Tomcat ä¹ç±»ç容å¨å° JSP 页é¢ç¼è¯æ servletï¼å³è½¬æ¢æ Java 代ç ï¼ãç¶èï¼æ¨å ä¹æ°¸è¿ä¸å¿ å ³å¿è¿ä¸ç¹ãåªéè¦ç¥éåçäºä¸åæµç¨å³å¯ï¼
ç¨æ·å¨æµè§å¨ä¸è¾å ¥ URLï¼J2EE servlet 容å¨å°è¯¥æµè§å¨æåä¸ä¸ª servletã
servlet å®æå ¶å·¥ä½ï¼å¹¶å¨ä¼è¯ä¸è¾å ¥ä¿¡æ¯ï¼æè å¨ bean ä¸ï¼ååéç» JSP 页é¢ã
JSP 代ç è½¬æ¢ bean å/æä¼è¯ä¸çä¿¡æ¯ï¼å¹¶å°ååºåéç»æµè§å¨ã
æ¨å¯ä»¥å¾å®¹æå°å建ç®åç JSP 页é¢ï¼åªéè¦å¨ Web åºç¨ç¨åºä¸è¿è¡å¾®å°çä¿®æ¹å³å¯ï¼å¹¶ä¸æ éä¸è½½é¢å¤ç代ç åºï¼å°±å¯ä»¥å¨ Tomcat ä¸è¿è¡å®ä»¬ï¼å æ¤ï¼æ们å°å¨è¿é使ç¨å®ä»¬ï¼å ³äº JSP ææ¯çæ´å¤è¯¦ç»ä¿¡æ¯ï¼è¯·åé åèèµæï¼ã
æ们ç Contacts åºç¨ç¨åºä¼æä¸ä¸ªä¸»è¦ç JSP 页é¢ï¼å举ç°æçåå并添å æ°çååãç¨åï¼æ们å°æ·»å ç¨äºç»å½åéåºé¡µé¢ã
éè¦çæ¯è®°å¾ JSP ææ¯åªæ¯ä¸ç§è¡¨ç¤ºéæ©ãè¿æå ¶ä»æ¹æ³ãåå°æ大欢è¿çä¸ç§æ¹æ³æ¯ Jakarta Velocity 模æ¿å ï¼è¯·åé åèèµæï¼ãJSP ææ¯åå¨ä¸ä¸ªä¸»è¦çä¸è¶³ï¼å¤æçãåè½ä¸°å¯çåºç¨ç¨åºå¾åäºéè¦æå ¶å¤æç JSP 页é¢ï¼å¦ææ³ä½¿é»è¾ä¸è¡¨ç¤ºåå¼ï¼é£ä¹è¿éè¦è¿è¡é¢å¤çæå¡å¨å·¥ä½æ¥å建å®å¶æ ç¾ãå¦ä¸ä¸ªä¸è¶³å°±æ¯ JSP ææ¯ç»å¸¸å¸¦æ¥äºæ æ³æå¶ç诱æï¼å°ä¸å¡é»è¾å表示混åï¼è¿å®¹æ导è´éè¦ç¹éçç»´æ¤å·¥ä½çè弱系ç»ã
æ®æçæ¥ï¼JSP ææ¯å¸¸å¸¸æ¯ä¸ä¸ªé误çéæ©ï¼è Velocityï¼æè å ¶ä»æç§æ¨¡æ¿åæ¹æ³ï¼é常æ¯æ£ç¡®çãä½å¯¹äºæ们è¿ä¸ªç®åä¾åï¼JSP ææ¯å°èµ·ä½ç¨ï¼å¯ä»¥è¯´ææ们éè¦ä»ç»çæ¦å¿µãå¨è¿æ ·çç®åæ åµä¸ï¼å°ä¸ç¹ç¹é»è¾åä¸ç¹ç¹è¡¨ç¤ºæ··åæ¯å¯ä»¥æ¥åçãä½ä»ä¸ä¸çè§åº¦æ¥è¯´ï¼å¤æ°æ åµä¸ï¼è¿ç§åæ³æ¯ä¸ææºçï¼å³ä½¿è®¸å¤ç¼ç¨äººåé½è¿æ ·åã
2.2.4 web.xml æ件
为äºè®©æ们è½å¤ä½¿ç¨å°è¦å建ç JSP 页é¢ï¼æä»¬å¿ é¡»åè¯ Tomcat å¦ä½å¤ç该页é¢ãå æ¤ï¼æä»¬å¿ é¡»å¨ WEB-INF ç®å½ä¸å建ä¸ä¸ª web.xml æ件ãå¦ä¸æ示ï¼
<!DOCTYPE web-app PUBLIC '-//Sun Microsystems, Inc.//DTD
Web Application 2.3//EN' 'http://java.sun.com/dtd/web-app_2_3.dtd'>
<web-app>
<servlet>
<servlet-name>contacts</servlet-name>
<servlet-class>com.roywmiller.contacts.model2.ContactsServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>contacts</servlet-name>
<url-pattern>/index.htm</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>contacts</servlet-name>
<url-pattern>*.perform</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>jspAssign</servlet-name>
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
<init-param>
<param-name>logVerbosityLevel</param-name>
<param-value>WARNING</param-value>
</init-param>
<init-param>
<param-name>fork</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jspAssign</servlet-name>
<url-pattern>/*.jsp</url-pattern>
</servlet-mapping>
</web-app>
æ们为 HelloWorldServlet å建äºä¸ä¸ªåºæ¬ç web.xml æ件ï¼ä½æ¯å®é常å°ãéçåºç¨ç¨åºåå¾æ´å å¤æï¼web.xml æ件ä¹ä¸å¾ä¸åå¾æ´æºè½ã让æ们快éåæ该æ件ã
<servlet> æ ç¾ä¸º servlet æå®ä¸ä¸ªå«åï¼æ们å°å¨è¯¥æ件çå«å¤ä½¿ç¨å®ãå®è¿åè¯ Tomcat å®ä¾ååªä¸ªç±»ï¼ä»¥ä¾¿å¨å åä¸å建 servletãå¨æç Eclipse å·¥ä½åºä¸ï¼æåå»ºäº com.roywmiller.contacts.model2 å æ¥ä¿å该 servlet ç±»ãæ 论éè¦ä»ä¹ï¼é½å¯ä»¥è°ç¨æ们çå ï¼ä½æ¯å° servlet çè·¯å¾å¿ é¡»å¹é <servlet-class> å ç´ ä¸çå 容ãæ们å®ä¹ç第äºä¸ª servlet æ¯ä¸è½½ Tomcat æ¶é带çï¼æ¨ä¸å¿ ä¿®æ¹å®ãå®åªæ¯ JSP æ£å¨å¤çç servletã
<servlet-mapping> åè¯ Tomcat å½æ个 URL å°è¾¾æå¡å¨æ¶ï¼æ§è¡åªä¸ª servletãæ们è¿éæä¸ä¸ªæ å°ã第ä¸ä¸ªå° Web æå¡å¨æ¥æ¾çé»è®¤é¡µé¢ï¼<index.htm>ï¼æ å°å° servletã第äºä¸ªåè¯ Tomcat å°ä»¥ .perform ç»å°¾ç URL æ å°å° servletã该形å¼ç URL å°åè¯ servlet å®ç°åªä¸ªå¨ä½ï¼ç¨åï¼æ们å°æ´è¯¦ç»å°è®¨è®ºå ¶å·¥ä½æ¹å¼ï¼ã第ä¸ä¸ªæ å°åè¯ Tomcat ä½¿ç¨ JSP servlet æ¥å¤ç JSP 页é¢ã
2.2.5 JSP 页é¢çç¨æ·è§å¾
å¨æ们çç®åä¾åä¸ï¼æ们ä¸ä¼è±å¤ªå¤æ¶é´è°è®º JSP ææ¯ãJSP ææ¯å¯ä»¥ä½¿äºæ ç®åï¼ä¸ä¼é·å ¥ä¸è¬è¡¨ç¤ºçç»èä¸ï¼ç¹å«æ¯ä¸ä¼é·å ¥ JSP ææ¯ç»èä¸ãï¼æå ³çæ´å¤ä¿¡æ¯ï¼è¯·å次åé åèèµæãï¼æ们è¿ä¼å°ææäºæ æ¾ç½®å¨ä¸ä¸ªé¡µé¢ä¸ï¼å³ä½¿è¿æ ·åæäºä¸å¤ªç°å®ãè¿å°æ大ç¨åº¦å°åå°ä» ä» ä¸ºäºè¯´æå¦ä½ä½¿ç¨ servlet çéè¦æ¦å¿µèå¿ é¡»å建ç页é¢æ°ã
æ们çæå页é¢å°æ¾ç¤ºååå表ï¼è¿å°æ¥èªäºä¸ä¸ªå å«äºè¯¥å表ç对象ãå®è¿å°å å«ä¸ä¸ªç¨äºæ·»å æ°ååç表åã该页å°å¦å¾ 5 æ示ã
å¾ 5. ååå表页é¢
è½ç¶å¹¶éä¸ä»¶èºæ¯ä½åï¼ä½è¯¥é¡µå¨é¡¶é¨æç §è¯å¥½çæ ¼å¼æ¾ç¤ºäºææååãæ¯ä¸ä¸ªé¡µé¢é½æ Delete é¾æ¥ï¼ç¨æ·å¯ä»¥åå»å®æ¥å é¤ç¹å®çååã该表åå å«å称åå°åå¼å段ï¼ä»¥åå ³äºååç±»åï¼æ们çç®å示ä¾ä¸æ¯ family æ acquaintanceï¼çåéæé®ãè¿ä¸ªç®å页é¢å°å 许æ们æ¢ç´¢å¦ä½å¨ servlet åºç¨ç¨åºä½¿ç¨ç®åçå¨ä½æ¡æ¶ãå®è¿å°è®©æ们æ¢ç´¢å¦ä½å¨ç¨æ·ä¼è¯æé´ä½¿ç¨è¯·æ±ï¼ä»¥å对 servlet ä»æµè§å¨æ¥æ¶çå 容è¿è¡ååºã
ç°å¨ï¼æ们åå¤å建该页é¢ã
2.2.5 JSP 页é¢ç¼ç
ä¸é¢æ¯æ们ç JSP 页é¢ç代ç ï¼
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@ page import="java.util.*" %>
<%@ page import="com.roywmiller.contacts.model.*" %>
<html>
<head>
<title>Contacts List 1.0</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css">
body, table, hr {
color: black;
background: silver;
font-family: Verdana, sans-serif;
font-size: x-small;
}
</style>
</head>
<body>
<jsp:useBean id="contacts" scope="session"
class="com.roywmiller.contacts.model.ContactList"/>
<h2>Contact List 1.0</h2>
<hr size="2"/>
<table frame="below" width="100%">
<tr>
<th align="left"></th>
<th align="left">Name</th>
<th align="left">Street</th>
<th align="left">City</th>
<th align="left">State</th>
<th align="left">Zip</th>
<th align="left">Type</th>
</tr>
<%
List list = contacts.getContacts();
for (Iterator i = list.iterator(); i.hasNext();) {
Contact contact = (Contact)i.next();
%>
<tr>
<td width="100"><a href="removeContactAction.perform?id=<%= contact.getId()%>" target="_blank" rel="external nofollow"
>Delete</a></td>
<td width="200"><%=contact.getFirstname()%> <%=contact.getLastname()%></td>
<td width="150"><%=contact.getStreet()%></td>
<td width="100"><%=contact.getCity()%></td>
<td width="100"><%=contact.getState()%></td>
<td width="100"><%=contact.getZip()%></td>
<td width="100"><%=contact.getType()%></td>
</tr>
<%
}
%>
</table>
<br/>
<br/>
<br/>
<fieldset>
<legend><b>Add Contact</b></legend>
<form method="post" action="addContactAction.perform">
<table>
<tr>
<td>First Name:<td>
<td><input type="text" size="30" name="firstname"></td>
</tr>
<tr>
<td>Last Name:<td>
<td><input type="text" size="30" name="lastname"></td>
</tr>
<tr>
<td>Street:<td>
<td><input type="text" size="30" name="street"></td>
</tr>
<tr>
<td>City:<td>
<td><input type="text" size="30" name="city"></td>
</tr>
<tr>
<td>State:<td>
<td><input type="text" size="30" name="state"></td>
</tr>
<tr>
<td>Zip:<td>
<td><input type="text" size="30" name="zip"></td>
</tr>
<tr>
<td>Type:<td>
<td><input type="radio" size="30" name="type" value="family">
Family <input type="radio" size="30" name="type"
value="acquaintance"
checked> Acquaintance</td>
</tr>
</table>
<br/>
<input type="submit" name="addContact" value=" Add ">
</form>
</fieldset>
</body>
</html>
2.2.6 å建 servlet
æ们ç servlet ç±»ä¼¼äº HelloWorldServletï¼å¹¶æ·»å äºå¨ä½å¤çåè½ï¼
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.roywmiller.contacts.actions.Action;
public class ContactsServlet extends HttpServlet {
protected ActionFactory factory = new ActionFactory();
public ContactsServlet() {
super();
}
protected String getActionName(HttpServletRequest request) {
String path = request.getServletPath();
return path.substring(1, path.lastIndexOf("."));
}
public void service(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException {
Action action = factory.create(getActionName(request));
String url = action.perform(request, response);
if (url != null)
getServletContext().getRequestDispatcher(url).forward(request, response);
}
}
å°±å以åä¸æ ·ï¼æ们æ©å± HttpServlet 并éè½½ service() æ¹æ³ãå¨è¯¥æ¹æ³ä¸ï¼æ们ï¼
ä»å¯¼è´è°ç¨ servlet ç URL ä¸æ´¾çå¨ä½åã
åºäºè¯¥å称å®ä¾åæ£ç¡®çå¨ä½ã
åè¯è¯¥å¨ä½å¼å§æ§è¡ã
å°ååºåéç»å¨ä½ææåç URLã
æ们ä»å¯¼è´è°ç¨ servlet ç URL ä¸æ´¾çå¨ä½åï¼è该 servlet æ¯ä» request.servletPath() è·å¾çã请记ä½ï¼å¯¼è´æ们è°ç¨å¨ä½çææ URL é½å ·æ *.perform çå½¢å¼ãæ们å°è§£æ该形å¼æ¥è·å¾åç¹å·¦è¾¹çå符串ï¼è¯¥å符串就æ¯å¨ä½åï¼ç¶åå°è¯¥å¨ä½åä¼ éç» ActionFactoryï¼ä»¥å®ä¾åæ£ç¡®çå¨ä½ãç°å¨ï¼æ¨çå°æ们为ä½åè¯ Web åºç¨ç¨åºå¦ä½å¤ç该形å¼ç URLï¼ä»¥å为ä½å¨ JSP 页é¢ä¸ä½¿ç¨è¿äºâç¥å¥âçå符串ãæ£æ¯å 为è¿æ ·ï¼æ们æå¯ä»¥å¨è¿é对å®ä»¬è¿è¡è§£ç ï¼å¹¶éå对æ们æå©çå¨ä½ãæä»ä¹æ¿ä»£æ¹æ¡ï¼å¤§éç if è¯å¥å大éçéå 代ç ãæ£å¦æ们å°çå°çï¼éè¿å¨ä½ï¼éè¦æ§è¡çæ¯ä¸ªå¨ä½é½å·²å®å ¨å°è£ ã
è¿æ ·åå¾å¥½ï¼ä½æ¯æ们éè¦ä¸äºéå ç±»æ¥å®æ该任å¡ãè¿å°±æ¯å¨ä½æ¡æ¶è¦åçäºã
2.2.7 ç®åçå¨ä½æ¡æ¶
æ们çç®åå¨ä½æ¡æ¶æ 4 个主è¦ç»ä»¶ï¼
ActionFactoryã该工åå°è¯·æ±ä¸çå¨ä½å转æ¢æ servlet å¯ä»¥ç¨æ¥å®æå ¶å·¥ä½çå¨ä½ç±»ã
Action æ¥å£ã该æ¥å£å®ä¹ææå¨ä½çæå ¶ç®åçå ¬å ±æ¥å£ã
å为 ContactsAction çæ½è±¡ç±»ã该类å®ç°äºææå¨ä½å ±ç¨çä¸ä¸ªæ¹æ³ï¼å¹¶å¼ºå¶åç±»å®ç°å¦ä¸ä¸ªæ¹æ³ï¼perform()ï¼ã
ContactsAction çä¸ä¸ªåç±»ãè¿äºå类使 servlet è½å¤è¿è¡èªæå¼å¯¼ãæ·»å æ°åååå é¤ååã
å¨ servlet ç service() æ¹æ³ä¸ï¼è¯¥è¿ç¨ä»¥ ActionFactory å¼å§ã
2.2.7.1 ActionFactory
ä¸é¢æ¯æ们ç ActionFactoryï¼
import java.util.HashMap;
import java.util.Map;
import com.roywmiller.contacts.actions.Action;
import com.roywmiller.contacts.actions.AddContactAction;
import com.roywmiller.contacts.actions.BootstrapAction;
import com.roywmiller.contacts.actions.RemoveContactAction;
public class ActionFactory {
protected Map map = defaultMap();
public ActionFactory() {
super();
}
public Action create(String actionName) {
Class klass = (Class) map.get(actionName);
if (klass == null)
throw new RuntimeException(getClass() + " was unable to find
an action named '" + actionName + "'.");
Action actionInstance = null;
try {
actionInstance = (Action) klass.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return actionInstance;
}
protected Map defaultMap() {
Map map = new HashMap();
map.put("index", BootstrapAction.class);
map.put("addContactAction", AddContactAction.class);
map.put("removeContactAction", RemoveContactAction.class);
return map;
}
}
ActionFactory æå ¶ç®åãå®æä¸ä¸ª Map å¨ä½ç±»åå ¶å称ãæ们å¨é¡µé¢ä¸ä½¿ç¨è¯¥å称åè¯ servlet æ§è¡åªä¸ªå¨ä½ãæ¬ä¾ä¸ï¼æ们æä¸ä¸ªå¨ä½ï¼
BootstrapAction
AddContactAction
RemoveContactAction
è®°å¾è¦åå«éè¿ Add 表åå Delete é¾æ¥ï¼å°æ·»å åå é¤ååçå¨ä½ä½ä¸º URL åéç» servletãBootstrapAction ä» ä» éç¨äºå° /index.htm è°ç¨è³æ们çå¨ä½æ¡æ¶ä¸ã
å½åè¯è¯¥å·¥åå建 Action æ¶ï¼å®å°å®ä¾å该类ï¼å¹¶æå®éåå®ä¾ãå该工åæ·»å æ°å¨ä½å ¶å®å°±æ¯ç®åå°ä¸ºè¯¥å¨ä½å建ä¸ä¸ªç±»ï¼ç¶åå¨å·¥åçå¨ä½ Map ä¸æ·»å æ°çæ¡ç®ã
2.2.7.2 Action
Action æ¥å£å¦ä¸æ示ï¼
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public interface Action {
public String perform(HttpServletRequest request, HttpServletResponse response);
public void writeToResponseStream(HttpServletResponse response, String output);
}
ç°å¨ï¼æ们å°å¹¿æ³ä½¿ç¨çæ¹æ³æ¯ perform()ãèå¦ä¸æ¹æ³ï¼writeToReponseStream() å 许å¨ä½ç´æ¥åå ¥ååºçè¾åºæµï¼ä»¥ä¼ éç» JSP 页é¢ãåå ¥çä»»ä½å 容ï¼ææ¬ãHTML çï¼é½å°å¨è¯¥é¡µé¢ä¸æ¾ç¤ºãæ们ææ¶ä¸éè¦ä½¿ç¨è¯¥æ¹æ³ï¼ä½æ¯ï¼æ¨å¯ä»¥å¨ ContactsAction ä¸è·å¾å®ï¼ä»¥æ¥çå®å¦ä½å·¥ä½ãè®°å¾æä»¬å¨ HelloWorldServlet é使ç¨äºè¯¥æ¹æ³ä½ä¸ç代ç ï¼å æ¤ï¼æ¨ä¸ä¼å¯¹å®æå°éçã
2.2.7.3 ç¨ BootstrapAction å¯å¨
æ们æ¥æç ContactsAction çæç®åçåç±»æ¯ BootstrapActionï¼å®æ¯å ¶ä»åç±»çä¸ä¸ªå¥½æ¨¡åï¼
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class BootstrapAction extends ContactsAction {
public String perform(HttpServletRequest request, HttpServletResponse response) {
return "/" + "contactList.jsp";
}
}
å ¶ä»æ·»å åååå é¤ååç代ç ï¼å¨è¿éå°±ä¸è´´äºï¼æå ´è¶£çå°åæå»æ¾ï¼
2.2.8 è¿è¡åºç¨ç¨åº
å¦æ好å¥å¿è¿æ²¡æå ä¸é£ï¼é£ä¹æ¨ç°å¨å°±åºè¯¥è¿è¡è¿ä¸ªåºç¨ç¨åºï¼ççå®æ¯å¦ä½å·¥ä½çã
å¯å¨æµè§å¨ï¼å¹¶è¾å ¥ä¸å URLï¼
http://localhost:8080/contacts/
å¦æ Tomcat è¿è¡æ£ç¡®ï¼æ¨å°±åºæ¥ç contactList.jspï¼å ¶å表ä¸æ²¡æååãå¨ add 表åä¸çææ¬å段ä¸è¾å ¥ä¸äºå¼ï¼ç¶å并åå» Add æé®ãæ¨å°å¨è¯¥å表ä¸çå°æ°çååï¼è¯¥ååå称ç左边æä¸ä¸ª Delete é¾æ¥ãé¤éæ¨ä¿®æ¹å®ï¼å¦åå ¶ç±»åå°è®¾ä¸º Acquaintanceï¼åéé®çé»è®¤ç±»åéæ©ï¼ã为äºç®ä¾¿èµ·è§ï¼æ们没æ对该表åè¿è¡ä»»ä½éªè¯ï¼å æ¤ï¼æ¨å¯ä»¥è¾å ¥ææå段å¼å®å ¨ç¸åçå¤ä¸ªååãæ¯ä¸ªååé½æä¸ä¸ªæä¸ç IDï¼å æ¤ï¼æ¯ä¸ªååå°åå¼æ¾ç¤ºï¼æ¨å¯ä»¥é个å é¤å®ä»¬ã
说å¾ç®åç¹ ââ æ们æäºä¸ä¸ªå®ç¨ç Web åºç¨ç¨åºï¼ä½æ们æ æ³ä¿åååå表ï¼å æ¤ï¼æ¯å½å¯å¨è¯¥åºç¨ç¨åºæ¶ï¼æ们é½å¿ é¡»éæ°è¾å ¥å®ä»¬ãæ´ç³çæ¯ï¼è¯¥åºç¨ç¨åºçæ¯ä½ç¨æ·é½æç¸åçååå表ãæ们æ¯å¯ä»¥éè¿æ·»å 对äºæä¸ç¨æ·çæ¯æï¼ä»¥åéè¿å¨æ件ä¸åå¨æ°æ®ï¼å¯ä»¥å·¥ä½çæç®åçæ°æ®åºï¼ï¼æ¥è§£å³è¿äºé®é¢ãå¨ä¸ä¸å°èä¸ï¼æ们å°å®æè¿ä¸¤é¡¹å·¥ä½ã
2.3 ç¨æ·åæ°æ®
2.3.1 å¢å¼ºåºç¨ç¨åº
å¨è¿ä¸å°èä¸ï¼æ们å°å¯¹ä»£ç åç°æç JSP 页é¢è¿è¡å°ééæï¼refactorï¼ï¼ä»¥ä¾¿è½ä¸ºæä¸çç¨æ·å¤çæä¹ åå¨çååæ°æ®ãç®è¨ä¹ï¼æ们è¿è¡ä¸åå·¥ä½ï¼
- å建ä¸ä¸ª ContactsUser 对象ã
- 为æ¯ä¸ª ContactsUser æä¾ç¨æ·åãå¯ç åååå表ã
- ä¿®æ¹ JSP 页é¢ç <jsp:useBean/> æ ç¾ä»¥ä½¿ç¨ ContactsUserã
- æ·»å login.jsp ä½ä¸ºè¯¥åºç¨ç¨åºç第ä¸é¡µã
- ä¿®æ¹ contactList.jspï¼ä¸ºç»å½ç¨æ·æä¾å好ç欢è¿æ¶æ¯ã
- å contactList.jsp æ·»å Logout é¾æ¥ï¼ç¶åè°ç¨ LogoutActionã
- æ·»å goodbye.jsp æ¥æ¾ç¤ºä¸ªæ§åçåè§æ¶æ¯ã
- æ·»å LoginAction å LogoutActionã
- æ·»å UsersDatabase æ¥å¤ç usersDatabase.txt ä¸ Contacts çåå¨åæ£ç´¢ã
- éè¿éè½½ servlet ä¸ç init() åå§å ContactsDatabaseã
- éè½½ servlet ä¸ç destroy()ï¼åè¯ UsersDatabase å ³é usersDatabase.txtã
å®é ä¸å¹¶éå¦æ¤ç³ç³ãæä¸çæ£è¾æ°çæ¦å¿µæ¯ä½¿ç¨æ件ï¼åªæ¯æ´å¤æ å Java è¯è¨å·¥ä½ï¼ä»¥åæåæ°é¡µé¢ãææå¨ä½å¤çæºå¶é½æ¯ç¸åçãè¿è¯´æå¨ä½æ¡æ¶çåè½å¼ºå¤§ï¼èå建该æ¡æ¶åªéè¦è±è´¹ä¸ç¹ç¹å®è´µçæ¶é´ãå®å®å ¨ä¸å Jakarta ç Struts æ¡æ¶é£æ ·å¤æï¼è¯·åé åèèµæï¼ï¼å° Struts æ¡æ¶ç¨äºåºç¨ç¨åºä¸æè¿è¡çå·¥ä½å¯è½æç¹å°é¢å¤§åã
2.3.2 ContactsUser
å é¤å¯¼å ¥è¯å¥åååç¨åºä¹åï¼ContactsUser 对象å°å¦ä¸æ示ï¼æ¨å¯ä»¥å¨ contacts.jar ä¸æ¾å°å®æ´çæºä»£ç ï¼ï¼
public class ContactsUser {
protected String username = "";
protected String password = "";
protected List contactList = new ArrayList();
public ContactsUser() {
}
public ContactsUser(String username, String password, List contactList) {
this.username = username;
this.password = password;
this.contactList.addAll(contactList);
}
public boolean hasContacts() {
return !contactList.isEmpty();
}
public void addContact(Contact aContact) {
contactList.add(aContact);
}
public void removeContact(Contact aContact) {
contactList.remove(aContact);
}
public void removeContact(int id) {
Contact toRemove = findContact(id);
contactList.remove(toRemove);
}
protected Contact findContact(int id) {
Contact found = null;
Iterator iterator = contactList.iterator();
while (iterator.hasNext()) {
Contact current = (Contact) iterator.next();
if (current.getId() == id)
found = current;
}
return found;
}
accessors...
}
该类ä¿ååºç¨ç¨åºç¨æ·çæå ³ä¿¡æ¯ãè¿é常就æ¯å®æè¦åçææå·¥ä½ãå®ä¿åç¨æ·çç¨æ·ååå¯ç ï¼å¹¶ç»´æ¤è¯¥ç¨æ·çååå表ãå®å 许å¨ä½æ¡æ¶ä¸çåç§å¨ä½ä¸ºè¯¥ç¨æ·æ·»å åå é¤ Contactãå¨è¿éï¼ä¸å¸¦åæ°çæé å½æ°è¢«ç¨äºåå æµè¯ãå¦ä¸ä¸ªæ¥æ¶ä¸ä¸ªåæ°çæé å½æ°ææ¯åºç¨ç¨åºç¨æ·æ使ç¨çã
æ¨å¯è½ä¼é®èªå·±ï¼â该类为ä½æ²¡æä¸ä¸ª ContactList å®ä¾åéå¢ï¼âæ¯ç«ï¼æ们æ©å è±å夫å建äºè¿æ ·ä¸ä¸ªå®ä¾ãæ们为ä½ä¸ä½¿ç¨å®å¢ï¼çæ¡å¾ç®åï¼æ们å®é ä¸ä¸åéè¦è¯¥ç±»ãå®å è£ äºä¸ä¸ª ArrayListï¼å¹¶ä¸ºæ们æä¾äºä¸äºè¾ å©æ¹æ³ãè¿äºè¾ å©æ¹æ³å®é å¨ ContactUser ä¸æ´ææä¹ãå¦ææ们使ç¨äº ContactListï¼åéè¦éè¿æ¥æç¸åå称以åéè¦å®æç¸åäºæ ç ContactUser æ¥è°ç¨å®ä¸é¢çæ¹æ³ãä¾å¦ï¼å¦æ ContactUser æ¥æä¸ä¸ª ContactListï¼å¹¶ä¸å°è¯¥å®ä¾åéå½å为 contactListï¼é£ä¹ addContact() å°å¦ä¸æ示ï¼
public void addContact(Contact aContact) {
contactList.addContact(aContact);
}
å¨è¿éå¯¹å ¶ä»å¯¹è±¡è¿è¡æææäºæè ¢ãå æ¤ï¼æ们å é¤äº ContactList ç±»ãé£æ£æ¯éæè¦åçå ¨é¨å·¥ä½ãæ们ç®åäºä»£ç ï¼å¹¶åå°äºç³»ç»ä¸ç±»çæ°ç®ï¼ä½ä»è½å®æç¸åçä»»å¡ãæ¥æ ContactList æ¯å建系ç»æ¶çä¸é´æ¥éª¤ãå®å 许æ们å¯å¨å¹¶è¿è¡ç³»ç»ï¼å¹¶å¸®å©æ们å建å¨ä½æ¡æ¶ãç¶åï¼å®çææ寿å½å°±ç»æäºï¼æ们å°å é¤å®ãç¼åä¸äºä»£ç 并ä¸ä»£è¡¨æ¨å¿ 须永è¿ç»´æ¤å®ä»¬ã
2.3.3 ä¿®æ¹ contactList.jsp
ä¿®æ¹ JSP 页é¢æ¥ä½¿ç¨æ°ç ContactUser ååç®åãæ们éè¦è¿è¡ä¸å¤ä¿®æ¹ã
第ä¸å¤å°±æ¯ä¿®æ¹ <jsp:useBean> æ ç¾ï¼å¦ä¸æ示ï¼
<jsp:useBean id="user" scope="session"
class="com.roywmiller.contacts.model.ContactsUser"/>
ç°å¨ï¼é¡µé¢å°å®ä¾å ContactsUserï¼èé ContactListã
第äºå¤ä¿®æ¹å°±æ¯æ´æ°é¡µé¢ä¸ç表è¡æ建é»è¾ï¼ä»¥ä½¿ç¨æ°ç user åéï¼
<%
List list = user.getContacts();
for (Iterator i = list.iterator(); i.hasNext();) {
Contact contact = (Contact)i.next();
%>
第ä¸å¤ä¿®æ¹å°±æ¯ä¸ºç¨æ·æ·»å ä¸ä¸ªéåºé¾æ¥ï¼
<a href="logoutAction.perform" target="_blank" rel="external nofollow" >Logout</a>
æ们å°è¯¥é¾æ¥ç½®äºâContacts 1.0â头æè¾¹ãå½ç¨æ·åå»è¯¥é¾æ¥æ¶ï¼servlet å°æ§è¡ LogoutActionã
2.3.4 æ·»å ç»å½/éåºé¡µé¢
ä¸å ¶ä»é¡µé¢ç¸æ¯ï¼æ¯æç»å½åéåºç页é¢é½ååç®åãæä¸çå·®å«åå¨äº <body> æ ç¾ä¸ãä¸é¢æ¯ login.jspï¼
<body>
<h2>Contact List 1.0</h2>
<hr size="2"/>
<fieldset>
<legend><b>Please Login</b></legend>
<form method="post" action="loginAction.perform">
<table>
<tr>
<td>Username:<td>
<td><input type="text" size="30" name="username"></td>
</tr>
<tr>
<td>Password:<td>
<td><input type="text" size="30" name="password"></td>
</tr>
</table>
<br/>
<input type="submit" name="login" value=" Login ">
</form>
</fieldset>
</body>
该页é¢æä¸ä¸ªè¡¨åï¼å ¶ä¸å¸¦æ两个ææ¬å段åä¸ä¸ªæ交æé®ãå½ç¨æ·åå» Login æ¶ï¼servlet å°æ§è¡ LoginActionã
ä¸é¢æ¯ goodbye.jspï¼
<body>
<jsp:useBean id="user" scope="session"
class="com.roywmiller.contacts.model.ContactsUser"/>
<h2>Contact List 1.0</h2>
<hr size="2"/>
Goodbye <%= user.getUsername() %>!
</body>
该页é¢è°ç¨ ContactsUser bean ä¸ç getUsername() æ¥æ¾ç¤ºä¸ªæ§åçåè§æ¶æ¯ã
å½ç¨æ·ç¨ä¸ä¸ªæ°æ®åºä¸æ²¡æçç¨æ·åå°è¯ç»å½æ¶ï¼åºç¨ç¨åºå°æ¾å¼ç»å½ï¼å¹¶å°ç¨æ·æåä¸ä¸ªé误页é¢ï¼å¦ä¸æ示ï¼
<body>
<h2>Contact List 1.0</h2>
<hr size="2"/>
<fieldset>
<legend><b>Error</b></legend>
There was an error: <%= session.getAttribute("errorMessage") %>
</fieldset>
</body>
è¿æ¯æ们æ¥æçæç®åç页é¢ãå®ä½¿ç¨å¯ä»ææ JSP 页é¢è·å¾çé»è®¤ session åéæ¥æ¾ç¤ºåºéæ¶æ¯ã
2.3.5 æ·»å LoginAction
LoginAction ç±»å¦ä¸æ示ï¼
public class LoginAction implements Action {
public String perform(HttpServletRequest request, HttpServletResponse response) {
String username = request.getParameter(USERNAME);
String password = request.getParameter(PASSWORD);
ContactsUser user = UserDatabase.getSingleton().get(username, password);
if (user != null) {
ContactsUser contactsUser = (ContactsUser) user;
request.getSession().setAttribute("user", contactsUser);
return "/contactList.jsp";
} else
request.getSession().setAttribute("errorMessage",
"Invalid username/password.");
return "/error.jsp";
}
}
该å¨ä½ä»è¯·æ±ä¸æå username å password åæ°ï¼ç¶åç¨ username/password ç»åæ¥çæ°æ®åºä¸æ¯å¦å å«è¯¥ç¨æ·ãå¦æåå¨è¯¥ç¨æ·ï¼é£ä¹å°±å°è¯¥ç¨æ·ç½®äºä¼è¯ä¸ï¼å¹¶ç´æ¥è¿å ¥ contactList.jspãå¦ææ°æ®åºä¸æ²¡æ该ç¨æ·ï¼é£ä¹å°±å¨ä¼è¯ä¸è®¾ç½®ä¸æ¡åºéæ¶æ¯ï¼å¹¶è½¬è³ error.jspã
ç°å¨ï¼æ·»å å¨ä½å¯¹äºæ们èè¨åºè¯¥å¾å®¹æäºãæ们åå¨ä½å·¥åæ·»å ä¸ä¸ªæ¡ç®ï¼å¦ä¸æ示ï¼
map.put("loginAction", LoginAction.class);
å¨è®¾ç½®å¥½é¡µé¢ä¹åï¼å·¥åä¼æç¥æ°å¨ä½ï¼æ·»å æä½ä¹å°±å®æäºãæ¨åºè¯¥è½å¤è¿è¡è¯¥åºç¨ç¨åºï¼å¹¶çå°ç»å½é¡µé¢ãå½è¾å ¥ç¨æ·ååå¯ç æ¶ï¼ä¸ç®¡è¾å ¥çæ¯ä»ä¹ï¼æ¨é½ä¼çå°åºé页é¢ãçä¸ä¼å¿ä¹åï¼æ¨å°±å¯ä»¥éè¿ææçç¨æ·ååå¯ç ç»å½ï¼å¹¶çå°å å«ç©ºååå表ç contactList.jspã
2.3.6 æ·»å LogoutAction
LogoutAction ç±»å¦ä¸æ示ï¼
public class LogoutAction implements Action {
public String perform(HttpServletRequest request, HttpServletResponse response) {
UserDatabase.getSingleton().shutDown();
return "/goodbye.jsp";
}
}
å¨è¿éï¼æ们å°åè¯æ°æ®åºæ§è¡ shutDown() æä½ãUserDatabase ä¸çæ¹æ³å¦ä¸æ示ï¼
public void shutDown() {
writeUsers();
}
protected void writeUsers() {
StringBuffer buffer = new StringBuffer();
Collection allUsers = users.values();
Iterator iterator = allUsers.iterator();
while (iterator.hasNext()) {
ContactsUser each = (ContactsUser) iterator.next();
UserRecord record = new UserRecord(each);
buffer.append(record.getFullRecord());
}
writeText(buffer.toString());
}
protected synchronized void writeText(String text) {
Writer writer = null;
try {
writer = new FileWriter(usersFile.getAbsolutePath());
writer.write(text);
} catch (Exception e) {
throw new RuntimeException("Unable to append to file.", e);
} finally {
closeWriter(writer);
}
}
shutDown() è°ç¨ writeUsers()ï¼è¯¥æ¹æ³å°è¿ä»£å åä¸ä¿åçææç¨æ·ï¼å½ servlet 对èªèº«è¿è¡åå§åæ¶ï¼å°ä»æä»¬è¯»å ¥è¯¥æ件çå°æ¹å¼å§ï¼ï¼ä¸ºæ¯ä¸ªç¨æ·å建ä¸ä¸ª UserRecordï¼ç¶åå°å®æ´çåç¬¦ä¸²ä¼ éç» writeText()ãwriteText() å°è¯¥å符串åå ¥æ件ä¸ï¼éåç°æçå 容ãUserRecord ç±»æ¯ä¸ä¸ªæ好çè¾ å©ç±»ï¼å°è£ äºæ件ä¸æ¯æ¡ç¨æ·è®°å½çææç¦æçæ è®°å·¥ä½ãæ¨å¯ä»¥èªå·±æ£æ¥ä»£ç ï¼å ³äºå®æ´çæºä»£ç æ¸ åï¼è¯·åé contacts.jarï¼ã
ä¸æ¦å ³éæ°æ®åºï¼å°±å¯ä»¥åè¯ servlet åé goodbye.jspï¼æ¾ç¤ºä¸ªæ§åçåè§ã
2.4 userDatabase.txt æ件
大å¤æ° Web åºç¨ç¨åºä»æç§âæ°æ®åºâä¸è®¿é®æ°æ®ã许å¤é½ä½¿ç¨è¡ä¸çº§ï¼industrial-strengthï¼ç RDBMSï¼ä½ææ¬æ件ä¹å¯ä»¥æ¯æ°æ®åºãå®æ¯å¯ä»¥å·¥ä½çæç®åçæ°æ®åºãå¦ææ¨å°å®å è£ å¾å¾å¥½ï¼å¹¶å°è®¿é®ç»èéèå¨ä¸ä¸ªæ¥å£ä¹åï¼è该æ¥å£ä½¿å¾åºç¨ç¨åºä¸çå ¶ä»ç±»ææäºè®¿é®è¿äºæ°æ®ï¼é£ä¹åºå±æ°æ®éç¨ä»ä¹æ ·çåå¨å½¢å¼å®é ä¸å°±æ²¡ä»ä¹å ³ç³»ã
å¨è¿ä¸ªåºç¨ç¨åºä¸ï¼æ们å°ä½¿ç¨ä¸ä¸ªææ¬æ件ã该æ件å°æç §ä¸åå½¢å¼ï¼ä¸ºæ¯ä½ç¨æ·ä¿åä¸è¡ï¼
username password comma-delimited contact1 info|comma-delimited contactN info|...
该æ件ä¸çç¨æ·åå°æ¯ææï¼ä½åºäºå®å ¨èèï¼å¯ç å°æ¯ Base64 ç¼ç ï¼ç»å¯¹æç®åï¼ãååæ¡ç®å°ç¨éå·åéãèååæ¬èº«å°éè¿ | å符åéãè¿ç§æ ¼å¼æ²¡æä»ä¹ç¹å«ãå®åªæ¯æ§è¡æ们éè¦å®å®æçå·¥ä½ï¼ä»¥å 许æ们æäºè§£æ该æ件ã
为äºæ¹ä¾¿ï¼æ们å°è¯¥æ件æ¾ç½®å¨æ¬é¡¹ç®çæ ¹ç®å½ä¸ï¼ä»¥ä¾¿è¯¥æ件çè·¯å¾ç®åç´æ¥ã
为äºä½¿äºæ ç®åï¼è¯¥åºç¨ç¨åºä¸æ¯æç¨æ·ç»´æ¤åè½ï¼è¿æå³çæ æ³å¨åºç¨ç¨åºä¸æ·»å æå é¤ç¨æ·ãè¿å°±è¡¨ç¤ºæ¨å¿ é¡»æå·¥å°ç¨æ·æ·»å å° userDatabase.txt ä¸ãä¾å¦ï¼è¦æ·»å ä¸ä¸ªå为 testuser 以åå¯ç 为 password çç¨æ·ï¼å°±è¦å该æ件添å ä¸åä¸è¡ï¼
testuser cGFzc3dvcmQ=
æ¯ä¸ªæ¡ç®ä¸çå¯ç é½æ¯éè¿ Base64 ç¼ç è¿è¡ç¼ç çãæ¨å¯ä»¥å¨ contacts.jar ä¸ä½¿ç¨ EncoderDecoder ç±»æ¥è®¡ç®æ¨å¯ç çç¼ç çæ¬ãå®ç main() æ¹æ³å 许æ¨è¾å ¥ææå符串ï¼ç¶åè¿è¡è¯¥ç±»ï¼å¨æ§å¶å°ä¸è¾åºå·²ç¼ç çå¯ç ã
2.4.1 UserDatabase
UserDatabase å è£ äºä¸ææ¬æ件ç交äºãè¿ä¸ªç±»çæ¸ åçä¸å»å¾å¤§ï¼ä½æ¯å¹¶ä¸å¤æï¼å¤§é¨å让人æè§å¾å¤æçä¸è¥¿æ¯é£äºé¢å¤ç Java ç¼ç å 容ï¼å¤ç读åæ件æä½éè¦å®ä»¬ï¼ãæ们å°å¨æ¬é¢æ¿ä¸è®¨è®ºä¸äºè¦ç¹ï¼å ³äºå®æ´ç代ç æ¸ åï¼è¯·åé contacts.jarï¼ã
该类å®ç°äº Singleton 模å¼ï¼å¹¶ä¸ç»´æ¤äºä¸ä¸ªå®ä¾ï¼èææç¨æ·åéè¿è°ç¨ getSingleton() å ±äº«è¿ä¸ªå®ä¾ã
该类维æ¤äº ContactsUser çä¸ä¸ª Mapï¼è¯¥ Map å°ç¨æ·åä¸å¯ç çç»åä½ä¸ºæ¯ä¸ªæ¡ç®çå¯é¥ãä»»ä½ä¸è¥¿é½å¯ä»¥å å½æ¯ä¸ªæ¡ç®çé®ï¼ä½è¿ä¸ªæ¯è¾æ¹ä¾¿ã
å¨ servlet ç init() æ¹æ³ä¸ï¼æ们å°åè¯ UserDatabase æ°æ®åºæ件ä½äºä½å¤ï¼åºäº ServletContextï¼ï¼ç¶ååè¯å®éè¿è°ç¨ initialize() åå§åå®æ¬èº«ã该æ¹æ³å¦ä¸æ示ï¼
public void initialize() {
usersFile = new File(databaseFilePathname);
String allUsers = retrieveText();
StringTokenizer tokenizer = new StringTokenizer(allUsers, "\n");
while (tokenizer.hasMoreTokens()) {
String userEntry = tokenizer.nextToken();
UserRecord record = new UserRecord(userEntry);
put(new ContactsUser(record.getName(), record.getPassword(),
record.getContactList()));
}
}
该æ¹æ³éè¿è°ç¨ retrieveText è¯»å ¥å®æ´çæ件ï¼æ è®°è¾å¤§çå符串ï¼ä¸ºæ¯ä¸ªç¨æ·å建 UserRecordï¼ç¶åè°ç¨ put() æ¥å¨è¯¥ map ä¸æ¾ç½®æ°ç ContactsUserã该æ¹æ³ççæ£ä½ç¨ä½ç°å¨è°ç¨ retrieveText() å put() ä¸ï¼
protected synchronized String retrieveText() {
BufferedReader bufferedReader = null;
try {
bufferedReader =
new BufferedReader(new FileReader(usersFile.getAbsolutePath()));
char charBuff[] =
new char[(int) new File(usersFile.getAbsolutePath()).length()];
bufferedReader.read(charBuff);
return new String(charBuff);
} catch (Exception e) {
throw new RuntimeException("Unable to read in the file.", e);
} finally {
closeReader(bufferedReader);
}
}
protected void closeReader(BufferedReader bufferedReader) {
try {
if (bufferedReader != null)
bufferedReader.close();
} catch (Exception ex) {}
}
public void put(ContactsUser user) {
String userKey = user.getUsername() + user.getPassword();
users.put(userKey, user);
}
retrieveText() æ¹æ³è´è´£å®ææ件读åå·¥ä½ãå®å建äºä¸ä¸ª BufferedReaderï¼å°æ´ä¸ªæ件å å®¹è¯»å ¥å°å符ç¼å²åºä¸ï¼ç¶åå°è¿äºå 容转æ¢æä¸ä¸ª Stringãå¨å ¶ finally åå¥ä¸ï¼å®åªè°ç¨ closeReader() æ¥å®æ该工ä½ãwriteText() æ¹æ³å°è¾åºåå ¥æ件ï¼éåç°æçå 容ã该æ¹æ³éèäºåä¸ç±»åçæ件交äºç»èã
put() æ¹æ³ä¸ºç¨æ·å建å¯é¥ï¼ç¨æ·åå ä¸å¯ç ï¼ï¼å¹¶å°è¯¥å¯é¥æå ¥ç¨æ·ç map ä¸ã
3 æ»ç»
æ ¹æ®ä»¥ä¸çä¾åï¼æ们å¯ä»¥çæµï¼å ¶å®æ¯è¯å®ï¼å¾åºå¦ä¸ç»è®ºï¼
    1ãææ请æ±çå ¥å£é½æ¯servletï¼äºæ¯ä½ ä¼åç°ï¼ä¸ç®¡æ¯structè¿æ¯springçï¼å®é ä¸å¨web.xmlä¸é ç½®çå ¥å£é½æ¯servletï¼
    2ã请æ±åæ°ä¼ éï¼ç¨æ·è¯·æ±æ个å°åæ¶ï¼åæ°æ¯å¦ä½ä¼ å ¥servletçï¼ä»ä¾åä¸æ们å¯ä»¥çå°åæ°æ¯è¢«å è£ å¨HttpServletRequestä¸äºãè¿éä¼æ¶åå°ä¸¤ä¸ªé®é¢ï¼1ï¼éªè¯åæ°ï¼æ¯å¦è¾å ¥çæ°åä¸è½æ¯å°æ°çï¼2ï¼åæ°ä¸å¯¹è±¡ä¹é´çç»å®ï¼
      1ï¼åæ°éªè¯ï¼æ¹æ³ä¸»è¦æ3ç§ï¼1ãå端jséªè¯ï¼2ãè·åHttpServletRequeståæ°æ¶éªè¯ï¼3ã转为类对象æ¶éªè¯ï¼
      2ï¼åä¸ä¸ç±»å¯¹è±¡ç»å®ï¼å¨å¤§å¤æ°æ¡æ¶ï¼ä¼å°ä¼ å ¥åæ°ç»å®å°ç±»å¯¹è±¡ä¸ï¼ç¨åºå®é ä¸å¤ççæ¯ç±»å¯¹è±¡ï¼
    3ãå¨ä½æ¡æ¶ï¼å¦ææ¯ä¸ªè¯·æ±é½é ç½®ä¸ä¸ªservletï¼è¿äºæ··ä¹±ï¼å¦æ¬æä¸æ述设计ä¸ä¸ªå¨ä½æ¡æ¶ï¼è¿ä¸ªæ¯æ¯è¾å级çï¼é常æ¡æ¶ä¼æä¾ä¸ä¸ªåºç¡ç±»æ¥åè¿ä¸ªäºæ ï¼ä¸éè¦ç¨æ·è®¾è®¡ï¼
    4ã请æ±æè æ¯ç»æå¤çï¼å¦æææ³å¯¹è¯·æ±åä¸äºå¤çï¼æ¯å¦è®¾ç½®ç¼ç æ¹å¼ï¼æè éªè¯ç¨æ·æéï¼è¿æ¶å该å¦ä½å¤çï¼æ»ä¸å¯è½å¯¹æ¯ä¸ªè¯·æ±å¤çç代ç éé¢é½å å ¥ç¸åç代ç å§ï¼å¯¹äºè¿ä¸ªå¤çï¼ä¸è¬æ¯ç¨servletçfilterãæè æ¯springä¸çinterceptorãæè å©ç¨aopæ¥å®ç°ï¼
    5ã表ç°å±ï¼å¯¹äºç¨æ·çå°çé¨åï¼ä½¿ç¨åªç§ææ¯æ¥å®ç°ï¼æ¯jspè¿æ¯å ¶ä»ï¼å¯¹äºéå®çææ¯ï¼å®é ä¸è¿éè¦è§£å³ï¼è¿ååæ°å¦ä½æ¾ç¤ºå¨jspï¼æå ¶ä»æ件ï¼ä¸ï¼
    6ãæ°æ®åå¨ï¼1ï¼æ°æ®åå¨å¨æ°æ®åºæ¶ï¼éè¦è°ç¨å¯¹åºçç¨åºï¼ä¸è¬æ¯éè¿è°ç¨jdbcæ¥ä¸æ°æ®äº¤äºï¼è¿éå°±æ¶åå°ä¸ä¸ªéè¦é®é¢ï¼é£å°±æ¯äºå¡ï¼
                2ï¼æ°æ®æºåæ¢ï¼é常çç论设计æ¡æ¶ï¼é½å¨é¼å¹æ¯å¦æ¯æåæ¢æ°æ®åºï¼æ¯å¦ä»oracleåæ¢å°mysqlï¼ä¹å°±æ¯åå°æ°æ®åºæ å ³æ§ï¼ï¼ä¸ªäººæè§è¿ä¸ªéæ±ä¼¼ä¹æ²¡é£ä¹å¼ºçï¼
                3ï¼ç¼åï¼å¯¹å®æ¶æ§è¦æ±æ¯è¾é«çç³»ç»ï¼æææ°æ®é½ä»æ°æ®åºè¯»åï¼æ¾ç¶æç太差ï¼äºæ¯éè¦å¼å ¥æ°æ®ç¼åæºå¶ï¼æ¯å¦hibernateä¸ehanceï¼æè redisçå¼æºç»ä»¶ï¼
    7ãçå¬ï¼é常æ们å¯è½èèå¨ç³»ç»åå§åæ¶åä¸äºäºæ ï¼æè å¨æäºäºä»¶åçæ¶åä¸äºäºæ ãé£ä¹è¿ä¸ªå°±éè¦ç¨å°çå¬äºãå®é ä¸å¨web.xmlä¸æ¯å¯ä»¥é ç½®listenerçã
    8ãä¸ä¸æï¼ä¸è¬çåºç¨é½è¦æ±åä¸äºå½é åçä¹ç±»çäºæ ï¼è¿ä¸ªå¯è½å°±éè¦ç»´æ¤ä¸ä¸æï¼ç¨äºæ¯æå½é åçï¼
    9ãsessionåcookieï¼webå¼åè¿ä¸¤ä¸ªä¸è¥¿æ¯å ä¸äºçäºã
    10ãæ¥å¿ï¼æ¥å¿æ¬è´¨ä¸ä¸åºè¯¥å¨è¿éæï¼å 为å®æ¯å±äºå®ç°çä¸é¨åï¼ä½æ¯èèå°å¨ç³»ç»bugåæãè¿ç»´ãç¨æ·è¡ä¸ºåæï¼suï¼Â
    以ä¸åºæ¬è¦çäºä¸ä¸ªwebæ¡æ¶éè¦åçäºæ ï¼å¨åæå个æ¡æ¶æ¶ä»¥è¿ä¸ªæè·¯å»èèå ¶å¯¹åºçé ç½®å°åºæ¯åä»ä¹çï¼å°±å¯ä»¥ä¸ç®äºç¶äºï¼èä¸æ¯è¢«åç§æ¡æ¶äºè±å «é¨çå®ç°ç»è¿·æäºãå½ç¶ï¼å¨ä¸äºæ¡æ¶ä¸å¯è½è¿ç¨å°ä¸äºæ¯è¾æ¹ä¾¿çåè½ï¼
    1ãbeanèªå¨è£ é ï¼å¦æç³»ç»æå¾å¤ç±»ï¼è¿äºç±»é½è¦å¨é ç½®æ件ä¸è¿è¡é ç½®æ¾ç¶æ¯ä¸ä¸ªå¾ç¹ççäºæ ï¼äºæ¯èªå¨è£ é bean就被æåºæ¥äºãè¿ä¸ªä¸»è¦æ¯å©ç¨javaç注解ååå°ã
    2ãåå¸å¼ï¼å¤çº¿ç¨ï¼ï¼ç±äºwebç½ç«æå¯è½è®¿é®éç¹å«å¤§ï¼å æ¤éè¦è¿è¡æ©å®¹ï¼è¿é就设计åå¸å¼ï¼å¤çº¿ç¨ï¼ï¼