Servlet、Filter 项目示例

  如果初学 Java Web 开发,请远离各种开发框架,应该从Servlet 开发,学习java web应用最本质的内容。

  Servlet 是 Java Web 技术的核心基础,掌握 Servlet 的工作原理是成为一名合格的 Java Web 技术开发人员的基本要求。
   
  Servlet和Servlet容器的关系像子弹和抢的关系,彼此依存,但又独立发展,它们通过标准化接口相互协作。选择一个你喜爱的Servlet容器,或者说大一点就是应用服务器,推荐 Tomcat 、Resin 或者 Jetty 这些轻量级的产品。这三个产品下载 zip 包解压后就可以用了。不建议使用.exe格式的安装版本。
 
1 在Eclipse中新建一个普通的java项目
  创建文件夹:webapp、webapp/WEB-INF
  创建文件:webapp/WEB-INF/web.xml
  设置.class文件的输出路径为 :TestWebpp/webapp/WEB-INF/classes
目录结构如图:
 
   一个最基本的 Java Web 项目所需的 jar 包只需要一个 servlet-api.jar ,这个 jar 包中的类大部分都是接口,还有一些工具类,共有 2 个包,分别是 javax.servlet 和 javax.servlet.http。我们把这个jar包放到了 webapp 目录外的一个独立 packages 文件夹里,这是因为所有的 Servlet 容器都带有这个包,你无需再放到Web项目里,我们放到这里只不过是编译的需要,运行是不需要的。如果你硬是把 servlet-api.jar 放到 webapp/WEB-INF/lib 目录下,那么 Tomcat 启动时还会报一个警告信息。
 
     Java Web 项目还需要一个非常重要的配置文件 web.xml ,在这个项目中已经被我最小化了,只保留有用的信息:
