本文主要介绍servlet,包括入门到升入,基本上可以对servlet有一个很好的认识;

1servlet介绍:

  Servlet(Server Applet),全称Java Servlet,未有中文译文。是用Java编写的服务器端程序。其主要功能在于交互式地浏览和修改数据,生成动态Web内容。狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。

手把手教你建立一个继承servlet的类:

  1. 在webcontent点击右键选择other,选择servlet,这里就建成了servlet的类
  2. 重写doGet和doPost方法
public class TestServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
out.println("hello peace");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
  1. 修改web.xml或者加上webServlet注解:

    修改web.xml:在根标签下加入一下代码
<!-- 配置一个servlet -->
<!-- servlet的配置 -->
<servlet>
<!-- servlet的内部名称,自定义。尽量有意义 -->
<servlet-name>TestServlet</servlet-name>
<!-- servlet的类全名: 包名+简单类名 -->
<servlet-class>com.rlovep.servlet.TestServlet</servlet-class>
<!-- servlet的映射配置 -->
</servlet>
<servlet-mapping>
<!-- servlet的内部名称,一定要和上面的内部名称保持一致!! -->
<servlet-name>TestServlet</servlet-name>
<!-- servlet的映射路径(访问servlet的名称) -->
<url-pattern>/TestServlet</url-pattern>
</servlet-mapping>

或者在类定义上加上webServlet的注解(注意两者只能有一个)

注意:1.不要在web.xml根标签中指定metadata-complete="true".2。不要在web.xml中配置servlet

修改后的servlet类:

@WebServlet("/TestServlet")//设置servlet的访问路径为/TestServlet;或者这样写@WebServlet(name="TestServlet",urlPatterns={"/TestServlet"})
public class TestServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
out.println("hello peace");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
  1. 访问http://localhost:8080/HttpSer/TestServlet即可看到结果。

2servlet的路径映射:

