您的位置:首页 > 编程语言 > Java开发

javaWeb实战教程1-servlet

2017-06-30 11:59 375 查看

javaWeb实战教程

1.简介

本教程将使用servlet+jsp的技术实现一个在线商城,项目中还会使用到过滤器filter、jdbc连接数据库、dbutils更方便的操作数据库、jstl标准标签库、fileupload实现文件的上传、Cookie的存取、jsp页面重定向、JavaBean、JSP 异常处理等技术。



【此处在浏览器中展示已完成的商城】

本商城包含用户注册/登录、商品展示、购物车、订单的生成/展示等几个模块,在开始项目前,必须先学习javaWeb的基础内容。

2.基础讲解

2.1 servlet

2.1.1 Servlet 是什么?

Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。

使用 Servlet,您可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页。

2.1.2 Servlet 架构

下图显示了 Servlet 在 Web 应用程序中的位置。



用户通过浏览器访问HTTP服务器,HTTP服务器包装好request和response传给servlet程序,程序内是由程序员写好的业务逻辑和操作数据库的代码,serlvet运行完成后将数据保存到response内传给HTTP服务器,HTTP服务器再将数据发送给用户的浏览器。

【此处新建一个项目,演示一个servlet】

我们先来创建一个servlet,在servlet中打印一句话:hello world。

打开eclipse,新建一个Dynamic Web Project项目,在src上新建一个包:cn.funsoftware.lesson.servlet,在包下新建一个class:Lesson1.java。

在实际项目中,我们通常使用公司的网址作为包名。

package cn.funsoftware.Lesson.servlet;

public class Lesson1 {

}


让Lesson1继承于javax.servlet.http.HttpServlet:

public class Lesson1 extends HttpServlet{

}


重载doGet()方法:

@Override
protected void doGet(HttpServletRequest req,
HttpServletResponse resp) throws ServletException, IOException {

}


在doGet方法里写上

resp.getOutputStream().write("hello world".getBytes());


再将我们写的servlet配置到web服务器上,在
public class Lesson1
上添加注解:
@WebServlet("/lesson1")


@WebServlet("/lesson1")
public class Lesson1 extends HttpServlet{

@Override
protected void doGet(HttpServletRequest req,
HttpServletResponse resp) throws ServletException, IOException {
resp.getOutputStream().write("hello world".getBytes());}
}


也可以不使用注解来配置servlet,在WEB-INF文件夹下的web.xml文件里写上:

<servlet>
<servlet-name>lesson1</servlet-name>
<servlet-class>cn.funsoftware.Lesson.servlet.Lesson1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>lesson1</servlet-name>
<url-pattern>/lesson1</url-pattern>
</servlet-mapping>


两种配置效果是相同的。注解的配置方法只在servlet3.0中才被支持;servlet的版本号和服务器自带的serlvet-api.jar有关,其中tomcat7.0以上版本支持servlet3.0。

我们把项目运行到tomcat服务器上,在浏览器中打开网址http://localhost/javaWeb/lesson1查看效果。

2.1.3 Servlet 生命周期

Servlet 生命周期可被定义为从创建直到毁灭的整个过程。以下是 Servlet 遵循的过程:

Servlet 通过调用 init () 方法进行初始化,在整个生命周期中,init()方法只会被执行一次。

Servlet 调用 service() 方法来处理客户端的请求。

Servlet 通过调用 destroy() 方法终止(结束),在整个生命周期中,destroy()方法只会被执行一次。

最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。

2.1.4 init() 方法

init 方法被设计成只调用一次。它在第一次创建 Servlet 时被调用,在后续每次用户请求时不再调用。因此,它是用于一次性初始化。

Servlet 创建于用户第一次调用对应于该 Servlet 的 UR
a3a8
L 时,但是您也可以指定 Servlet 在服务器第一次启动时被加载。

当用户调用一个 Servlet 时,就会创建一个 Servlet 实例,每一个用户请求都会产生一个新的线程,适当的时候移交给 doGet 或 doPost 方法。init() 方法简单地创建或加载一些数据,这些数据将被用于 Servlet 的整个生命周期。

init 方法的定义如下:

public void init() throws ServletException {
// 初始化代码...
}


2.1.5 service() 方法

