一、从 Servlet 说起

   在Java中,Servlet 技术用来创建Web应用程序,本质上来讲,Servlet是运行在服务器端的Java程序,接收客户端发起的HTTP请求并动态的生成相响应内容,响应内容可以是纯文本,html,xml,excel,json等。

   Servlet 主要执行以下任务:

1、读取客户端(浏览器)发送的显式的数据。如网页上的 HTML 表单。

2、读取客户端(浏览器)发送的隐式的 HTTP 请求数据。这包括 cookies、媒体类型和浏览器能理解的压缩格式等等。浏览器发送请求时,除了html中的显式信息之外,还有一些不能直观看到的信息,称为请求头信息,这些信息和浏览器有关,包括cookies、媒体类型和浏览器能理解的压缩格式等,在HttpServletRequest对象中有相应的方法可以获取这些信息。

HttpServletRequest 读取后如何重新设置数据_java web

3、处理数据并生成结果。这个过程可能需要访问数据库等。

4、发送显式的数据(即文档)到客户端(浏览器)。该文档的格式可以是多种多样的,包括文本文件(HTML或XML)、二进制文件(GIF 图像)、Excel 等。

5、发送隐式的 HTTP 响应到客户端(浏览器)。和请求头信息相对应的响应头信息,这包括告诉浏览器或其他客户端被返回的文档类型(例如 HTML),设置cookies 和缓存参数,以及其他类似的任务。

HttpServletRequest 读取后如何重新设置数据_java web_02

   为了让 Servlet 运行起来,需要将其部署在Servlet容器中,Servlet容器是Web服务器和Servlet进行通讯的主要构件,它的主要职责包括:

  • 管理Servlet程序的生命周期
  • 将URL映射到指定的Servlet进行处理
  • 与Servlet程序合作处理HTTP请求——根据HTTP请求生成HttpServletResponse对象并传递给Servlet进行处理,将Servlet中的HttpServletResponse对象生成的内容返回给浏览器
  • 并发请求的多线程处理、线程池管理
  • Session管理,HTTP缓存等

doGet(),doPost()等)


   Servlet的生命周期:

HttpServletRequest 读取后如何重新设置数据_客户端_03

   Servlet与前端的数据传输可以通过Request和Response,代码大约长这样:

HttpServletRequest 读取后如何重新设置数据_客户端_04

   至于前端某个页面如何知道要哪个Servlet来处理,则需要在新建Servlet类之后在web.xml中进行配置,前端相应的action中要写web.xml中对应的名称即可。web.xml文件在后面会有详细解释。


二、然后来看看JSP


   学习了前端技术——HTML/CSS/JavaScript后,我们有能力构建一个漂亮的博客页面,但它是静态的,如果需要添加新的内容,需要修改相应的前端文件代码。掌握了编写Servlet程序后,我们有能力让网页“动”起来——根据不同的输入(URL参数、Session等)生成不同的页面内容。但是Servlet也有自己的缺陷,在Java源文件中维护大量的HTML代码是及其困难的,比如博客页面的源代码,近百行的HTML代码,混杂着各种各样的标签。大量的HTML代码混杂在Java源文件中,同时如果页面动态内容非常多的话,就会有很多字符串拼接操作。这样的代码是及其不利于阅读与维护的,Servlet中的doGet()方法里难道得把这个字符串(页面的HTML内容)给拼接起来? 所以在实际的Web应用开发中肯定不会采用这种方法。

   然后就有了JSP,JSP可以在html中插入java代码段,是简化的servlet设计,在服务器端执行,返回给客户端html文件,所以客户端只要有浏览器就可以浏览。JSP的基本语法这里就不介绍了。


三、接着把Servlet和JSP结合起来

  我们已经学习了两种Java服务器端技术——JSP和Servlet,比较二者的不同:

  • Servlet在Java代码中通过HttpServletResponse对象动态输出HTML内容
  • JSP在静态HTML内容中嵌入Java代码,Java代码被动态执行后生成HTML内容

  两种技术有着不同的特点,在不同的场景下有着各自的优势:

  • Servlet能够很好地组织业务逻辑代码,但是在Java源文件中通过字符串拼接的方式生成动态HTML内容会导致代码维护困难、可读性差
  • JSP虽然规避了Servlet在生成HTML内容方面的劣势,但是在HTML中混入大量、复杂的业务逻辑同样也是不可取的


  于是使用MVC模式将二者结合:


