Servlet入门笔记
一、一个简单的Servlet
在servlet 3.0之前,下面是基本步骤:
1.新建一个class名为FirstServlet,让它继承javax.servlet.http.HttpServlet;
2.重写doGet和doPost方法:
public void doGet(HttpServletRequest request, HttpServletResponse response){
this.log("以GET方式访问");
} public void doPost(HttpServletRequest request, HttpServletResponse response){
this.log("以POST方式访问");
}
3.在web.xml中配置servlet:
首先,一个servlet的基本信息配置在一个<servlet>标签中,
<servlet>
<servlet-name>FirstServlet</servlet-name>
<servlet-class>com.levice.servlet.FirstServlet</servlet-class>
</servlet>
<servlet-name>代表servlet名称,可以取任意字符串,用于唯一标识某个servlet,一般和类名相同;<servlet-class>代表该servlet所指向的Servlet类。
然后,servlet的访问方式(地址)配置在<servlet-mapping>标签中,
<servlet-mapping>
<servlet-name>FirstServlet</servlet-name>
<url-pattern>/FirstServlet</url-pattern>
</servlet-mapping>
<servlet-name>代表servlet名称,<url-pattern>配置了该servlet的访问方式。上面的配置表示整个项目中可以使用“./FirstServlet”这个链接来访问这个servlet。
到这里,一个简单的servlet就编写和配置完毕了,在/FirstServlet前面加上主机域名、端口号和项目名就可以访问这个servlet了。比如,服务器就是本机,端口号是8080,项目名称是Test,那么在将项目部署到tomcat并启动tomcat服务后,在浏览器上输入http://localhost:8080/Test/FirstServlet就能访问刚才写的那个servlet了,控制台会输出“以GET方式访问”这句话。
二、在servlet中,还可以定义初始化参数
在servlet标签内,还可以使用init-param标签定义初始化参数,
<servlet>
<servlet-name>FirstServlet</servlet-name>
<servlet-class>com.levice.servlet.FirstServlet</servlet-class>
<init-param>
<param-name>ProjectName</param-name>
<param-value>Traditional</param-value>
</init-param>
</servlet>
param-name定义参数名,param-value定义参数值,在Servlet中使用getInitParameter(String paramName)来访问参数。
三、servlet中的资源注射
在servlet中使用@Resource修饰变量时,变量的值会在servlet运行时动态注入,例如
@Resource(name="TestResource")
private String message;
上面表示message的值会在servlet运行时动态注入,此时只需要在web.xml配置一个名为TestResource的参数就可以了,如下:
<env-entry>
<env-entry-name>TestResource</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>this is a test message</env-entry-value>
</env-entry>
在使用@Resource的时候,要注意import javax.annotation.Resource;同时,@Resource可以和变量使用在同一行中:
private @Resource(name="TestResource") String message;
四、servlet的生命周期
Servlet会在服务器启动或第一次请求该Servlet时开始生命周期,在服务器结束时结束生命周期。无论多少次请求Servlet,最多只有一个Servlet实例。多个客户端并发请求Servlet时,服务器会启动多个线程分别执行该Servlet的service()方法。
在Servlet对象的生命周期中,init(ServletConfig conf)方法与destroy()均只会被服务器执行一次,而service()在每次客户端请求Servlet时都会被执行。Servlet中有时会用到一些需要初始化与销毁的资源,因此可以把初始化资源的代码放入init()方法内,把销毁该资源的代码放入到destroy()方法内,而不需要每次处理请求都要初始化与销毁资源。
对于Servlet的init(ServletConfig conf)方法,HttpServlet提供了一个更简单的不带参数的替代方法init()。HttpServlet加载时会执行这个不带参数的init()方法,因此只需把代码放置在init()中就可以了。对于原来的ServletConfig参数,仍然可以通过getServletConfig()方法获取到。
从Java EE 5规范开始,Servlet中增加了两个影响Servlet生命周期的注解:@PostConstruct和@PreDestroy。这两个注解被用来修饰非静态的void()方法,而且该方法不能抛出异常声明。该注解同样可以写在方法前或返回类型void前面,如下:
@PostConstruct
public void someMethod(){
...
} public @PreDestroy void anotherMethod(){
...
}
被@PostConstruct修饰的方法会在服务器加载Servlet时运行,并且只会被服务器调用一次,类似于init()方法。事实上,@PostConstruct修饰的方法构造函数之后、init()方法之前被运行。
被@PreDestroy修饰的方法会在服务器卸载Servlet时运行,并且只会被服务器调用一次,类似于destroy()方法。被@PreDestroy修饰的方法会在destroy()之后(注意,不是之前),Servlet被彻底卸载之前运行。
五、servlet之间的跳转
Servlet之间的跳转通过RequestDispatcher对象的forward(HeetServletResquest req, HttpSevletResponse res)来实现,例如,跳转到另一个servlet:
RequestDispatcher dispatcher = request.getRequestDispatcher("/servlet/SecondServlet");
dispatcher.forward(request, response);
getRequestDispatcher()方法的参数必须以“/”开始,“/”表示Web应用程序的根目录。
Forward不仅可以跳转到Servlet,还可以跳转到另外一个文件,甚至WEB-INF文件夹下的文件,其中跳转到Servlet和JSP页面是最常见的。
六、servlet与线程安全
线程安全问题是指在多线程并发执行时,会不会出现问题。如果不出现问题,则是线程安全的;如果会出现问题,则是线程不安全的。
Servlet只会有一个实例,多个用户同时请求Servlet时,Tomcat会派生出多条线程执行Servlet代码,因此Servlet有线程不安全的隐患。看下面一个例子:
public class TestServlet extends HttpServlet {
private String name; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException{
name=request.getParameter("name");
try{
Thread.sleep(10000);
}catch(InterruptedException e) {}
response.getWriter().println("Hello," + name);
}
这段代码让线程沉睡了10秒。10秒内分别用两个浏览器访问TestServlet?name=jack和TestServlet?name=tom,显示的结果均为“Hello,tom”,这就意味着程序出了问题。在前一个线程输出之前,后一个线程已将name修改成了tom。解决的办法是尽量不要像这样定义name,而把name定义在doGet和doPost里面。使用synchronized(name){}语句块也可以解决问题,但会造成线程等待,这样并不科学。
七、servlet 3.0
前面介绍了3.0之前的servlet,当servlet到了3.0,就变得高大上了许多,再也不需要配置web.xml了,所有配置都通过注解完成。我们看一个servlet 3.0的例子:
package com.levice.servlet; import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; /**
* Servlet implementation class MethodServlet
*/
@WebServlet(
description = "show the using of different nethod",
urlPatterns = { "/MethodServlet" },
initParams = {
@WebInitParam(name = "ProjectName", value = "Levice"),
@WebInitParam(name = "ServletName", value = "MethodServlet")
})
public class MethodServlet extends HttpServlet {
private static final long serialVersionUID = 1L; /**
* @see HttpServlet#HttpServlet()
*/
public MethodServlet() {
super();
// TODO Auto-generated constructor stub
} /**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.getWriter().append("Served at: ").append(request.getContextPath());
this.log("Hello World! again");
this.log(getInitParameter("ProjectName"));
} /**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
} }
如上,使用@WebServlet注释该Servlet后,就不需要web.xml中配置了,在description、urlPatterns和initParams这几个参数中只有urlPatterns是必须的。当然,要使用这些注解,下面两句是必不可少的:
import javax.servlet.annotation.WebInitParam; import javax.servlet.annotation.WebServlet;
Servlet入门笔记的更多相关文章
- 每天成长一点---WEB前端学习入门笔记
WEB前端学习入门笔记 从今天开始,本人就要学习WEB前端了. 经过老师的建议,说到他每天都会记录下来新的知识点,每天都是在围绕着这些问题来度过,很有必要每天抽出半个小时来写一个知识总结,及时对一天工 ...
- ES6入门笔记
ES6入门笔记 02 Let&Const.md 增加了块级作用域. 常量 避免了变量提升 03 变量的解构赋值.md var [a, b, c] = [1, 2, 3]; var [[a,d] ...
- [Java入门笔记] 面向对象编程基础(二):方法详解
什么是方法? 简介 在上一篇的blog中,我们知道了方法是类中的一个组成部分,是类或对象的行为特征的抽象. 无论是从语法和功能上来看,方法都有点类似与函数.但是,方法与传统的函数还是有着不同之处: 在 ...
- React.js入门笔记
# React.js入门笔记 核心提示 这是本人学习react.js的第一篇入门笔记,估计也会是该系列涵盖内容最多的笔记,主要内容来自英文官方文档的快速上手部分和阮一峰博客教程.当然,还有我自己尝试的 ...
- redis入门笔记(2)
redis入门笔记(2) 上篇文章介绍了redis的基本情况和支持的数据类型,本篇文章将介绍redis持久化.主从复制.简单的事务支持及发布订阅功能. 持久化 •redis是一个支持持久化的内存数据库 ...
- redis入门笔记(1)
redis入门笔记(1) 1. Redis 简介 •Redis是一款开源的.高性能的键-值存储(key-value store).它常被称作是一款数据结构服务器(data structure serv ...
- OpenGLES入门笔记四
原文参考地址:http://www.cnblogs.com/zilongshanren/archive/2011/08/08/2131019.html 一.编译Vertex Shaders和Fragm ...
- OpenGLES入门笔记三
在入门笔记一中比较详细的介绍了顶点着色器和片面着色器. 在入门笔记二中讲解了简单的创建OpenGL场景流程的实现,但是如果在场景中渲染任何一种几何图形,还是需要入门笔记一中的知识:Vertex Sha ...
- unity入门笔记
我于2010年4月1日硕士毕业加入完美时空, 至今5年整.刚刚从一家公司的微端(就是端游技术+页游思想, 具体点就是c++开发, directX渲染, 资源采取所需才会下载)项目的前端主程职位离职, ...
随机推荐
- 与大家分享robotium一个小问题。Test run failed:Instrumentation run failed due to 'java.lang.ClassNotFoundException'
今天和大家分享robotium一个小问题. 我们在运行自已经搭好的框架时,有可能会出现一个找不到类的错误(如上图所示). 问题是重签名工具给出的activity有误,这时我们可以用Appt命令查看重签 ...
- SQL Server 批量主分区备份(Multiple Jobs)
一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 案例分析(Case) 方案一(Solution One) 方案二(Solution Two) ...
- Redis系列之key操作命令与Redis中的事务详解(六)
序言 本篇主要目的有二: 1.展示所有数据类型中key的所有操作命令,以供大家学习,查阅,更深入的挖掘redis潜力. 2.掌握redis中的事务,让你的数据完整性一致性拥有更优的保障. redis命 ...
- 慕课网H5圣诞主题
继七夕之后,我又出了一个圣诞主题的课程.圣诞主题是基于HTML5+CSS+JS编写与实现的,同时也是七夕主题的故事延续.圣诞主题依旧延续着七夕主题设计的思路,引入了3个经典的场景页面,在每个场景中表述 ...
- HTML自定义对象与属性(谷歌,火狐,IE9浏览器没问题)
1.自定义标签 <zqz>asdas</zqz> <style> zqz{ color:red; } </style> 页面变色 2.自定义标签的hov ...
- JavaScript权威设计--JavaScript对象(简要学习笔记七)
1.with语句 语法: width(object){ statement } with语句可用于临时扩展作用域链.作用域链可以按序检索的对象列表,通过它可以进行变量名解析. with将object添 ...
- SQL Server-聚焦使用索引和查询执行计划(五)
前言 上一篇我们讲了聚集索引对非聚集索引的影响,对数据库一直在强调的性能优化,所以这一节我们统筹讲讲利用索引来看看查询执行计划是怎样的,简短的内容,深入的理解,Always to review the ...
- 坎坷路:ASP.NET 5 Identity 身份验证(上集)
之所以为上集,是因为我并没有解决这个问题,写这篇博文的目的是纪录一下我所遇到的问题,以免自己忘记,其实已经忘了差不多了,写的过程也是自己回顾的过程,并且之前收集有关 ASP.NET 5 身份验证的书签 ...
- ARM CPU大小端
ARM CPU大小端: 大端模式:低位字节存在高地址上,高位字节存在低地址上 小端模式:高位字节存在高地址上,低位字节存在低地址上 STM32属于小端模式,简单的说,比如u32 temp=0X1234 ...
- Properties操作指南
一.简介: Properties是java中用的比较多的一个类,表示一个持久的属性集.继承于Hashtable,Properties可从流中加载,也可保存在流中.属性列表中每个键极其对应值共同组成一个 ...