基本概念

  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. 【6集iCore3_ADP触摸屏驱动讲解视频】6-4 底层驱动之SDRAM读写(上)

    源视频包下载地址: 链接:http://pan.baidu.com/s/1i5lzzj3 密码:bwoe   银杏科技优酷视频发布区: http://i.youku.com/gingko8  

  2. Loadrunner C/S关联函数(LSP)AND(LSSS)使用-案例

    LSP就是lrs_save_param()函数 LSSS就是lrs_save_searched_string()函数 一下我们用一个例子去说明他们的使用. C/S机制和B/S不一样,特别是有一个dat ...

  3. 在linux下用命令行编译 java的eclipse项目

    由于jdk的版本问题导致在windows上编译打包好的jar包放在linux服务器上运行的时候出现一点小异常,所以决定在linux上进行一次项目编译,这有两个选择1.在相同的linux环境下安装lin ...

  4. (转载)Redis5.0重量级特性Stream尝鲜

    转 导读:Redis5.0最新重点推出了Stream的支持,给众多架构师在消息队列方面带来了新的选择,特别是Redis粉丝们绝对是一个福音.那么Redis的Stream有哪些特别的功能?跟kafka有 ...

  5. 【Mac brew】代理安装brew insall

    http_proxy=dev-proxy.**.**:8080 https_proxy=dev-proxy.**.**:8080  brew install npm

  6. [Bayes] runif: Inversion Sampling

    runifum Inversion Sampling 看样子就是个路人甲. Ref: [Bayes] Hist & line: Reject Sampling and Importance S ...

  7. 【ArcGIS】栅格分析-问题之001(转)

    在arcgis中进行栅格计算时,碰到这样的错误ERROR 000539:Error running expression:rcexec()<type 'exceptions.ValueError ...

  8. 跨服务器做yum源

    服务器无法上网,然后自己根据光盘搭建的YUM源不够用.RPM安装软件,各种依赖,找包烦死. 先做个 能上外网的 http proxy 找一个可以上Internet的服务器,然后起一个squid服务, ...

  9. 不用軟體解PPT密碼

    解PPT密碼的軟體很多,最好用的是advanced office password recovery pro,論壇裡有,不多說了~ 但是軟體有時候在解PPT密碼時多顯無力,現介紹不用軟體就能解pptx ...

  10. 适用于CentOS6.4的Win7双系统安装方式

    (文章在2013-11-16 15:56:31修改,此次修改幅度较大,之前的安装方式有问题,已经不推荐使用.笔者在此对各位读者表示深深的歉意!) 在之前的文章中我们实现了Win7+CentOS6.3双 ...