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>
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 文档 熟知每个类和接口的具体意思。特别是下面几个接口必须熟知每个方法的意思和用途:
HttpServletServetConfigServletContextFilterFilterConfigFilterChainRequestDispatcherHttpServletRequestHttpServletResponseHttpSession
为什么我这么强调 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