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 58 <input type="checkbox" name="favorite" value="music"> 音乐 59 <input type="checkbox" name="favorite" value="movie"> 电影 60 <input type="checkbox" name="favorite" value="internet"> 上网 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="注册"/> 78 <input type="reset" value="取消"/> 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"> <jsp:getProperty name="regUser" property="username"/></td>30 </tr>31 <tr>32 <td class="title">密码:</td>33 <td class="content"> <jsp:getProperty name="regUser" property="password"/></td>34 </tr>35 <tr>36 <td class="title">性别:</td>37 <td class="content"> <jsp:getProperty name="regUser" property="sex"/></td>38 </tr>39 <tr>40 <td class="title">E-mail:</td>41 <td class="content"> <jsp:getProperty name="regUser" property="email"/></td>42 </tr>43 <tr>44 <td class="title">出生日期:</td>45 <td class="content"> 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"> 56 <% 57 String[] favorites = regUser.getFavorites();58 if(favorites!=null){59 for(String f:favorites)60 {61 %>62 <%=f%> 63 <% 64 }65 }66 %>67 </td>68 </tr>69 <tr>70 <td class="title">自我介绍:</td>71 <td class="content"> <jsp:getProperty name="regUser" property="introduce"/></td>72 </tr>73 <tr>74 <td class="title">是否介绍协议:</td>75 <td class="content"> <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() %> 价格:¥<%=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
- Servlet基础 及详细介绍(附带代码)
- jsp基础及详细介绍(附带案例代码)
- Servlet的应用及详细介绍
- 详细介绍 CVS (附带 其配置与使用方法)
- Servlet 介绍 以及Servlet生命周期(详细)
- Servlet 介绍 以及Servlet生命周期(详细)
- Servlet 介绍 以及Servlet生命周期(详细)
- 网球循环赛赛程安排(分治策略)---附带详细代码
- iOS 3D Touch超详细入门介绍(附带demo示例代码)
- RabbitMQ基础概念详细介绍及示例
- 设计模式详细介绍及代码举例
- 03饭店管理系统总结(附带代码及报告)
- 心得2--Servlet详细介绍及应用分析
- 心得2--Servlet详细介绍及应用分析 .
- servlet的详细介绍
- servlet的详细介绍
- Servlet入门基础介绍
- Servlet基础介绍
- iPhone学习之路 TableView实现动态加载图片
- hibernate配置文件简介,以及主键生成策略
- 编译错误 --- does not name a type和field `XX' has incomplete type
- 对称密钥与非对称密钥
- 读取iOS设备中应用的数据
- Servlet基础 及详细介绍(附带代码)
- Note Pad++ 和 Srt 两个工具的两点小应用
- Grizzly:Java NIO框架
- TCP实现过程详解
- opencv特征检测之角点检测
- 关于 myqsl的字符存储问题
- Linux环境中往MySQl数据库导入数据文件乱码问题
- 测试
- 最详细的Codis集群扩容方法