<url-pattern>/TestServlet</url-pattern>或者:@WebServlet(urlPatterns={"/TestServlet"})
匹配方式 url-pattern 地址栏
精确匹配 /TestServlet
/TestServlet/test
http://localhost:8080/HttpSer/TestServlet
http://localhost:8080/HttpSer/TestServlet/test
模糊匹配 /*
/TestServlet/*
/*.do
http://localhost:8080/HttpSer/任意路径
http://localhost:8080/HttpSer/TestServlet/任意路径
http://localhost:8080/HttpSer/任意路径.do

__注意__
1)url-pattern要么以 / 开头,要么以*开头。 例如, TestServlet是非法路径。
2)不能同时使用两种模糊匹配,例如 /TestServlet/*.do是非法路径
3)当有输入的URL有多个servlet同时被匹配的情况下:
  3.1 精确匹配优先。(长的最像优先被匹配)
  3.2 以后缀名结尾的模糊url-pattern优先级最低!!!
##3servlet生命周期:
1. 生命周期的引入:
Servlet的生命周期: servlet类对象什么时候创建,什么时候调用什么方法,什么时候销毁。
以前的对象: new Student(); stu.study(); stu=null;
Servlet程序的生命周期由tomcat服务器控制的!!!!
2. Servlet重要的四个生命周期方法:
构造方法: 创建servlet对象的时候调用。默认情况下,第一次访问servlet的时候创建servlet对象 只调用1次。证明servlet对象在tomcat是单实例的。
init方法: 创建完servlet对象的时候调用。只调用1次。
service方法: 每次发出请求时调用。调用n次。
destroy方法: 销毁servlet对象的时候调用。停止服务器或者重新部署web应用时销毁servlet对象。只调用1次。
3. 代码演示:
```
@WebServlet(name="TestServlet",urlPatterns={"/TestServlet"})
public class TestServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
int i=0;
/**
* 1.构造方法,只被调用一次
*/
public TestServlet() {
super();
System.out.println("构造方法>>>>");
}
/**
* 2.init初始化方法,在构造方法后只被调用一次
* 有参数的init方法会调用init方法;;一般覆盖无参数的init方法;
*/
@Override
public void init() throws ServletException {
// TODO Auto-generated method stub
super.init();
System.out.println("inti>>>>");
}
/**
* 3.service方法,发生请求和响应时调用的方法,次数不限
* 一般是重写doget和dopost,此去只是方便演示
*/
@Override
protected void service(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException {
System.out.println("service>>>" +i++);
}
/**
* 4.destory方法,只有在停止服务器和重新部署web应用时调用
*/
@Override
public void destroy() {
System.out.println("destory");
super.destroy();
}
}
#输出结果:http://localhost:8080/HttpSer/TestServlet。连续访问四次,得到下面的结果:
构造方法>>>>
inti>>>>
service>>>0
service>>>1
service>>>2
service>>>3
Oct 11, 2015 8:53:52 PM org.apache.catalina.core.StandardContext reload
INFO: Reloading Context with name [/HttpSer] has started
destory
```
4. 伪代码演示:
```
Tomtcat内部代码运行:
1)通过映射找到到servlet-class的内容,字符串: com.rlovep.serlvet.TestServlet
2)通过反射构造TestServlett对象
2.1 得到字节码对象
Class clazz = class.forName(" com.rlovep.serlvet.TestServlet");
2.2 调用无参数的构造方法来构造对象
Object obj = clazz.newInstance(); ---1.servlet的构造方法被调用
3)创建ServletConfig对象,通过反射调用init方法
3.1 得到方法对象
Method m = clazz.getDeclareMethod("init",ServletConfig.class);
3.2 调用方法
m.invoke(obj,config); --2.servlet的init方法被调用
4)创建request,response对象,通过反射调用service方法
4.1 得到方法对象
Methodm m =clazz.getDeclareMethod("service",HttpServletRequest.class,HttpServletResponse.class);
4.2 调用方法
m.invoke(obj,request,response); --3.servlet的service方法被调用
5)当tomcat服务器停止或web应用重新部署,通过反射调用destroy方法
5.1 得到方法对象
Method m = clazz.getDeclareMethod("destroy",null);
5.2 调用方法
m.invoke(obj,null); --4.servlet的destroy方法被调用
```
5. 图像演示如下:
![1](http://7xk3em.com1.z0.glb.clouddn.com/servlet0101.png)

4自动加载servlet:

默认情况下,第一次访问servlet的时候创建servlet对象。如果servlet的构造方法或init方法中执行了比较多的逻辑代码,那么导致用户第一次访问sevrlet的时候比较慢。

改变servlet创建对象的时机: 提前到加载web应用的时候!!!

在servlet的配置信息中,加上一个或者加上注解(loadOnStartup=1)即可:

 <servlet>
<!-- servlet的内部名称,自定义。尽量有意义 -->
<servlet-name>TestServlet</servlet-name>
<!-- servlet的类全名: 包名+简单类名 -->
<servlet-class>com.rlovep.serlvet.TestServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
或者:
@WebServlet(name="TestServlet",loadOnStartup=1,urlPatterns={"/TestServlet"})

5多用户问题:

注意: servlet对象在tomcat服务器是单实例多线程的。可以有多个用户;

因为servlet是多线程的,所以当多个线程同时访问了servlet的共享数据,如成员变量,可能会引发线程安全问题。

解决办法:

1)把使用到共享数据的代码块进行同步(使用synchronized关键字进行同步)

2)建议在servlet类中尽量不要使用成员变量。如果确实要使用成员,必须同步。而且尽量缩小同步代码块的范围。(哪里使用到了成员变量,就同步哪里!!),以避免因为同步而导致并发效率降低。

6Servlet常用对象:

servlet:有几个比较有用的对象:

1.HttpServletRequest   请求对象   http协议中已讲
2.HttpServletResponse 响应对象 http协议中已讲
3.ServletConfig servlet配置对象
4.ServletContext Servlet的上下文对象。对整个web应用有效
5.HttpSession 会话对象,当一个用户向服务器发送第一个请求时,服务器为其建立一个session,并为此session创建一个标识号;

ServletConfig对象介绍:

ServletConfig对象: 主要是用于加载servlet的初始化参数。在一个web应用可以存在多个ServletConfig对象(一个Servlet对应一个ServletConfig对象)

可以直接从getServletConfig方法;或者自己在有参的init中获得 .

在web.xml中创建参数:一样有两种方法:

 <servlet>
<!-- servlet的内部名称,自定义。尽量有意义 -->
<servlet-name>TestConfig</servlet-name>
<!-- servlet的类全名: 包名+简单类名 -->
<servlet-class>com.rlovep.serlvet.TestConfig</servlet-class>
<init-param>
<param-name>name</param-name>
<param-value>peace</param-value>
</init-param>
</servlet>
或者:
@WebServlet(urlPatterns={"/TestConfig"},
initParams={@WebInitParam(name="driver",value="com.mysql*")
,@WebInitParam(name="url",value="jdbc*"),
@WebInitParam(name="user",value="root"),
@WebInitParam(name="pass",value="123456")})

测试如下:

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletConfig servletConfig = getServletConfig();
//得到servlet的名字
System.out.println(servletConfig.getServletName());
//根据参数名获取参数值
String name=servletConfig.getInitParameter("user");
System.out.println(name+">>>>>");
//获取所有参数名称
Enumeration<String> names = servletConfig.getInitParameterNames();
while(names.hasMoreElements()){
String s=names.nextElement();
System.out.println(s+"="+servletConfig.getInitParameter(s));
}
}

ServletContext对象介绍:

1. 引入

ServletContext对象 ,叫做Servlet的上下文对象。表示一个当前的web应用环境。一个web应用中只有一 个ServletContext对象。

2. 对象引用的得到

创建时机:加载web应用时创建ServletContext对象。

得到对象: 从ServletConfig对象的getServletContext方法得到或者直接调用ServletContext servletContext = getServletContext();

3. 核心api

java.lang.String getContextPath()   --得到当前web应用的路径
java.lang.String getInitParameter(java.lang.String name) --得到web应用的初始化参数
java.util.Enumeration getInitParameterNames()
void setAttribute(java.lang.String name, java.lang.Object object) --域对象有关的方法
java.lang.Object getAttribute(java.lang.String name)
void removeAttribute(java.lang.String name)
RequestDispatcher getRequestDispatcher(java.lang.String path) --转发(类似于重定向)
java.lang.String getRealPath(java.lang.String path) --得到web应用的资源文件
java.io.InputStream getResourceAsStream(java.lang.String path)

4. 演示如下

ServletContext servletContext = getServletContext();
//得到当前web应用路径
System.out.println("路径:"+servletContext.getContextPath());
//根据参数名获得参数值
System.out.println("AAA="+servletContext.getInitParameter("AAA"));
//获取所有参数名称
Enumeration<String> names = servletContext.getInitParameterNames();
while(names.hasMoreElements()){
String s=names.nextElement();
System.out.println(s+":"+servletContext.getInitParameter(s));
}
//设置域对象,整个web应用有效
servletContext.setAttribute("name","peace");
servletContext.setAttribute("age", "23");
//获得域对象
System.out.println("name"+servletContext.getAttribute("name"));
System.out.println("age"+servletContext.getAttribute("age"));
//删除域对象
servletContext.removeAttribute("age");
System.out.println("age"+servletContext.getAttribute("age"));

7.转发和重定向;

域对象介绍:

域对象:作用是用于保存数据,获取数据。可以在不同的动态资源(servlet)之间共享数据。

案例:

#通过重定向,使用实体内容传递数据,一般只能存储字符
Servlet1 传数据:name=eric
response.sendRedirect("/Servlet2?name=eric")
Servlet2接收:
String request.getParameter("name");
#通过域对象传递:可以传递任何数据;
ServletContext就是一个域对象,上面有介绍怎么用
保存数据:void setAttribute(java.lang.String name, java.lang.Object object)
获取数据: java.lang.Object getAttribute(java.lang.String name)
删除数据: void removeAttribute(java.lang.String name)
ServletContext域对象:作用范围在整个web应用中有效!!!
所有域对象:
HttpServletRequet 域对象 测试;
ServletContext域对象
HttpSession 域对象
PageContext域对象

重定向:

重定向是服务器告诉浏览器,重新请求另一页面,请求信息丢失更新

a)地址栏会改变,变成重定向到地址。

b)重定向可以跳转到当前web应用,或其他web应用,甚至是外部域名网站。

c)不能在重定向的过程,把数据保存到request中。

测试如下:

1.建立一个TestRedect servlet:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/**
* 保存数据到request域对象
*/
request.setAttribute("name", "rose");
//重定向
/**
* 注意:可以跳转到web应用内,或其他web应用,甚至其他外部域名。
*/
//request域数据会丢失
response.sendRedirect("/HttpSer/GetData");
//重定向到外部域名:
//response.sendRedirect("www.baidu.com");
}
2.建立一个GetData的servlet
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
out.println("hello");
System.out.println("获得域对象"+request.getAttribute("name"));
}

现象如下:

1.地址栏从http://localhost:8080/HttpSer/TestRedect变为http://localhost:8080/HttpSer/GetData;

2.request域对象数据丢失:获得域对象null

转发:

转发是服务器将请求信号封装后转发到另一个servlet页面,请求信息会保存

a)地址栏不会改变

b)转发只能转发到当前web应用内的资源

c)可以在转发过程中,可以把数据保存到request域对象中

测试如下:

1.建立一个TestRedect servlet:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/**
* 保存数据到request域对象
*/
request.setAttribute("name", "rose");
//转发
/**
* 注意:不能转发当前web应用以外的资源。
*/
/*RequestDispatcher rd = this.getServletContext().getRequestDispatcher("/GetDataServlet");
rd.forward(request, response);*/
this.getServletContext().
getRequestDispatcher("/GetData").forward(request, response);
}
2.建立一个GetData的servlet
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
out.println("hello");
System.out.println("获得域对象"+request.getAttribute("name"));
}

现象如下:

1.地址栏没有变化

2.request域对象数据没有丢失:获得域对象rose

来自一条小鲨鱼(rlovep.com)

代码下载

Servlet入门实践的更多相关文章

  1. Cookie快速入门实践

    第一个servlet[比如是CookieDemo01]中的代码如下: import javax.servlet.http.Cookie; //--------省略若干代码----------- pro ...

  2. Spring Boot WebFlux 快速入门实践

    02:WebFlux 快速入门实践 Spring Boot 2.0 spring.io 官网有句醒目的话是: BUILD ANYTHING WITH SPRING BOOT Spring Boot ( ...

  3. Spring Boot WebFlux-01——WebFlux 快速入门实践

    第01课:WebFlux 快速入门实践 Spring Boot 2.0 spring.io 官网有句醒目的话是: BUILD ANYTHING WITH SPRING BOOT Spring Boot ...

  4. 分布式学习系列【dubbo入门实践】

    分布式学习系列[dubbo入门实践] dubbo架构 组成部分:provider,consumer,registry,monitor: provider,consumer注册,订阅类似于消息队列的注册 ...

  5. sass、less和stylus的安装使用和入门实践

    刚 开始的时候,说实话,我很反感使用css预处理器这种新玩意的,因为其中涉及到了编程的东西,私以为很复杂,而且考虑到项目不是一天能够完成的,也很少是 一个人完成的,对于这种团队的项目开发,前端实践用c ...

  6. HTTP协议 Servlet入门 Servlet工作原理和生命周期 Servlet细节 ServletConfig对象

    1 HTTP协议特点   1)客户端->服务端(请求request)有三部份     a)请求行--请求行用于描述客户端的请求方式.请求的资源名称,以及使用的HTTP协议版本号 请求行中的GET ...

  7. Django入门实践(三)

    Django入门实践(三) Django简单应用 前面简单示例说明了views和Template的工作过程,但是Django最核心的是App,涉及到App则会和Model(数据库)打交道.下面举的例子 ...

  8. Django入门实践(二)

    Django入门实践(二) Django模板简单实例 上篇中将html写在了views中,这种混合方式(指Template和views混在一起)不适合大型开发,而且代码不易管理和维护,下面就用Djan ...

  9. Django入门实践(一)

    Django入门实践(一) Django编程思路+入门 认识Django有一个多月了,我觉得学习Django应该先理清它的编程思路.它是典型的MVC框架(在Django里也称MTV),我觉得Djang ...

随机推荐

  1. SpringBoot中使用LoadTimeWeaving技术实现AOP功能

    目录 1. 关于LoadTimeWeaving 1.1 LTW与不同的切面织入时机 1.2 JDK实现LTW的原理 1.3 如何在Spring中实现LTW 2. Springboot中使用LTW实现A ...

  2. animate.css动画种类

    animate.css 一个非常好用的css动画库 Github地址 包括了一下多种动画 1. bounce 弹跳 2. flash 闪烁 3. pulse 放大,缩小 4. rubberBand 放 ...

  3. Region在connection前后进行“交并差”等操作的异同

    connection直译为“连接”.其实它的功能不是连接,它的功能是确定区域之间的连接关系,如果简单粗暴地解释的话,可以认为:connection的意思是“打散”,将不连接的区域打散成一个一个的区域. ...

  4. Python爬虫利器一之Requests库的用法

    前言 之前我们用了 urllib 库,这个作为入门的工具还是不错的,对了解一些爬虫的基本理念,掌握爬虫爬取的流程有所帮助.入门之后,我们就需要学习一些更加高级的内容和工具来方便我们的爬取.那么这一节来 ...

  5. Java 设计模式系列(七)桥接模式

    Java 设计模式系列(七)桥接模式 桥接模式(Bridge)是一种结构型设计模式.Bridge 模式基于类的最小设计原则,通过使用封装.聚合及继承等行为让不同的类承担不同的职责.它的主要特点是把抽象 ...

  6. 跟微软保持适当距离--Hessian + .net 实现RPC体系的企业应用

    同在一个产业链园区的XX厂因为5台Window2003服务器收到了律师函并且被迫下了12万$的采购单,虽然100万对XXX厂来数不是大数目,但是总有种被打劫的感觉. 在企业ERP应用中服务层一般都是做 ...

  7. delphi跨平台SOCKET--System.Net.Socket

    delphi跨平台SOCKET--System.Net.Socket 不知始于DELPHI哪一个版本,姑且始于柏林版吧. 基于此单元的TSocket类,大家可以很方便地封装出自己的服务端和客户端的SO ...

  8. [LeetCode 题解]: Partition List

    Given a linked list and a value x, partition it such that all nodes less than x come before nodes gr ...

  9. Ubuntu 16.04 无人值守自动更新

    https://help.ubuntu.com/lts/serverguide/automatic-updates.html 设置说明 APT::Periodic::Update-Package-Li ...

  10. Linux Guard Service - 杀死守护进程

    杀死某个子进程 杀死守护进程的子进程后,改进程会变为僵尸进程 14087 ? Ss 0:00 ./test4-1 14088 ? S 0:00 \_ ./test4-1 14089 ? S 0:00 ...