基本概念

  Servlet又称为Java Servlet是一个基于java技术的web组件,运行在服务器端,用于生成动态的内容。Servlet是平台独立的java类,编写一个Servlet实际上就是按照Servlet规范编写的java类。

  Servlet运行需要一个运行环境,及需要一个Servlet容器,这里我们以tomcat为例,tomcat作为一个web服务器,具有处理HTML页面的功能,另外它还是一个Servlet和jsp容器。

实现方式

  第一种:实现servlet接口,需要实现接口中定义的5个方法

package day_052102;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/*
这里通过实现Servlet接口来编写一个简单的Servlet
*/
public class ServletDemo implements Servlet
{
public void init(ServletConfig config) throws ServletException
{
}
public ServletConfig getServletConfig()
{ return null;
}
public String getServletInfo()
{
return null;
}
public void destroy()
{
}
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException
{
PrintWriter out=res.getWriter();
out.print("hello World!");
out.close();
}
}

  第二种:继承抽象类GenericServlet,该类定义了一个通用的Servlet

public abstract class GenericServlet implements Servlet, ServletConfig, java.io.Serializable
public class GenericServletDemo extends GenericServlet
{ @Override
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException
{
PrintWriter out=res.getWriter();
out.println("hello World!");
out.close(); } }

  第三种:通过继承抽象的HttpServlet类,此类继承于GenericServlet类

HttpServlet中service方法的实现代码:
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
String method = req.getMethod();
if (method.equals(METHOD_GET)) //当请求方式为GET时,调用doGet方法
{
long lastModified = getLastModified(req);
if (lastModified == -1)
{
// servlet doesn't support if-modified-since, no reason
// to go through further expensive logic
doGet(req, resp);
}
else
{
long ifModifiedSince;
try
{
ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
}
catch (IllegalArgumentException iae)
{
// Invalid date header - proceed as if none was set
ifModifiedSince = -1;
}
if (ifModifiedSince < (lastModified / 1000 * 1000))
{
// If the servlet mod time is later, call doGet()
// Round down to the nearest second for a proper compare
// A ifModifiedSince of -1 will always be less
maybeSetLastModified(resp, lastModified);
doGet(req, resp);
}
else
{
resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
}
}
}

如果想在自己的类中重写service方法,那么servlet容器就会把请求交给我们自己重写的service方法处理

protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
String method = req.getMethod();
if (method.equals(METHOD_GET)) //当请求方式为GET时,调用doGet方法
{
long lastModified = getLastModified(req);
if (lastModified == -1)
{
// servlet doesn't support if-modified-since, no reason
// to go through further expensive logic
doGet(req, resp);
}
else
{
long ifModifiedSince;
try
{
ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
}
catch (IllegalArgumentException iae)
{
// Invalid date header - proceed as if none was set
ifModifiedSince = -1;
}
if (ifModifiedSince < (lastModified / 1000 * 1000))
{
// If the servlet mod time is later, call doGet()
// Round down to the nearest second for a proper compare
// A ifModifiedSince of -1 will always be less
maybeSetLastModified(resp, lastModified);
doGet(req, resp);
}
else
{
resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
}
}
}

在web中的应用

  首先java类的实现代码和“实现方式”中的代码类似,不再累述。

  除此之外,还需要在web.xml中配置响应的servlet标签,分为两部分:

<servlet>
<servlet-name>ServletDemo</servlet-name>
<servlet-class>day_052102.ServletDemo</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletDemo</servlet-name>
<url-pattern>/ServletDemo</url-pattern>
</servlet-mapping>

数据填充

  请求被某个servlet处理后,返回的是处理后的结果数据,不会调到我们指定的页面,需要在我们自己写的servlet的方法中通过内部重定向(forward)和跳转(redirect)调到相应的页面。那如何将数据返回到页面呢?

  1.利用ServletContext这个web全局上下文来共享数据 

  servlet中getServletContext()可以获得一个ServletContext对象,利用这个对象的getAttribute()/setAttribute()方法可以在整个WEB应该里共享数据,可以实现servlet和jsp之间的数据互传
  比如:在servlet中getServletContext.setAttribute("title", "hello world");在servlet上下文中以“hello”为键,保存了“hello world”这一个字符串,如果要在jsp中调用,则用如下jsp脚本
  <%=application.getAttribute("hello")%>
 2、利用session在同一个会话共享数据
  利用HttpSession共享同一个会话的数据。这也要用到session的getAttribute()/setAttribute()方法,和ServletContext()的使用差不多的
 3.利用request共享一次请求的数据
    一次请求当中,可以利用request的getAttribute()/setAttribute()方法在servlet和jsp页面间共享数据。
 4.以字节流或字符流输出返回值

    返回json字符串形式…

 PrintWriter out = response.getWriter();