service() 方法是执行实际任务的主要方法。Servlet 容器(即 Web 服务器)调用 service() 方法来处理来自客户端(浏览器)的请求,并把格式化的响应写回给客户端。

每次服务器接收到一个 Servlet 请求时,服务器会产生一个新的线程并调用服务。service() 方法检查 HTTP 请求类型(GET、POST、PUT、DELETE 等),并在适当的时候调用 doGet、doPost、doPut,doDelete 等方法。

下面是该方法的特征:

public void service(ServletRequest request,
ServletResponse response)
throws ServletException, IOException{
}


service() 方法由容器调用,service 方法在适当的时候调用 doGet、doPost、doPut、doDelete 等方法。所以,您不用对 service() 方法做任何动作,您只需要根据来自客户端的请求类型来重写 doGet() 或 doPost() 即可。

doGet() 和 doPost() 方法是每次服务请求中最常用的方法。下面是这两种方法的特征。

2.1.6 doGet() 方法

GET 请求来自于一个 URL 的正常请求,或者来自于一个未指定 METHOD 的 HTML 表单,它由 doGet() 方法处理。

public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
// Servlet 代码
}


2.1.7 doPost() 方法

POST 请求来自于一个特别指定了 METHOD 为 POST 的 HTML 表单,它由 doPost() 方法处理。

public void doPost(HttpServletRequest request,HttpServletResponse response)
throws ServletException, IOException {
// Servlet 代码
}


2.1.8 destroy() 方法

destroy() 方法只会被调用一次,在 Servlet 生命周期结束时被调用。destroy() 方法可以让您的 Servlet 关闭数据库连接、停止后台线程、把 Cookie 列表或点击计数器写入到磁盘,并执行其他类似的清理活动。

在调用 destroy() 方法之后,servlet 对象被标记为垃圾回收。destroy 方法定义如下所示:

public void destroy() {
// 终止化代码...
}


2.1.9 架构图

下图显示了一个典型的 Servlet 生命周期方案。

第一个到达服务器的 HTTP 请求被委派到 Servlet 容器。

Servlet 容器在调用 service() 方法之前加载 Servlet。

然后 Servlet 容器处理由多个线程产生的多个请求,每个线程执行一个单一的 Servlet 实例的 service() 方法。



因为servlet被多个线程调用,所以会出现线程安全问题;比如在servlet中定义个全局变量
int i=0;
,并在doGet()方法里执行
i++;
,当多个线程同时调用时,i的值不会像预期那样自增;所以不要在servlet内随意定义全局变量又不考虑线程安全。

2.1.10 servlet处理表单数据

很多情况下,需要传递一些信息,从浏览器到 Web 服务器,最终到后台程序。浏览器使用两种方法可将这些信息传递到 Web 服务器,分别为 GET 方法和 POST 方法。

GET 方法

GET 方法向页面请求发送已编码的用户信息。页面和已编码的信息中间用 ? 字符分隔,如下所示:

http://localhost/javaWeb/lesson2?key1=value1&key2=value2


我们新建一个servlet名叫Lesson2,并继承与HttpServlet,重载doGet()方法,在其中获取从浏览器传过来的key1和key2的值:

protected void doGet(javax.servlet.http.HttpServletRequest req, javax.servlet.http.HttpServletResponse resp)
throws javax.servlet.ServletException, java.io.IOException {

System.out.println(req.getParameter("key1"));
System.out.println(req.getParameter("key2"));

};


POST 方法

另一个向后台程序传递信息的比较可靠的方法是 POST 方法。POST 方法打包信息的方式与 GET 方法基本相同,但是 POST 方法不是把信息作为 URL 中 ? 字符后的文本字符串进行发送,而是把这些信息作为一个单独的消息。消息以标准输出的形式传到后台程序,您可以解析和使用这些标准输出。Servlet 使用 doPost() 方法处理这种类型的请求。

我们在WebContent目录下新建一个html:
lesson2_post.html
,在
lesson2_post.html
内写一个
form
表单:

<form action="/javaWeb/lesson2" method="post">
<input type="text" name="key1"/>
<input type="text" name="key2"/>
<input type="submit" value="post表单提交"/>
</form>


再在Lesson2.java里重载doPost方法:

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println(req.getParameter("key1"));
System.out.println(req.getParameter("key2"));
}


在浏览器里访问http://localhost/javaWeb/lesson2_post.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: