Servlet基础 及详细介绍(附带代码)

来源:互联网 发布:淘宝货到付款流程 编辑:程序博客网 时间:2024/06/05 19:43

javaweb学习笔记 Servlet基础   

完整代码下载地址

http://download.csdn.net/download/qq_26676207/9477503


1.Servlet概述

    JSP的前身就是Servlet。Servlet就是在服务器端运行的一段小程序。一个Servlet就是一个Java类,并且可以通过“请求-响应”编程模型来访问的这个驻留在服务器内存的Servlet程序。
2.Tomcat容器等级
    Tomcat的容器分为4个等级,Servlet的容器管理Context容器,一个Context对应一个Web工程。


  3.手工编写第一个Servlet
    编写一个Servlet程序大体上需要3个步骤:继承HttpServlet-->重写doGet()或者doPost()方法-->在web.xml中注册Servlet。
    HttpServlet的继承关系如图:




    重写doGet还是doPost方法需要根据请求方式而定。
  一、编写一个类继承自HttpRequest并重写doGet(或者doPost方法)在项目的src目录下新建一个servlet.MyServlet.java

 1 package servlet; 2  3 import java.io.IOException; 4 import java.io.PrintWriter; 5  6 import javax.servlet.ServletException; 7 import javax.servlet.http.HttpServlet; 8 import javax.servlet.http.HttpServletRequest; 9 import javax.servlet.http.HttpServletResponse;10 11 /** 继承自HttpServlet */12 public class HelloServlet extends HttpServlet {13 14     /** 重写doGet方法 */15     @Override16     protected void doGet(HttpServletRequest request, HttpServletResponse response)17             throws ServletException, IOException {18         System.out.println("处理get请求。。。");19         PrintWriter out = response.getWriter();20         out.println("<b>HelloServlet</b>");21     }22 23     /** 重写doPost方法 */24     @Override25     protected void doPost(HttpServletRequest request, HttpServletResponse response)26             throws ServletException, IOException {27         System.out.println("处理post请求。。。");28         PrintWriter out = response.getWriter();29         out.println("<b>HelloServlet</b>");30     }31     32 }

  二、在WEB-INF/web.xml中注册刚刚新建的Servlet:

 1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app version="2.5"  3     xmlns="http://java.sun.com/xml/ns/javaee"  4     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  5     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee  6     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> 7   <display-name></display-name>     8   <welcome-file-list> 9     <welcome-file>index.jsp</welcome-file>10   </welcome-file-list>11   12   <!-- 注册Servlet开始 -->13   <servlet>14       <servlet-name>HelloServlet</servlet-name>15       <servlet-class>servlet.HelloServlet</servlet-class>16   </servlet>17   <servlet-mapping>18       <servlet-name>HelloServlet</servlet-name>19       <url-pattern>/servlet/HelloServlet</url-pattern>20   </servlet-mapping>21   <!-- 注册Servlet结束 -->22   23 </web-app>

  其中servlet-name表示Servlet的名字,servlet-class要写完成的类的定义(包名.类名),url-pattern表示Servlet的路径。
  在index.jsp中使用自定义的Servlet处理get和post请求。

 1 <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> 2 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 3 <html> 4   <head> 5     <title>手工编写的第一个Servlet</title> 6   </head> 7    8   <body> 9     <h1>第一个Servlet小例子</h1><hr>10     <a href="servlet/HelloServlet">get方式请求HelloServlet</a><br /><br />11     <form action="servlet/HelloServlet" method="post">12         <input type="submit" value="post方式请求HelloServlet" /> 13     </form>14   </body>15 </html>

 发布项目,运行结果:


  4.使用MyEclipse编写Servlet
      1.src-->new Servlet。
      2.重写doGet()或者doPost()方法。  
      3.部署运行。
   通过MyEclipse创建Servlet的时候它默认继承自HttpServlet。默认勾选覆写init()、destory()、doGet()和doPost()方法,并且自动向web.xml中注册该Servlet。
   可以发现使用MyEclipse创建的Servlet它已经自动为我们生成了输出的html模板,我们只需要做很少的改动即可。   
  5.Servlet的执行流程和生命周期


    用户点击超链接向Servlet发送请求-->服务器在web.xml中的servlet-mapping寻找与该Servlet相对应的URL地址-->找到对应的Servlet名字-->根据Servlet的名字找到和该Servlet相关的处理类-->根据请求的方式不同确定是调用doGet还是doPost方法。
    一个Servlet的生命周期大致分为3个阶段:


  
    1.客户端发送请求给服务器。
    2.服务器开始接受,先判断该请求的servlet实例是否存在,如果不存在先装载一个servlet类并创建实例。
        如果存在则直接调用该servlet的service方法,之后进行判断是调用  doGet方法还是doPost方法。
    3.servlet创建实例后,调用init方法进行初始化。之后调用servce方法,判断是调用doGet方法还是doPost方法。
      4.最后判断服务器是否关闭,如果关闭则调用destroy方法。
  下面这个例子展示了Servlet的生命周期:
