基本概念

  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. opencv 无法使用 dll 动态链接库 UnsatisfiedLinkError java.library.path Can't find dependent libraries

    System.loadLibrary(Core.NATIVE_LIBRARY_NAME) 使用如上方法加载本地 dll文件. 一般会出现两种错误: 1. UnsatisfiedLinkError ja ...

  2. 使用echo $? 查看命令是否执行成功

    shell中的特殊变量:变量名含义$0shell或shell脚本的名字$*以一对双引号给出参数列表$@将各个参数分别加双引号返回$#参数的个数$_代表上一个命令的最后一个参数$$代表所在命令的PID$ ...

  3. 在linux环境下编译android so库

    (1) 配置Android NDK环境 (2) mk文件编写 LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) # OpenCV OPENCV_CA ...

  4. 第三百九十五节,Django+Xadmin打造上线标准的在线教育平台—Xadmin集成富文本框

    第三百九十五节,Django+Xadmin打造上线标准的在线教育平台—Xadmin集成富文本框 首先安装DjangoUeditor3模块 Ueditor HTML编辑器是百度开源的HTML编辑器 下载 ...

  5. 面试Spring之bean的生命周期

    找工作的时候有些人会被问道Spring中Bean的生命周期,其实也就是考察一下对Spring是否熟悉,工作中很少用到其中的内容,那我们简单看一下. 在说明前可以思考一下Servlet的生命周期:实例化 ...

  6. Excel文档间的数据替换 ---电脑版APP 自动操作魔法师

    http://www.won-soft.com/macro/solution/excel-data-replace.htm 介绍: 在我们的日常工作中, 可能经常需要使用同各种数据表格打交道.比如财务 ...

  7. IE11不能使用F12功能DOM资源管理器无法使用

    https://www.ludou.org/win7-ie-11-f12-bug.html 32位win7下载补丁:http://www.microsoft.com/zh-CN/download/de ...

  8. duilib进阶教程 -- TreeView控件的bug (9)

    一.不自动调整子控件的宽度(TreeView宽度小于260时) 相信亲们用同样的代码,显示效果肯定和Alberl不一样吧~O(∩_∩)O~ 嘿嘿,仔细对比下,看看你们的列表头背景图片是下面这样的么? ...

  9. Oracle数据库入门——基础知识

    1.安装完成Oracle数据库后,使用sqlplus客户端登录数据库管理系统,只输入用户名,没有输入密码时,会提示口令为空,登录被拒绝. 请输入用户名:system 输入口令: ERROR:ORA-0 ...

  10. 7.16顺便贴一下 pep8的标准

    PEP8 Python 编码规范 一 代码编排 1 缩进.4个空格的缩进(编辑器都可以完成此功能),不使用Tap,更不能混合使用Tap和空格. 2 每行最大长度79,换行可以使用反斜杠,最好使用圆括号 ...