本文主要介绍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. 015年传智播客JavaEE 第168期就业班视频教程15-模块规范化

    注册功能最起码得有个用户名和密码吧. bigint相当于Java里面的Long.Long型最大的那个数字是19位,我们这里是20位,绝对够用. userName长度预留20%,让它后期可扩展.6-12 ...

  2. 11-SSH综合案例:前台用户模块:激活邮件的发送

    刚才已经把服务器的环境和客户端的软件已经搭建好了,现在就要发送邮件了.现在发送邮件的代码你不用重点去掌握啊,了解一下就行了. javax.activation javax.mail是Java EE 5 ...

  3. react-navigation 3.x版本的push、navigate、goback、pop、dispatch等常用方法

    一.方法简介 1. 应用中的每个页面组件都会自动提供 this.props.navigation this.props.navigation可以获取的一些方法: navigate - 转到另一个页面, ...

  4. SuSE 网卡配置模板

    heidsoft:/etc/sysconfig/network # cat ifcfg.template ## This is a template for a network interface c ...

  5. 7-linux-Centos7安装python3并与python2共存

    转载自:https://www.cnblogs.com/JahanGu/p/7452527.html linux-Centos7安装python3并与python2共存   1.查看是否已经安装Pyt ...

  6. ROS launch启动文件的理解与编写

    博客参考:https://blog.csdn.net/weixin_41995979/article/details/81784987 和 https://www.cnblogs.com/zjiaxi ...

  7. TLB与内存寻址,内存读取,虚拟内存的相关原理

    TLB(Translation Lookaside Buffer)转换检测缓冲区是一个内存管理单元,用于改进虚拟地址到物理地址转换速度的缓存. TLB是一个小的,虚拟寻址的缓存,其中每一行都保存着一个 ...

  8. Luogu 4449 于神之怒加强版

    挺套路的题,然而一开始还是想错了…… $\sum_{i = 1}^{n}\sum_{j = 1}^{m}gcd(i, j) ^ {k} = \sum_{T = 1}^{min(n, m)}\left ...

  9. [IIS] 测试的产品登陆之后有个引用外部站点js的请求半天都无法返回,导致网页一直在打转,Selenium的driver也无法对页面进行下一步的操作

    测试的产品登陆之后有个引用外部站点js的请求半天都无法返回: https://cdn.heapanalytics.com/js/heap-3497400264.js 这个js如果是在美国的机器上就可以 ...

  10. thinkphp 调用wsdl接口实例化SoapClient抛出异常

    异常:Message:SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://*****?wsdl' : failed to load externa ...