首先是一个Servlet:TestServlet1

 1 package servlet; 2  3 import java.io.IOException; 4 import java.io.PrintWriter; 5  6 import javax.servlet.ServletException; 7 import javax.servlet.http.HttpServlet; 8 import javax.servlet.http.HttpServletRequest; 9 import javax.servlet.http.HttpServletResponse;10 11 public class TestServlet1 extends HttpServlet {12 13     public TestServlet1() {14         System.out.println("TestServlet1构造方法被执行!");15     }16 17     public void destroy() {18         System.out.println("TestServlet1销毁方法被执行!");19     }20 21     public void doGet(HttpServletRequest request, HttpServletResponse response)22             throws ServletException, IOException {23 24         System.out.println("TestServlet1的doGet方法被执行!");25         response.setContentType("text/html;charset=utf-8");26         PrintWriter out = response.getWriter();27         out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");28         out.println("<HTML>");29         out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>");30         out.println("  <BODY>");31         out.println("<h1>你好我是TestServlet1</h1>");32         out.println("  </BODY>");33         out.println("</HTML>");34         out.flush();35         out.close();36     }37 38     public void doPost(HttpServletRequest request, HttpServletResponse response)39             throws ServletException, IOException {40         System.out.println("TestServlet1的doPost方法被执行!");41         doGet(request, response);// 让doPost与doGet执行相同的操作42     }43 44     public void init() throws ServletException {45         System.out.println("TestServlet1的初始化方法被执行!");46     }47 48 }

    主页index.jsp

 1 <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> 2 <% 3 String path = request.getContextPath(); 4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 5 %> 6  7 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 8 <html> 9   <head>10     <base href="<%=basePath%>">11     <title>Servlet的生命周期</title>12   </head>13   14   <body>15       <h1>Servlet的生命周期</h1><hr />16       <a href = "servlet/TestServlet1">以get方式请求TestServlet1</a>17   </body>18 </html>

  当服务器启动之后我们第一次访问index.jsp的时候,构造方法,初始化方法和doGet()方法执行


    当我们再次请求该页面的时候,只有doGet()方法被执行:


    服务器关闭的时候销毁方法执行。
 6.Tomcat装载Servlet的3种情况
    在下列时刻Servlet容器会加载Servlet:
    1.Servlet容器启动时自动装载某些Servlet,实现它只需要在web.xml文件中的<servlet></servlet>之间添加以下代码:

<load-on-startup>1</load-on-startup>

  其中,数字越小表示优先级越高。
    例如:我们在web.xml中设置TestServlet2的优先级为1,而TestServlet1的优先级为2,启动和关闭Tomcat:


  优先级高的先启动也先关闭。
    2.客户端首次向某个Servlet发送请求。【例子详见Servlet生命周期的那个例子】
    3.Servlet类被修改后,Tomcat容器会重新装载Servlet。
    Servlet被装载后,Servlet容器会创建一个Servlet实例,并且调用Servlet的init()方法进行初始化,在Servlet的真个生命周期内init()方法只被调用一次。
  7.Servlet与JSP内置对象的对应关系


  8.Servlet获取表单数据
    用户在reg.jsp中填写注册表单,使用post方式将数据发送到一个名称为servlet.RegServlet的Servlet处理【Servlet的doPost()方法】,Servlet将用户信息封装成一个Users对象存储在session中,讲请求转发到userinfo.jsp。在userinfo.jsp中通过<jsp:useBean>指令从session中取出保存的用户对象,通过<jsp:getPerproty>指令显示用户对象的各个字段。




 1 package entity; 2  3 import java.util.Date; 4  5 /** 用户实体类 */ 6 public class Users { 7     private String username; 8     private String password; 9     private String email;10     private String sex;11     private Date birthday;12     private String[] favorites;13     private String introduce; // 自我介绍14     private boolean flag; // 是否接受协议15 16     public Users() {17     }18 19     public String getUsername() {20         return username;21     }22 23     public void setUsername(String username) {24         this.username = username;25     }26 27     public String getPassword() {28         return password;29     }30 31     public void setPassword(String password) {32         this.password = password;33     }34 35     public String getEmail() {36         return email;37     }38 39     public void setEmail(String email) {40         this.email = email;41     }42 43     public String getSex() {44         return sex;45     }46 47     public void setSex(String sex) {48         this.sex = sex;49     }50 51     public Date getBirthday() {52         return birthday;53     }54 55     public void setBirthday(Date birthday) {56         this.birthday = birthday;57     }58 59     public String[] getFavorites() {60         return favorites;61     }62 63     public void setFavorites(String[] favorites) {64         this.favorites = favorites;65     }66 67     public String getIntroduce() {68         return introduce;69     }70 71     public void setIntroduce(String introduce) {72         this.introduce = introduce;73     }74 75     public boolean isFlag() {76         return flag;77     }78 79     public void setFlag(boolean flag) {80         this.flag = flag;81     }82 83 }

用户实体entity.Users.java




 1 <%@ page language="java" import="java.util.*" contentType="text/html;charset=utf-8"%> 2  3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 4 <html> 5   <head> 6     <title>用户注册</title> 7      <style type="text/css"> 8      .label{ 9           width: 20%    10      }11      .controler{12           width: 80%    13      }14      </style>  15      <script type="text/javascript" src="js/Calendar3.js"></script>16   </head>17   18   <body>19        <h1>用户注册</h1>20     <hr>21     <form name="regForm" action="servlet/RegServlet" method="post" >22               <table border="0" width="800" cellspacing="0" cellpadding="0">23                 <tr>24                     <td class="lalel">用户名:</td>25                     <td class="controler"><input type="text" name="username" /></td>26                 </tr>27                 <tr>28                     <td class="label">密码:</td>29                     <td class="controler"><input type="password" name="password" ></td>30                     31                 </tr>32                 <tr>33                     <td class="label">确认密码:</td>34                     <td class="controler"><input type="password" name="confirmpass" ></td>35                     36                 </tr>37                 <tr>38                     <td class="label">电子邮箱:</td>39                     <td class="controler"><input type="text" name="email" ></td>40                     41                 </tr>42                 <tr>43                     <td class="label">性别:</td>44                     <td class="controler"><input type="radio" name="sex" checked="checked" value="Male"><input type="radio" name="sex" value="Female"></td>45                 </tr>46                47                 <tr>48                     <td class="label">出生日期:</td>49                     <td class="controler">50                       <input name="birthday" type="text" id="control_date" size="10"51                       maxlength="10" onclick="new Calendar().show(this);" readonly="readonly" />52                     </td>53                 </tr>54                 <tr>55                     <td class="label">爱好:</td>56                     <td class="controler">57                     <input type="checkbox" name="favorite" value="nba"> NBA &nbsp;58                       <input type="checkbox" name="favorite" value="music"> 音乐 &nbsp;59                       <input type="checkbox" name="favorite" value="movie"> 电影 &nbsp;60                       <input type="checkbox" name="favorite" value="internet"> 上网 &nbsp;61                     </td>62                 </tr>63                 <tr>64                     <td class="label">自我介绍:</td>65                     <td class="controler">66                         <textarea name="introduce" rows="10" cols="40"></textarea>67                     </td>68                 </tr>69                 <tr>70                     <td class="label">接受协议:</td>71                     <td class="controler">72                         <input type="checkbox" name="isAccept" value="true">是否接受霸王条款73                     </td>74                 </tr>75                 <tr>76                     <td colspan="2" align="center">77                         <input type="submit" value="注册"/>&nbsp;&nbsp;78                         <input type="reset" value="取消"/>&nbsp;&nbsp;79                     </td>80                 </tr>81               </table>82     </form>83   </body>84 </html>

注册页reg.jsp




 1 <%@ page language="java" import="java.util.*,java.text.*" contentType="text/html; charset=utf-8"%> 2 <%@ page import="entity.Users" %> 3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 4 <html> 5   <head> 6     <title>用户信息显示</title> 7     <style type="text/css"> 8      .title{ 9          width: 30%;    10          background-color: #CCC;11          font-weight: bold;12      }13      .content{14          width:70%;15          background-color: #CBCFE5;16      }17      18    </style>  19   </head>20   21   <body>22     <h1>用户信息</h1>23     <hr>24     <center>25      <jsp:useBean  id="regUser" class="entity.Users" scope="session"/>   26      <table width="600" cellpadding="0" cellspacing="0" border="1">27         <tr>28           <td class="title">用户名:</td>29           <td class="content">&nbsp;<jsp:getProperty name="regUser" property="username"/></td>30         </tr>31         <tr>32           <td class="title">密码:</td>33           <td class="content">&nbsp;<jsp:getProperty name="regUser" property="password"/></td>34         </tr>35         <tr>36           <td class="title">性别:</td>37           <td class="content">&nbsp;<jsp:getProperty name="regUser" property="sex"/></td>38         </tr>39         <tr>40           <td class="title">E-mail:</td>41           <td class="content">&nbsp;<jsp:getProperty name="regUser" property="email"/></td>42         </tr>43         <tr>44           <td class="title">出生日期:</td>45           <td class="content">&nbsp;46             <% 47                SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");48                String date = sdf.format(regUser.getBirthday());49             %>50              <%=date%>51           </td>52         </tr>53         <tr>54           <td class="title">爱好:</td>55           <td class="content">&nbsp;56             <% 57                String[] favorites = regUser.getFavorites();58                if(favorites!=null){59                    for(String f:favorites)60                    {61                 %>62                     <%=f%> &nbsp;&nbsp;63                 <% 64                    }65                }66             %>67           </td>68         </tr>69         <tr>70           <td class="title">自我介绍:</td>71           <td class="content">&nbsp;<jsp:getProperty name="regUser" property="introduce"/></td>72         </tr>73         <tr>74           <td class="title">是否介绍协议:</td>75           <td class="content">&nbsp;<jsp:getProperty name="regUser" property="flag"/></td>76         </tr>77      </table>78     </center>79   </body>80 </html>

用户信息显示页userinfo.jsp




 1 package servlet; 2  3 import java.io.IOException; 4 import java.text.ParseException; 5 import java.text.SimpleDateFormat; 6 import java.util.Date; 7  8 import javax.servlet.ServletException; 9 import javax.servlet.http.HttpServlet;10 import javax.servlet.http.HttpServletRequest;11 import javax.servlet.http.HttpServletResponse;12 13 import entity.Users;14 15 public class RegServlet extends HttpServlet {16 17     public RegServlet() {18         super();19     }20 21     public void destroy() {22         super.destroy(); // Just puts "destroy" string in log23     }24 25     public void doGet(HttpServletRequest request, HttpServletResponse response)26             throws ServletException, IOException {27 28         doPost(request, response);//因为表单是post方式提交的29     }30 31     public void doPost(HttpServletRequest request, HttpServletResponse response)32             throws ServletException, IOException {33 34         request.setCharacterEncoding("utf-8");35         36         Users u = new Users();37         String username,password,email,introduce,sex,isAccept;38         Date birthday;39         String[]favorites;40         41         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");42         43         try {44             45             username = request.getParameter("username");46             password = request.getParameter("password");47             sex = request.getParameter("sex");48             email = request.getParameter("email");49             introduce = request.getParameter("introduce");50 51             if (request.getParameter("birthday")!=null&&request.getParameter("birthday").length()!=0) {52                 birthday = sdf.parse(request.getParameter("birthday"));53             }else {54                 birthday = new Date();55             }56             57             favorites = request.getParameterValues("favorite");//getParamterValues返回字符串数组58             isAccept = request.getParameter("isAccept");59             60             u.setUsername(username);61             u.setPassword(password);62             u.setEmail(email);63             u.setBirthday(new Date());64             u.setIntroduce(introduce);65             u.setFavorites(favorites);66             u.setSex(sex);67             u.setFlag(isAccept!=null&&isAccept.equals("true")?true:false);68             69             //把注册成功的用户对象保存在session中70             request.getSession().setAttribute("regUser", u);71             72             request.getRequestDispatcher("../userinfo.jsp").forward(request, response);73         } catch (ParseException e) {74             e.printStackTrace();75         }76     }77 78     public void init() throws ServletException {79     }80 81 }

处理用户注册的Servlet:RegServlet


  9.Servlet路径跳转
    相对路径就是相对于当前页面的路径,绝对路径就是相对于项目根目录的路径(绝对路径需要使用到path变量)。

 1 <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> 2 <% 3 String path = request.getContextPath(); 4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 5 %> 6  7 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 8 <html> 9   <head>10     <base href="<%=basePath%>">11     <title>Servlet路径跳转</title>12   </head>13   14   <body>15     <h1>Servlet路径跳转</h1>16     <!-- 使用相对路径访问HelloServlet -->17     <a href="servlet/HelloServlet">使用相对路径访问servlet</a><br />18     19     <!-- 使用绝对路径访问HelloServlet,使用path变量 -->20     项目的根目录:<%=path %><br />21     <a href="<%=path %>/servlet/HelloServlet">使用相对路径访问servlet</a><br />22   </body>23 </html>

  在web.xml中注册的Servlet的路径写法是绝对路径:

 1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app version="2.5"  3     xmlns="http://java.sun.com/xml/ns/javaee"  4     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  5     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee  6     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> 7   <display-name></display-name> 8    9   <!-- Servlet注册开始 -->10   <servlet>11     <description>This is the description of my J2EE component</description>12     <display-name>This is the display name of my J2EE component</display-name>13     <servlet-name>HelloServlet</servlet-name>14     <servlet-class>servlet.HelloServlet</servlet-class>15   </servlet>16   <servlet-mapping>17     <servlet-name>HelloServlet</servlet-name>18     <url-pattern>/servlet/HelloServlet</url-pattern><!-- Servlet的路径是绝对路径 -->19   </servlet-mapping>20   <!-- Servlet注册结束 -->21       22   <welcome-file-list>23     <welcome-file>index.jsp</welcome-file>24   </welcome-file-list>25 </web-app>

  在Servlet之中路径的跳转问题:
    index.jsp中有一个链接指向servlet.TestServlet

<a href="servlet/TestServlet">访问TestServlet,跳转到Test.jsp</a>

    servlet.TestServlet的doPost()和doGet()方法如下:

 1 public void doGet(HttpServletRequest request, HttpServletResponse response) 2             throws ServletException, IOException { 3  4             doPost(request, response); 5     } 6  7     public void doPost(HttpServletRequest request, HttpServletResponse response) 8             throws ServletException, IOException { 9         // 1.使用请求重定向的方式跳转到test.jsp10 //        response.sendRedirect("../test.jsp");11         // 也可以使用绝对路径的方式request.getContextPath12 //        response.sendRedirect(request.getContextPath()+"/test.jsp");13         14         // 2.使用服务器内部跳转的方式15 //        request.getRequestDispatcher("../test.jsp").forward(request, response);16         request.getRequestDispatcher("/test.jsp").forward(request, response);17     }

  在TestServlet中完成到网站根目录下的跳转有两种方式重定向和服务器内部转发,其中URL的写法也有2种方式:绝对路径和相对路径。相对路径使用..即可,而绝对路径重定向需要依赖request.getContextPath()方法取得上下文环境,而服务器内部转发中的斜线就表示项目的根目录。
  10.阶段案例——使用Servlet完成用户登录
用户名和密码都是admin,登陆成功则使用服务器内部转发到login_success.jsp,显示登录成功的用户名。登录失败则重定向到login_failure.jsp。
  把login.jsp中表单的action属性改为需要处理登录的Servlet

1 <form action="servlet/LoginServlet" method="post" name="loginForm">2     <!-- 代码省略 -->3 </form>





 1 package org.po; 2  3 /** 4  * 用户类-javabean 5  */ 6 public class Users { 7     private String username; 8     private String password; 9 10     public Users() {11     }12 13     public String getUsername() {14         return username;15     }16 17     public void setUsername(String username) {18         this.username = username;19     }20 21     public String getPassword() {22         return password;23     }24 25     public void setPassword(String password) {26         this.password = password;27     }28 29 }

用户实体类org.po.Users




 1 public void doGet(HttpServletRequest request, HttpServletResponse response) 2             throws ServletException, IOException { 3  4         doPost(request, response); 5     } 6  7     public void doPost(HttpServletRequest request, HttpServletResponse response) 8             throws ServletException, IOException { 9 10         Users u = new Users();11         String username = request.getParameter("username");12         String password = request.getParameter("password");13         u.setUsername(username);14         u.setPassword(password);15         16         if (u.getUsername().equals("admin")&&u.getPassword().equals("admin")) {17             request.getSession().setAttribute("username", username);18             request.getRequestDispatcher("/login_success.jsp").forward(request, response);19         }else {20             response.sendRedirect("../login_failure.jsp");21         }22     }

处理用户登录的LoginServlet
Servlet高级   1.获取初始化参数
    在web.xml中配置Servlet时,可以配置一些初始化参数。而在Servlet中可以通过ServletConfig接口提供的方法来取得这些参数。
    1.首先在index.jsp中建立一条超链接指向servlet.GetInitParameterServlet。

<a href = "servlet/GetInitParameterServlet">获取Servlet的初始化参数</a>

    2.在web.xml中配置该Servlet的初始化参数:




 1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app version="2.5"  3     xmlns="http://java.sun.com/xml/ns/javaee"  4     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  5     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee  6     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> 7   <display-name></display-name> 8    9   <!-- 注册Servlet开始 -->10   <servlet>11     <description>This is the description of my J2EE component</description>12     <display-name>This is the display name of my J2EE component</display-name>13     <servlet-name>GetInitParameterServlet</servlet-name>14     <servlet-class>servlet.GetInitParameterServlet</servlet-class>15     16     <!-- 配置用户名初始化参数 -->17     <init-param>18         <param-name>username</param-name>19         <param-value>admin</param-value>20     </init-param>21     <!-- 配置密码初始化参数 -->22     <init-param>23         <param-name>password</param-name>24         <param-value>123456</param-value>25     </init-param>26     27   </servlet>28   <!-- 注册Servlet结束 -->29 30   <servlet-mapping>31     <servlet-name>GetInitParameterServlet</servlet-name>32     <url-pattern>/servlet/GetInitParameterServlet</url-pattern>33   </servlet-mapping>    34   <welcome-file-list>35     <welcome-file>index.jsp</welcome-file>36   </welcome-file-list>37 </web-app>

web.xml
    3.在GetInitParameterServlet的init方法中使用this.getgetInitParameter(String name)方法获得初始化参数:




 1 package servlet; 2  3 import java.io.IOException; 4 import java.io.PrintWriter; 5  6 import javax.servlet.ServletException; 7 import javax.servlet.http.HttpServlet; 8 import javax.servlet.http.HttpServletRequest; 9 import javax.servlet.http.HttpServletResponse;10 11 public class GetInitParameterServlet extends HttpServlet {12     /* 封装属性 */13     private String username ;14     private String password ;15     16     public String getUsername() {17         return username;18     }19     20     public void setUsername(String username) {21         this.username = username;22     }23 24     public String getPassword() {25         return password;26     }27 28     public void setPassword(String password) {29         this.password = password;30     }31 32     public GetInitParameterServlet() {33         super();34     }35 36     public void destroy() {37         super.destroy(); // Just puts "destroy" string in log38     }39 40     public void doGet(HttpServletRequest request, HttpServletResponse response)41             throws ServletException, IOException {42 43         doPost(request, response);44     }45 46     public void doPost(HttpServletRequest request, HttpServletResponse response)47             throws ServletException, IOException {48 49         response.setContentType("text/html;charset=utf-8");50         PrintWriter out = response.getWriter();51         out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");52         out.println("<HTML>");53         out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>");54         out.println("  <BODY>");55         out.println("从web.xml中获取初始化参数,用户名:"+username+"<br />");56         out.println("从web.xml中获取初始化参数,密码:"+password);57         out.println("  </BODY>");58         out.println("</HTML>");59         out.flush();60         out.close();61     }62 63     /** 可以在Servlet的init方法中获得web.xml中配置的初始化参数 */64     public void init() throws ServletException {65         this.setUsername(this.getInitParameter("username"));66         setPassword(getInitParameter("password"));67     }68 69 }

servlet.GetInitParameterServlet.java
运行结果:


  2.MVC模式
  MVC旨在分离模型、视图、控制。是分层思想的一种体现。
结构图如下:


  1.浏览器发送请求被控制器接收(Servlet)。
  2.由控制器实例化一个模型层对象(JavaBean),模型层访问EIS(企业信息系统,就是DB)。EIS将结果返回给JavaBean,JavaBean将结果返回给控制层Servlet。
  3.控制层根据模型层返回的结果选择合适的视图给用户呈现。
  3.Model2简介
  Model2实际上就是JSP(V)+Servlet(C)+JavaBean(M),是MVC设计思想。


  4.阶段项目:使用MVC实现购物车
JSP(View)+Servlet(Control)+ dao(Model)。
已有的商品实体类:




 1 package entity; 2  3 /** 4  * 商品类(与DB中的表名一致)-javabean 属性和DB中表的字段完全一致 5  */ 6 public class Items { 7     private int id; 8     private String name; 9     private String city;10     private int price;11     private int number;12     private String picture;13 14     public Items() {15     }16 17     public Items(int id, String name, String city, int price, int number,18             String picture) {19         super();20         this.id = id;21         this.name = name;22         this.city = city;23         this.price = price;24         this.number = number;25         this.picture = picture;26     }27 28     public int getId() {29         return id;30     }31 32     public void setId(int id) {33         this.id = id;34     }35 36     public String getName() {37         return name;38     }39 40     public void setName(String name) {41         this.name = name;42     }43 44     public String getCity() {45         return city;46     }47 48     public void setCity(String city) {49         this.city = city;50     }51 52     public int getPrice() {53         return price;54     }55 56     public void setPrice(int price) {57         this.price = price;58     }59 60     public int getNumber() {61         return number;62     }63 64     public void setNumber(int number) {65         this.number = number;66     }67 68 69     public String getPicture() {70         return picture;71     }72 73     public void setPicture(String picture) {74         this.picture = picture;75     }76     77     @Override78     public String toString() {79         return "商品编号:"+this.getId()+",商品名称:"+this.getName();80     }81 }

Items.java
实现阶段:创建购物车类-->编写Servlet-->创建页面层。
  1.购物车类Cart的设计:
  购物车有2个属性,分别是购买商品的集合和商品的总价格。
  购物车的方法有3个:添加商品、删除商品、计算商品的总价格。
  那么问题来了,我们应该使用何种集合来存储用户购买的商品?我们可以使用Map类型,键是商品对象,值是该种商品的数量。
实现如下:




 1 package entity; 2  3 import java.util.HashMap; 4 import java.util.Iterator; 5 import java.util.Set; 6  7 /** 购物车类 */ 8 public class Cart { 9     private HashMap<Items, Integer> goods;// 商品信息以键值对的方式保存在hashMap中10     private double totalPrice;11 12     public Cart() {13         // 在构造方法中初始化属性14         goods = new HashMap<Items, Integer>();15         totalPrice = 0;16     }17 18     public HashMap<Items, Integer> getGoods() {19         return goods;20     }21 22     public void setGoods(HashMap<Items, Integer> goods) {23         this.goods = goods;24     }25 26     public double getTotalPrice() {27         return totalPrice;28     }29 30     public void setTotalPrice(double totalPrice) {31         this.totalPrice = totalPrice;32     }33 34     /**35      * 添加商品到购物车36      * @param items:商品对象37      * @param number:商品数量38      */39     public boolean addGoodsInCart(Items item, int number) {40         goods.put(item, number);41         calcTotalPrice();// 重新计算购物车的总金额42         return true;43     }44 45     /**46      * 从购物车中删除商品47      */48     public boolean removeGoodsFromCart(Items item) {49         goods.remove(item);50         calcTotalPrice();// 重新计算购物车的总金额51         return true;52     }53 54     /** 计算购物车的总金额 */55     public double calcTotalPrice() {56         double sum = 0;57         Set<Items> keys = goods.keySet();// 获得键的集合58         Iterator<Items> iterator = keys.iterator();59         while (iterator.hasNext()) {60             Items items = (Items) iterator.next();61             sum += items.getPrice() * goods.get(items);62         }63         this.setTotalPrice(sum);// 设置总金额64         return sum;65     }66 }

Cart.java
接下来测试上面的购物车类:
  直接在给Cart类中编写main方法测试购物车类;

 1 public static void main(String[] args) { 2         //创建2个商品对象 3         Items i1 = new Items(1, "沃特篮球鞋", "温州", 200, 500, "001.jpg"); 4         Items i2 = new Items(2, "李宁运动鞋", "广州", 300, 500, "002.jpg"); 5         Items i3 = new Items(1, "沃特篮球鞋", "温州", 200, 500, "001.jpg"); 6          7         //创建购物车对象 8         Cart cart = new Cart(); 9         cart.addGoodsInCart(i1, 1);10         cart.addGoodsInCart(i2, 2);11         cart.addGoodsInCart(i3, 3);//再买3双沃特篮球鞋12         13         14         //购物车中商品的集合15         Set<Map.Entry<Items, Integer>>items = cart.getGoods().entrySet();16         for (Map.Entry<Items, Integer> entry : items) {17             System.out.println(entry);18         }19         System.out.println("买4双沃特篮球鞋和2双李宁运动鞋之后,购物车总价格:"+cart.getTotalPrice());;20 }

  运行结果:
 

 虽然总金额的计算没有问题,但是用户体验不太好,购物车中中出现了相同的商品记录(应该是需要合并的)。
 一种方式是重写Items类的hashCode和equals方法。重写之后再次运行程序:


  虽然商品的记录在购物车中不会重复,但是购买的数量却不对了,沃特篮球鞋的后面的一条记录替换掉了前面的记录。
  解决方案:此时只要修改购物车的addGoodsInCart()方法就行了:在加入新的商品之前先判断如果已经添加了相同的商品,只需要修改商品的数量即可:

 1 public boolean addGoodsInCart(Items item, int number) { 2         //如果商品已经在购物车中只需要修改商品数量即可【原有数量+新加入的数量】 3         if (goods.containsKey(item)) { 4             goods.put(item, goods.get(item)+number); 5         }else { 6             goods.put(item, number); 7         } 8         calcTotalPrice();// 重新计算购物车的总金额 9         return true;10 }

  运行结果:


  2.Servlet类的设计
    由Servlet类调用购物车类的代码实现购物功能。




 1 package servlet; 2  3 import java.io.IOException; 4 import java.io.PrintWriter; 5  6 import javax.servlet.ServletException; 7 import javax.servlet.http.HttpServlet; 8 import javax.servlet.http.HttpServletRequest; 9 import javax.servlet.http.HttpServletResponse;10 11 import dao.ItemsDAO;12 import entity.Cart;13 import entity.Items;14 15 public class CartServlet extends HttpServlet {16     17     private String action;//购物车的动作(添加?删除?显示?商品)18     private ItemsDAO idao = new ItemsDAO();//商品业务逻辑类的对象19 20     public CartServlet() {21         super();22     }23 24     public void destroy() {25         super.destroy(); // Just puts "destroy" string in log26     }27 28     public void doGet(HttpServletRequest request, HttpServletResponse response)29             throws ServletException, IOException {30         doPost(request, response);31     }32     33     public void doPost(HttpServletRequest request, HttpServletResponse response)34             throws ServletException, IOException {35 36         response.setContentType("text/html;charset=utf-8");37         PrintWriter out = response.getWriter();38         if (request.getParameter("action")!=null) {39             this.action = request.getParameter("action");40             41             if (action.equals("add")) {//添加商品进购物车42                 if(addToCart(request,response)){43                     request.getRequestDispatcher("/add_to_cart_success.jsp").forward(request, response);44                 }else {45                     request.getRequestDispatcher("/add_to_cart_failure.jspp").forward(request, response);46                 }47             }48             if (action.equals("show")) {//显示购物车49                 request.getRequestDispatcher("/cart.jsp").forward(request, response);50             }51             if(action.equals("delete")){//从购物车中删除商品52                 deleteFromCart(request,response);53                 request.getRequestDispatcher("/cart.jsp").forward(request, response);54             }55         }56     }57 58     /** 从购物车中删除商品  */59     private boolean deleteFromCart(HttpServletRequest request,60             HttpServletResponse response) {61         String id = request.getParameter("id");62         Cart cart = (Cart) request.getSession().getAttribute("cart");63         Items item = idao.getItemsById(Integer.parseInt(id));64         if (cart.removeGoodsFromCart(item)) {65             return true;66         }else {67             return false;68         }69     }70 71     /** 添加商品进购物车 */72     private boolean addToCart(HttpServletRequest request,73             HttpServletResponse response) {74         String id = request.getParameter("id");75         String number = request.getParameter("num");76         Items item = idao.getItemsById(Integer.parseInt(id));77         78         //是否是第一次给购物车添加商品?【给session中创建一个购物车对象】79         if (request.getSession().getAttribute("cart")==null) {80             Cart cart= new Cart();81             request.getSession().setAttribute("cart", cart);82         }83         84         //获得Session中保存的购物车对象85         Cart cart = (Cart) request.getSession().getAttribute("cart");86         if (cart.addGoodsInCart(item, Integer.parseInt(number))) {87             return true;88         }else {89             return false;90         }91     }92 93     public void init() throws ServletException {94     }95 96 }

CartServlet
  3.界面层在details.jsp页面中显示购物车。




  1 <%@page import="entity.Items"%>  2 <%@page import="dao.ItemsDAO"%>  3 <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%>  4 <%  5 String path = request.getContextPath();  6 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  7 %>  8 <!-- 显示商品详情,并在右侧显示商品的浏览记录(最近5条记录) -->  9 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 10 <html> 11   <head> 12     <title>欢迎光临网上商城</title> 13     <link href="css/main.css" rel="stylesheet" type="text/css"> 14     <script type="text/javascript" src="js/lhgcore.js"></script> 15     <script type="text/javascript" src="js/lhgdialog.js"></script> 16     <style type="text/css"> 17         div{ 18           float:left; 19           margin-left: 30px; 20           margin-right:30px; 21           margin-top: 5px; 22           margin-bottom: 5px; 23         } 24         div dd{ 25           margin:0px; 26           font-size:10pt; 27         } 28         div dd.dd_name{ 29           color:blue; 30         } 31         div dd.dd_city{ 32           color:#000; 33         } 34         div #cart{ 35          margin:0px auto; 36          text-align:right;  37         } 38         span{ 39          padding:0 2px;border:1px #c0c0c0 solid;cursor:pointer; 40         } 41         a{ 42           text-decoration: none;  43         } 44     </style> 45     <script type="text/javascript"> 46       function selflog_show(id) {  47          var num =  document.getElementById("number").value;  48          J.dialog.get({id: 'haoyue_creat',title: '购物成功',width: 600,height:400, link: '<%=path%>/servlet/CartServlet?id='+id+'&num='+num+'&action=add', cover:true}); 49       } 50       function add(){ 51          var num = parseInt(document.getElementById("number").value); 52          if(num<100){ 53             document.getElementById("number").value = ++num; 54          } 55       } 56       function sub(){ 57          var num = parseInt(document.getElementById("number").value); 58          if(num>1){ 59             document.getElementById("number").value = --num; 60          } 61       } 62     </script> 63   </head> 64    65   <body>  66       <h1>商品详情</h1><hr> 67       <a href="index.jsp">首页</a> >> <a href="index.jsp">商品列表</a><hr/> 68       <center> 69           <table width="750" height="60" cellpadding="0" cellspacing="0" border="0"> 70               <tr> 71               <!-- 商品详细信息 --> 72               <% 73                   Items item = new ItemsDAO().getItemsById(Integer.parseInt(request.getParameter("id"))); 74                   if(item!=null){ 75                %> 76                       <td width="70%" valign="top"> 77                           <table> 78                               <tr> 79                                   <td rowspan="4"><img src="images/<%=item.getPicture()%>" width="200" height="160"/></td> 80                               </tr> 81                               <tr> 82                                   <td><b><%=item.getName() %></b></td> 83                               </tr> 84                               <tr> 85                                   <td>产地:<%=item.getCity() %></td> 86                               </tr> 87                               <tr> 88                                   <td>价格:¥<font color="red"><b><%=item.getPrice() %></b></font></td> 89                               </tr> 90                               <tr> 91                                   <td> 92                                       购买数量:<span id="sub" onclick="sub();">-</span> 93                                       <input type="text" id="number" name="number" value="1" size="2"/> 94                                       <span id="add" onclick="add();">+</span> 95                                   </td> 96                               </tr> 97                           </table> 98                           <div id="cart"> 99                                <img src="images/buy_now.png">100                                <a href="javascript:selflog_show(<%=item.getId()%>)"><img src="images/in_cart.png" /></a>101                                <a href="servlet/CartServlet?action=show"><img src="images/view_cart.jpg"/></a>102                          </div>103                       </td>104               <%105                   }    106                %>107                <!-- 取得Cookie -->108                <%109                    String list = "";110                    // 从客户端获得Cookie集合111                    Cookie[]cookies = request.getCookies();112                    if(cookies!=null&&cookies.length>0){113                        for(Cookie c:cookies){114                            if(c.getName().equals("ListViewCookie")){115                                list = c.getValue();116                            }117                            118                            String[] arr = list.split(",");119                            // 相同商品只在浏览记录中存放一次120                            if(Arrays.binarySearch(arr, request.getParameter("id"))<0){121                                list += request.getParameter("id") + ",";122                            }123                            // 如果浏览记录超过1000条,则清空Cookie124                            if(arr!=null&&arr.length>1000){125                                list = "";// 清零-置空串126                            }127                            Cookie cookie = new Cookie("ListViewCookie",list);128                            response.addCookie(cookie);129                        }130                    }131                 %>132                 133                 <!-- 浏览过的商品 -->134                 <td width="30%" bgcolor="#EEE" align="center">135                     <br /><b>您浏览过的商品</b><br />136                     <!-- 循环开始 -->137                     <%138                         ArrayList<Items>itemsList = new ItemsDAO().getViewList(list);139                         if(itemsList!=null&&itemsList.size()>0){140                             for(Items i:itemsList){141                      %>142                             <div>143                                 <dl>144                                     <dt><img src="images/<%=i.getPicture() %>" width="120" height="90" border="1" /></dt>145                                     <dd class="dd_name"><%=i.getName() %></dd>146                                     <dd class="dd_city">产地:<%=i.getCity() %>&nbsp;&nbsp;价格:¥<%=i.getPrice() %></dd>147                                 </dl>148                             </div>149                     <%150                             }151                         }152                      %>153                     <!-- 循环结束 -->154                 </td>155               </tr>156           </table>157       </center>158   </body>159 </html>


0 0
原创粉丝点击