//或:ServletOutputStream out = response.getOutputStream();
//但两个不要一起用!
out.write("[{\"id\":1,\"name\":default}]");
out.flush();
out.close();

PrintWriter与ServletOutputStream的区别如下: 
1. PrintWriter是以字符为单位,对所有的信息进行处理,而ServletOutputStream仅对二进制的资料进行处理。 
2. PrintWriter在输出字符文本时内部需要将字符串转换成某种字符集编码的字节数组,使用他的好处就是不需要自己来完成从字符串到字节数组的转换。 转换的字符集编码是通过设置setContentTpye或setCharacterEncoding或setLocale等方法实现的;使用ServletOutputStream对象直接从一个字节输入流中读取出来,然后再原封不动的输出到客服端。 
3. 这两个方法相互排斥,只能调用其一,如果要用,则要在换方法之前调用flush(),将缓冲区数据冲掉。

  5.ObjectMapper写返回值
   // 输出信息
PrintWriter out = response.getWriter();
Object result = new Object();
// jackson核心对象
ObjectMapper objectMap = new ObjectMapper();
objectMap.writeValue(out, result );
相关jar包:
jackson-core-2.2.3.jar 
jackson-annotations-2.2.3.jar 
jackson-databind-2.2.3.jar

匹配原则

   1.精确匹配

    比如servletA 的url-pattern为 /test,servletB的url-pattern为 /* ,这个时候,如果我访问的url为http://localhost/test ,这个时候容器就会先 进行精确路径匹配,发现/test正好被servletA精确匹配,那么就去调用servletA,也不会去理会其他的servlet了。

  2.最长路径匹配

    例子:servletA的url-pattern为/test/*,而servletB的url-pattern为/test/a/*,此时访问http://localhost/test/a时,容器会选择路径最长的servlet来匹配,也就是这里的servletB。

  3.扩展名匹配

    如果url最后一段包含扩展,容器将会根据扩展选择合适的servlet。例子:servletA的url-pattern:*.action。其实扩展名匹配我们可以理解成就是后缀匹配。

  4.默认匹配

    如果通过上述三种匹配规则都不能找到servlet,如果我们定义了default servlet,则容器将会把请求丢给这个默认的servlet,否则会报错

 内部重定向(转发)(forward)和跳转(重定向)(redirect)区别

  1.forward是服务器内部重定向,也就是转发的方法必须是同一个web应用中,在服务器内部直接重新定向到另一个方法中,客户端并不知道;redirect则是服务器收到请求后发送一个状态头给客户端,客户端将再请求一次,这里多了两次网络通信的来往,除了可以在同一个应用内,也可以请求到其他服务器上的资源,属于页面级别的重定向

   2.forward转发中request数据是共享的,redirect是不能共享request数据的

   3.就效率而言,forward效率高,redirect效率低,因为redirect多了一次对浏览器的请求和响应操作

注意事项

  1.web.xml中一个servlet可以对应多个servlet-mapping

  2.web.xmlservlet标签必须写在对应的servlet-mapping之前(这个不太确定)

Servlet基本介绍和使用的更多相关文章

  1. servlet简单介绍

    什么是Servlet? servlet是一种Java编程语言类,用于扩展托管通过请求 - 响应编程模型访问的应用程序的服务器的功能.尽管servlet可以响应任何类型的请求,但它们通常用于扩展Web服 ...

  2. Servlet过滤器介绍之原理分析

    zhangjunhd 的BLOG     写留言去学院学习发消息 加友情链接进家园 加好友 博客统计信息 51CTO博客之星 用户名:zhangjunhd 文章数:110 评论数:858 访问量:19 ...

  3. Introducation of Servlet filter(servlet过滤器介绍 )

    本文章向大家介绍Servlet Filter,主要包括 Servlet Filter使用实例.应用技巧.基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下. 过滤器是一个可以转换 ...

  4. Servlet 使用介绍(2)

    说明 本篇由于介绍Servlet容器回传请求方法service(ServletRequest req, ServletResponse res);传入参数用户请求参数request和请求返回参数res ...

  5. Servlet 使用介绍(1)

    说明 本篇介绍java web中比较重要的一个技术:servlet.servlet是一种对用户请求动态响应的一个技术,是java web的核心一环.对于一般服务性质的纯后台服务应用而言,或许整个应用是 ...

  6. 10.Servlet简单介绍

    1.什么是Servlet * Servlet是javaweb的三大组件之一,它属于动态资源.Servlet的作用是处理请求,服务器会把接收到的请求交给Servlet来处理,在Servlet种通常需要: ...

  7. J2EE的13个规范之(三) Servlet简单介绍

    Servlet是一种server端脚本,它是一个特殊的Java类,继承自HttpServlet.开发中主要用于处理和响应client的请求. Servlet在容器中执行,事实上例的和销毁创建由容器进行 ...

  8. Servlet 简单介绍

    来源于菜鸟教程http://www.runoob.com/servlet/servlet-intro.html Servlet 简介 Servlet 是什么? Servlet(Server Apple ...

  9. 一、动态网络编程的概念 二、Tomcat服务器搭建 三、Servlet组件介绍

    一.动态网络编程的概念 动态网页:结合了HTML以外的高级程序编程语言和数据库技术生成的页面. 动态网页编程技术: ASP,PHP,JSP HTTP协议:规范浏览器和服务器之间通信的数据格式. 浏览器 ...

随机推荐

  1. Java中内存溢出与内存泄露

    内存溢出 内存溢出(out of memory),是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory:比如申请了一个integer,但给他存了long才能存下的数,就会发 ...

  2. Linux查找指令(阮一峰)

    1. find find是最常见和最强大的查找命令,你可以用它找到任何你想找的文件. find的使用格式如下: $ find <指定目录> <指定条件> <指定动作> ...

  3. linux php命令安装

    1.添加php命令,在etc/profile文件下增加 if [ "$HISTCONTROL" = "ignorespace" ] ; then export ...

  4. Git错误:error: The following untracked working tree files would be overwritten by merge:

    [andy@localhost weixin_robot]$ git pull Updating d652d1c..fa05549 error: The following untracked wor ...

  5. Mac 环境 Vue 开发 CPU 占用率高 问题

    Mac开发Vue应用时,发现CPU风扇转的老高. htop查看一下: 问题找到了,就是这个dev-server.js,node起的进程. 然后就是 dtruss -p 1230(进程ID) 命名跟踪一 ...

  6. 关于Kafka Fetch Session的讨论

    Kafka在1.1.0版本引入了fetch session的概念,旨在降低“无效”FETCH请求对集群带宽资源的占用.故事的背景是这样的: 众所周知,Kafka的broker和consumer都会定期 ...

  7. Puppet报错汇总

    报错1: 解决:该报错是由于Puppet agent 的时间和Puppet master的时间不一致导致,可以使用ntp同步一下时间即可解决 报错2: 启动mcollective的时候报错 解决:ge ...

  8. Convert PLY to VTK Using PCL 1.6.0 or PCL 1.8.0 使用PCL库将PLY格式转为VTK格式

    PLY格式是比较流行的保存点云Point Cloud的格式,可以用MeshLab等软件打开,而VTK是医学图像处理中比较常用的格式,可以使用VTK库和ITK库进行更加复杂的运算处理.我们可以使用Par ...

  9. easyui---layout实战

    第一步: <div id="cc" class="easyui-layout" fit=true> <div region="nor ...

  10. 洛谷P1605 迷宫【dfs】

    题目背景 迷宫 [问题描述] 给定一个N*M方格的迷宫,迷宫里有T处障碍,障碍处不可通过.给定起点坐标和 终点坐标,问: 每个方格最多经过1次,有多少种从起点坐标到终点坐标的方案.在迷宫 中移动有上下 ...