1、Web浏览器发送HTTP请求到服务端,被Controller(Servlet)获取并进行处理(例如参数解析、请求转发)

2、Controller(Servlet)调用核心业务逻辑——Model部分,获得结果

3、Controller(Servlet)将逻辑处理结果交给View(JSP),动态输出HTML内容

4、动态生成的HTML内容返回到浏览器显示

  MVC模式在Web开发中的好处是非常明显,它规避了JSP与Servlet各自的短板,Servlet只负责业务逻辑而不需要动态生成HTML代码;JSP中也不会充斥着大量的Java业务代码。这大大提高了代码的可读性和可维护性。



四、最后谈谈Filter,Cookie和Session


  Cookie和Session一起说

  Web应用程序是使用HTTP协议传输数据的。HTTP协议是无状态的协议,一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。这就意味着服务器无法从连接上跟踪会话。即用户A购买了一件商品放入购物车内,当再次购买商品时服务器已经无法判断该购买行为是属于用户A的会话还是用户B的会话了。所以要跟踪该会话,必须引入一种机制。


常用的会话跟踪技术是Cookie与Session。Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。


     需要注意的一点是cookie需要浏览器的支持,session也需要浏览器的支持来传递sessionID,当浏览器不支持cookie时session机制也可以通过重写URL和SSL(?)的方式实现。


     然后是Filter


过滤器的概念:

     Java中的Filter并不是一个标准的Servlet,它不能处理用户请求,也不能对客户端生成响应。主要用于对HttpServletRequest进行预处理,也可以对HttpServletResponse进行后处理,是个典型的处理链。过滤链的好处是,执行过程中任何时候都可以打断,只要不执行chain.doFilter()就不会再执行后面的过滤器请求和请求的内容,在实际的应用过程中,要特别注意过滤链的执行顺序问题。


     过滤器的作用描述:

1、在HttpServletRequest 到达Servlet 之前,拦截客户的HttpServletRequest。

2、根据需要检查HttpServletRequest ,也可以修改HttpServletRequest 头和数据。

3、在HttpServletResponse 到达客户端之前,拦截HttpServletResponse 。

4、根据需要检查HttpServletResponse ,可以修改HttpServletResponse 头和数据。

  • 过滤器接口:


附:web.xml配置

       首先是web.xml的加载顺序:

WEB项目时,容器包括(JBoss、Tomcat等)首先会读取项目web.xml配置文件里的配置,当这一步骤没有出错并且完成之后,项目才能正常地被启动起来。

HttpServletRequest 读取后如何重新设置数据_xml_05

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
  <display-name> </display-name>	
  <welcome-file-list>
    <welcome-file>/views/main/adminlogin.jsp</welcome-file>
  </welcome-file-list>
 
	<filter>
		<filter-name>OpenSessionInViewFilter</filter-name>
		<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
		    <init-param>
            <param-name>sessionFactoryBeanName</param-name>
            <param-value>sessionFactory</param-value>
        </init-param>
        <init-param>
            <param-name>singleSession</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>flushMode</param-name>
            <param-value>AUTO</param-value>
        </init-param>
	</filter>

	<filter-mapping>
		<filter-name>OpenSessionInViewFilter</filter-name>
		<url-pattern>*.action</url-pattern>
	</filter-mapping>
    
  <context-param>
  	<param-name>contextConfigLocation</param-name>
	  <param-value>WEB-INF/applicationContext.xml</param-value>
  </context-param> 


  <listener>
  	<listener-class>
  		org.springframework.web.context.ContextLoaderListener
  	</listener-class>
  </listener>


  <context-param>
	  <param-name>log4jConfigLocation</param-name>
	  <param-value>WEB-INF/log4j.properties</param-value>
  </context-param>

  <listener>
	<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
  </listener>


  <error-page>
    error-code>500</error-code>
		<location>/views/main/error.jsp</location>
  </error-page> 

  <error-page>
    <error-code>404</error-code>
		<location>/views/main/404.jsp</location>
  </error-page>

</web-app>



参考:

https://course.tianmaying.com/servlet-and-jsp+start#0

http://study.163.com/course/courseMain.htm?courseId=648001

前面两个可忽略,看最后一个就好

http://www.ibm.com/developerworks/cn/java/j-lo-servlet/