<?xml version="1.0" encoding= "UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
      <filter >
             <filter-name >helloFilter </filter-name >
             <filter-class >edu.shao.webapp.sample.HelloFilter </filter-class >
      </filter >
      <filter-mapping >
             <filter-name >helloFilter </filter-name >
             <url-pattern >/* </url-pattern >
      </filter-mapping >
      
      <servlet >
             <servlet-name >hello_world </servlet-name >
             <servlet-class >edu.shao.webapp.sample.HelloServlet </servlet-class >
             <load-on-startup >1 </load-on-startup >
      </servlet >
      <servlet-mapping >
             <servlet-name >hello_world </servlet-name >
             <url-pattern >/hello </url-pattern >
             <!--Map e.g. http://localhost:8080/test/hello -->
      </servlet-mapping >
</web-app>
 
2 编写Servlet 和 Filter  
  每个 servlet 都必须在 web.xml 中定义并进行 URL 映射配置,早期 Java 开发 Web 在没有框架满天飞的时候,这个文件会定义了大量的 servlet,或者有人为了省事干脆来一个 /servlet/* 来通过类名直接调用 Servlet。
  Servlet是一种服务器端的Java应用程序,具有独立于平台和协议的特性,用于响应客户请求(Web浏览器或其他HTTP客户程序),采用请求-响应模式提供Web服务。 Servlet是位于Web 服务器内部的服务器端的Java 应用程序,与传统的从命令行启动的Java应用程序不同,Servlet由Web服务器(Servlet 容器)进行加载.
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HelloServlet extends HttpServlet {
      @Override
      public void doGet(HttpServletRequest req, HttpServletResponse resp)
                   throws ServletException, IOException {
            resp.getWriter().print( "Hello World");
      }
}
  Servlet 规范里还有另外一个非常重要而且非常有用的接口那就是 Filter 过滤器。
  Filter使用户可以改变一 个request或修改一个response。 Filter 不是一个servlet,它不能产生一个response,但是他能够在一个request到达servlet之前预先处理request,也可以在一个响应离开 servlet时处理response。
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

public class HelloFilter implements Filter {

      @Override
      public void init(FilterConfig arg0) throws ServletException {
            System. out.println( "Filter init...");
      }
      @Override
      public void doFilter(ServletRequest req, ServletResponse res,
                  FilterChain chain) throws IOException, ServletException {
            HttpServletRequest request = (HttpServletRequest)req;
            System. out.println( "拦截 URI="+request.getRequestURI());
            chain.doFilter(req, res);
      }
      @Override
      public void destroy() {
            System. out.println( "Filter destroy..");
      }
}
3 部署运行
  然后将下面 XML 内容替换 Tomcat 下的 conf/server.xml 文件:
<?xml version='1.0' encoding='utf-8'?>
<Server port="8005" shutdown="SHUTDOWN">
  <Service name="Catalina">
    <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8"/>
    <Engine name="Catalina" defaultHost="localhost">
      <Host name="localhost">
          <Context path="test" docBase="E:\Workspace\TestWebpp\webapp" reloadable="true"/>
      </Host>
    </Engine>
  </Service>
</Server>
  启动tomcat即可。
  在浏览器中输入:http://localhost:8080/test/,打开index.html页面
  输入:http://localhost:8080/test/hello,由HelloServlet响应,网页显示“Hello World”
  观察HelloFilter 在 tomcat的控制台中的输出。
  
4 Servlet 和 HTTP 的对应关系
   Servlet 是 J2EE 最重要的一部分,有了 Servlet 你就是 J2EE 了,J2EE 的其他方面的内容择需采用。而 Servlet 规范你需要掌握的就是 servlet 和 filter 这两项技术。绝大多数框架不是基于 servlet 就是基于 filter,如果它要在 Servlet 容器上运行,就永远也脱离不开这个模型。
     为什么 Servlet 规范会有两个包,javax.servlet 和 javax.servlet.http ,早先设计该规范的人认为 Servlet 是一种服务模型,不一定是依赖某种网络协议之上,因此就抽象出了一个 javax.servlet ,同时再提供一个基于 HTTP 协议上的接口扩展。但是从实际运行这么多年来看,似乎没有发现有在其他协议上实现的 Servlet 技术。
 
     javax.servlet 和 javax.servlet.http 这两个包总共加起来也不过是三十四个接口和类。你需要通过 J2EE 的 JavaDoc 文档 熟知每个类和接口的具体意思。特别是下面几个接口必须熟知每个方法的意思和用途:
HttpServlet
ServetConfig
ServletContext
Filter
FilterConfig
FilterChain
RequestDispatcher
HttpServletRequest
HttpServletResponse
HttpSession
     为什么我这么强调 HttpServletRequest 和 HttpServletResponse 这两个接口,因为 Web 开发是离不开 HTTP 协议的,而 Servlet 规范其实就是对 HTTP 协议做面向对象的封装,HTTP协议中的请求和响应就是对应了 HttpServletRequest 和 HttpServletResponse 这两个接口。
     你可以通过 HttpServletRequest 来获取所有请求相关的信息,包括 URI、Cookie、Header、请求参数等等,别无它路。因此当你使用某个框架时,你想获取HTTP请求的相关信息,只要拿到 HttpServletRequest 实例即可。而 HttpServletResponse接口是用来生产 HTTP 回应,包含 Cookie、Header 以及回应的内容等等
 
5 关于 JSP
     任何一个 JSP 页面在执行的时候都会编译成一个 Servlet 类文件,如果是 Tomcat 的话,这些生成的 java 文件会放置在 {TOMCAT}/work 目录下对应项目的子目录中。
     在 servlet 中有一个包 javax.servlet.jsp(jsp-api.jar) 是跟 JSP 相关的一些接口规范定义。JSP 比 Servlet 方便的地方在于可直接修改立即生效,不像 Servlet 修改后必须重启容器才能生效。
     因此 JSP 适合用来做视图,而 Servlet 则适合做控制层。
 
 
  参考:http://www.oschina.net/question/12_52027
原文地址:https://www.cnblogs.com/windlaughing/p/2983947.html