⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 servlets8.html

📁 j2eePDF格式的电子书
💻 HTML
📖 第 1 页 / 共 2 页
字号:
<?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">  <head>    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />    <meta http-equiv="Content-Style-Type" content="text/css" />    <title>Filtering Requests and Responses</title>    <link rel="StyleSheet" href="document.css" type="text/css" media="all" />    <link rel="StyleSheet" href="catalog.css" type="text/css" media="all" />    <link rel="Table of Contents" href="J2EETutorialTOC.html" />    <link rel="Previous" href="Servlets7.html" />    <link rel="Next" href="Servlets9.html" />    <link rel="Index" href="J2EETutorialIX.html" />  </head>  <body>    <table width="550" summary="layout" id="SummaryNotReq1">      <tr>	<td align="left" valign="center">	<font size="-1">	<a href="http://java.sun.com/j2ee/1.4/download.html#tutorial" target="_blank">Download</a>	<br>	<a href="http://java.sun.com/j2ee/1.4/docs/tutorial/information/faq.html" target="_blank">FAQ</a>	<br>	<a href="http://java.sun.com/j2ee/1.4/docs/tutorial/information/history.html" target="_blank">History</a>	</td>        <td align="center" valign="center"><a accesskey="p" href="Servlets7.html"><img id="LongDescNotReq1" src="images/PrevArrow.gif" width="26" height="26" border="0" alt="Prev" /></a><a accesskey="c" href="J2EETutorialFront.html"><img id="LongDescNotReq1" src="images/UpArrow.gif" width="26" height="26" border="0" alt="Home" /></a><a accesskey="n" href="Servlets9.html"><img id="LongDescNotReq3" src="images/NextArrow.gif" width="26" height="26" border="0" alt="Next" /></a><a accesskey="i" href="J2EETutorialIX.html"></a>        </td>	<td align="right" valign="center">	<font size="-1">	<a href="http://java.sun.com/j2ee/1.4/docs/api/index.html" target="_blank">API</a>	<br>	<a href="http://java.sun.com/j2ee/1.4/docs/tutorial/information/search.html" target="_blank">Search</a>	<br>	<a href="http://java.sun.com/j2ee/1.4/docs/tutorial/information/sendusmail.html" target="_blank">Feedback</a></font>	</font>	</td>      </tr>    </table>    <img src="images/blueline.gif" width="550" height="8" ALIGN="BOTTOM" NATURALSIZEFLAG="3" ALT="Divider">    <blockquote><a name="wp64572"> </a><h2 class="pHeading1">Filtering Requests and Responses</h2><a name="wp64574"> </a><p class="pBody">A <em class="cEmphasis">filter</em> is an object that can transform the header and content (or both) of a request or response. Filters differ from Web components in that they usually do not themselves create a response. Instead, a filter provides functionality that can be &quot;attached&quot; to any kind of Web resource. As a consequence, a filter should not have any dependencies on a Web resource for which it is acting as a filter, so that it can be composable with more than one type of Web resource. The main tasks that a filter can perform are as follows:</p><div class="pSmartList1"><ul class="pSmartList1"><a name="wp64575"> </a><div class="pSmartList1"><li>Query the request and act accordingly.</li></div><a name="wp64576"> </a><div class="pSmartList1"><li>Block the request and response pair from passing any further.</li></div><a name="wp64577"> </a><div class="pSmartList1"><li>Modify the request headers and data. You do this by providing a customized version of the request.</li></div><a name="wp64578"> </a><div class="pSmartList1"><li>Modify the response headers and data. You do this by providing a customized version of the response.</li></div><a name="wp64579"> </a><div class="pSmartList1"><li>Interact with external resources.</li></div></ul></div><a name="wp64580"> </a><p class="pBody">Applications of filters include authentication, logging, image conversion, data compression, encryption, tokenizing streams, and XML transformations, and so on. </p><a name="wp64581"> </a><p class="pBody">You can configure a Web resource to be filtered by a chain of zero, one, or more filters in a specific order. This chain is specified when the Web application containing the component is deployed and is instantiated when a Web container loads the component.</p><a name="wp64582"> </a><p class="pBody">In summary, the tasks involved in using filters include</p><div class="pSmartList1"><ul class="pSmartList1"><a name="wp64583"> </a><div class="pSmartList1"><li>Programming the filter</li></div><a name="wp64584"> </a><div class="pSmartList1"><li>Programming customized requests and responses</li></div><a name="wp64585"> </a><div class="pSmartList1"><li>Specifying the filter chain for each Web resource</li></div></ul></div><a name="wp64586"> </a><h3 class="pHeading2">Programming Filters</h3><a name="wp64587"> </a><p class="pBody">The filtering API is defined by the <code class="cCode">Filter</code>, <code class="cCode">FilterChain</code>, and <code class="cCode">FilterConfig</code> interfaces in the <code class="cCode">javax.servlet</code> package. You define a filter by implementing the <code class="cCode"><a  href="http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/Filter.html" target="_blank">Filter</a></code> interface. The most important method in this interface is the <code class="cCode">doFilter</code> method, which is passed request, response, and filter chain objects. This method can perform the following actions:</p><div class="pSmartList1"><ul class="pSmartList1"><a name="wp64593"> </a><div class="pSmartList1"><li>Examine the request headers.</li></div><a name="wp64594"> </a><div class="pSmartList1"><li>Customize the request object if it wishes to modify request headers or data.</li></div><a name="wp64595"> </a><div class="pSmartList1"><li>Customize the response object if it wishes to modify response headers or data.</li></div><a name="wp64596"> </a><div class="pSmartList1"><li>Invoke the next entity in the filter chain. If the current filter is the last filter in the chain that ends with the target Web component or static resource, the next entity is the resource at the end of the chain; otherwise, it is the next filter that was configured in the WAR. It invokes the next entity by calling the <code class="cCode">doFilter</code> method on the chain object (passing in the request and response it was called with, or the wrapped versions it may have created). Alternatively, it can choose to block the request by not making the call to invoke the next entity. In the latter case, the filter is responsible for filling out the response.</li></div><a name="wp64597"> </a><div class="pSmartList1"><li>Examine response headers after it has invoked the next filter in the chain</li></div><a name="wp64598"> </a><div class="pSmartList1"><li>Throw an exception to indicate an error in processing</li></div></ul></div><a name="wp64600"> </a><p class="pBody">In addition to <code class="cCode">doFilter</code>, you must implement the <code class="cCode">init</code> and <code class="cCode">destroy</code> methods. The <code class="cCode">init</code> method is called by the container when the filter is instantiated. If you wish to pass initialization parameters to the filter, you retrieve them from the <code class="cCode">FilterConfig</code> object passed to <code class="cCode">init</code>. </p><a name="wp64602"> </a><p class="pBody">The Duke's Bookstore application uses the filters <code class="cCode"><a  href="../examples/web/bookstore1/src/filters/HitCounterFilter.java" target="_blank">HitCounterFilter</a></code> and <code class="cCode"><a  href="../examples/web/bookstore1/src/filters/OrderFilter.java" target="_blank">OrderFilter</a></code> to increment and log the value of a counter when the entry and receipt servlets are accessed.</p><a name="wp64604"> </a><p class="pBody">In the <code class="cCode">doFilter</code> method, both filters retrieve the servlet context from the filter configuration object so that they can access the counters stored as context attributes. After the filters have completed application-specific processing, they invoke <code class="cCode">doFilter</code> on the filter chain object passed into the original <code class="cCode">doFilter</code> method. The elided code is discussed in the next section.</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative">public final class HitCounterFilter implements Filter {&nbsp;&nbsp;private FilterConfig filterConfig = null;&nbsp;&nbsp;public void init(FilterConfig filterConfig) &nbsp;&nbsp;&nbsp;&nbsp;throws ServletException {&nbsp;&nbsp;&nbsp;&nbsp;this.filterConfig = filterConfig;&nbsp;&nbsp;}&nbsp;&nbsp;public void destroy() {&nbsp;&nbsp;&nbsp;&nbsp;this.filterConfig = null;&nbsp;&nbsp;}&nbsp;&nbsp;public void doFilter(ServletRequest request,&nbsp;&nbsp;&nbsp;&nbsp;ServletResponse response, FilterChain chain) &nbsp;&nbsp;&nbsp;&nbsp;throws IOException, ServletException {&nbsp;&nbsp;&nbsp;&nbsp;if (filterConfig == null)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;&nbsp;&nbsp;&nbsp;&nbsp;StringWriter sw = new StringWriter();&nbsp;&nbsp;&nbsp;&nbsp;PrintWriter writer = new PrintWriter(sw);&nbsp;&nbsp;&nbsp;&nbsp;Counter counter = (Counter)filterConfig.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getServletContext().&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getAttribute(&quot;hitCounter&quot;);&nbsp;&nbsp;&nbsp;&nbsp;writer.println();&nbsp;&nbsp;&nbsp;&nbsp;writer.println(&quot;===============&quot;);&nbsp;&nbsp;&nbsp;&nbsp;writer.println(&quot;The number of hits is: &quot; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;counter.incCounter());&nbsp;&nbsp;&nbsp;&nbsp;writer.println(&quot;===============&quot;);&nbsp;&nbsp;&nbsp;&nbsp;// Log the resulting string&nbsp;&nbsp;&nbsp;&nbsp;writer.flush();&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(sw.getBuffer().toString());&nbsp;&nbsp;&nbsp;&nbsp;...&nbsp;&nbsp;&nbsp;&nbsp;chain.doFilter(request, wrapper);&nbsp;&nbsp;&nbsp;&nbsp;...&nbsp;&nbsp;}}<a name="wp64605"> </a></pre></div><a name="wp64606"> </a><h3 class="pHeading2">Programming Customized Requests and Responses</h3><a name="wp64609"> </a><p class="pBody">There are many ways for a filter to modify a request or response. For example, a filter could add an attribute to the request or insert data in the response. In the Duke's Bookstore example, <code class="cCode">HitCounterFilter</code> inserts the value of the counter into the response.</p><a name="wp64610"> </a><p class="pBody">A filter that modifies a response must usually capture the response before it is returned to the client. The way to do this is to pass a stand-in stream to the servlet that generates the response. The stand-in stream prevents the servlet from closing the original response stream when it completes and allows the filter to modify the servlet's response. </p><a name="wp64612"> </a><p class="pBody">To pass this stand-in stream to the servlet, the filter creates a response wrapper that overrides the <code class="cCode">getWriter</code> or <code class="cCode">getOutputStream</code> method to return this stand-in stream. The wrapper is passed to the <code class="cCode">doFilter</code> method of the filter chain. Wrapper methods default to calling through to the wrapped request or response object. This approach follows the well-known Wrapper or Decorator pattern described in <em class="cEmphasis">Design Patterns, Elements of Reusable Object-Oriented Software </em>(Addison-Wesley, 1995). The following sections describe how the hit counter filter described earlier and other types of filters use wrappers.</p><a name="wp64615"> </a><p class="pBody">To override request methods, you wrap the request in an object that extends <code class="cCode"><a  href="http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/ServletRequestWrapper.html" target="_blank">ServletRequestWrapper</a></code> or <code class="cCode"><a  href="http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/http/HttpServletRequestWrapper.html" target="_blank">HttpServletRequestWrapper</a></code>. To override response methods, you wrap the response in an object that extends <code class="cCode"><a  href="http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/ServletResponseWrapper.html" target="_blank">ServletResponseWrapper</a></code> or <code class="cCode"><a  href="http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/http/HttpServletResponseWrapper.html" target="_blank">HttpServletResponseWrapper</a></code>. </p><a name="wp64622"> </a><p class="pBody"><code class="cCode">HitCounterFilter</code> wraps the response in a <code class="cCode"><a  href="../examples/web/bookstore1/src/filters/CharResponseWrapper.java" target="_blank">CharResponseWrapper</a></code>. The wrapped response is passed to the next object in the filter chain, which is <code class="cCode">BookStoreServlet</code>. <code class="cCode">BookStoreServlet</code> writes its response into the stream created by <code class="cCode">CharResponseWrapper</code>. When <code class="cCode">chain.doFilter</code> returns, <code class="cCode">HitCounterFilter</code> retrieves the servlet's response from <code class="cCode">PrintWriter</code> and writes it to a buffer. The filter inserts the value of the counter into the buffer, resets the content length header of the response, and finally writes the contents of the buffer to the response stream.</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative">PrintWriter out = response.getWriter();CharResponseWrapper wrapper = new CharResponseWrapper(&nbsp;&nbsp;(HttpServletResponse)response);chain.doFilter(request, wrapper);<code class="cCode">CharArrayWriter caw = new CharArrayWriter();caw.write(wrapper.toString().substring(0,&nbsp;&nbsp;wrapper.toString().indexOf(&quot;&lt;/body&gt;&quot;)-1));caw.write(&quot;&lt;p&gt;\n&lt;center&gt;&quot; + &nbsp;&nbsp;messages.getString(&quot;Visitor&quot;) + &quot;&lt;font color=&#39;red&#39;&gt;&quot; + &nbsp;&nbsp;counter.getCounter() + &quot;&lt;/font&gt;&lt;/center&gt;&quot;);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -