001: /*
002: * Copyright 2002-2005 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.springframework.web.filter;
018:
019: import java.io.IOException;
020:
021: import javax.servlet.FilterChain;
022: import javax.servlet.ServletException;
023: import javax.servlet.http.HttpServletRequest;
024: import javax.servlet.http.HttpServletResponse;
025:
026: /**
027: * Base class for <code>Filter</code>s that perform logging operations before and after a
028: * request is processed.
029: *
030: * <p>Subclasses should override the <code>beforeRequest(HttpServletRequest, String)</code>
031: * and <code>afterRequest(HttpServletRequest, String)</code> methods to perform the actual
032: * logging around the request.
033: *
034: * <p>Subclasses are passed the message to write to the log in the <code>beforeRequest</code>
035: * and <code>afterRequest</code> methods. By default, only the URI of the request is logged.
036: * However, setting the <code>includeQueryString</code> property to <code>true</code> will
037: * cause the query string of the request to be included also.
038: *
039: * <p>Prefixes and suffixes for the before and after messages can be configured
040: * using the <code>beforeMessagePrefix</code>, <code>afterMessagePrefix</code>,
041: * <code>beforeMessageSuffix</code> and <code>afterMessageSuffix</code> properties,
042: *
043: * @author Rob Harrop
044: * @author Juergen Hoeller
045: * @since 1.2.5
046: * @see #beforeRequest
047: * @see #afterRequest
048: */
049: public abstract class AbstractRequestLoggingFilter extends
050: OncePerRequestFilter {
051:
052: public static final String DEFAULT_BEFORE_MESSAGE_PREFIX = "Before request [";
053:
054: public static final String DEFAULT_BEFORE_MESSAGE_SUFFIX = "]";
055:
056: public static final String DEFAULT_AFTER_MESSAGE_PREFIX = "After request [";
057:
058: public static final String DEFAULT_AFTER_MESSAGE_SUFFIX = "]";
059:
060: private boolean includeQueryString = false;
061:
062: private String beforeMessagePrefix = DEFAULT_BEFORE_MESSAGE_PREFIX;
063:
064: private String beforeMessageSuffix = DEFAULT_BEFORE_MESSAGE_SUFFIX;
065:
066: private String afterMessagePrefix = DEFAULT_AFTER_MESSAGE_PREFIX;
067:
068: private String afterMessageSuffix = DEFAULT_AFTER_MESSAGE_SUFFIX;
069:
070: /**
071: * Set the whether or not the query string should be included in the log message.
072: * Should be configured using an <code><init-param></code> in the filter
073: * definition in <code>web.xml</code>.
074: */
075: public void setIncludeQueryString(boolean includeQueryString) {
076: this .includeQueryString = includeQueryString;
077: }
078:
079: /**
080: * Return whether or not the query string should be included in the log message.
081: */
082: protected boolean isIncludeQueryString() {
083: return includeQueryString;
084: }
085:
086: /**
087: * Set the value that should be prepended to the log message written
088: * <i>before</i> a request is processed.
089: */
090: public void setBeforeMessagePrefix(String beforeMessagePrefix) {
091: this .beforeMessagePrefix = beforeMessagePrefix;
092: }
093:
094: /**
095: * Set the value that should be apppended to the log message written
096: * <i>before</i> a request is processed.
097: */
098: public void setBeforeMessageSuffix(String beforeMessageSuffix) {
099: this .beforeMessageSuffix = beforeMessageSuffix;
100: }
101:
102: /**
103: * Set the value that should be prepended to the log message written
104: * <i>after</i> a request is processed.
105: */
106: public void setAfterMessagePrefix(String afterMessagePrefix) {
107: this .afterMessagePrefix = afterMessagePrefix;
108: }
109:
110: /**
111: * Set the value that should be appended to the log message written
112: * <i>after</i> a request is processed.
113: */
114: public void setAfterMessageSuffix(String afterMessageSuffix) {
115: this .afterMessageSuffix = afterMessageSuffix;
116: }
117:
118: /**
119: * Forwards the request to the next filter in the chain and delegates
120: * down to the subclasses to perform the actual request logging both
121: * before and after the request is processed.
122: * @see #beforeRequest
123: * @see #afterRequest
124: */
125: protected void doFilterInternal(HttpServletRequest request,
126: HttpServletResponse response, FilterChain filterChain)
127: throws ServletException, IOException {
128:
129: beforeRequest(request, getBeforeMessage(request));
130: try {
131: filterChain.doFilter(request, response);
132: } finally {
133: afterRequest(request, getAfterMessage(request));
134: }
135: }
136:
137: /**
138: * Get the message to write to the log before the request.
139: * @see #createMessage
140: */
141: private String getBeforeMessage(HttpServletRequest request) {
142: return createMessage(request, this .beforeMessagePrefix,
143: this .beforeMessageSuffix);
144: }
145:
146: /**
147: * Get the message to write to the log after the request.
148: * @see #createMessage
149: */
150: private String getAfterMessage(HttpServletRequest request) {
151: return createMessage(request, this .afterMessagePrefix,
152: this .afterMessageSuffix);
153: }
154:
155: /**
156: * Create a log message for the given request, prefix and suffix.
157: * <p>If <code>includeQueryString</code> is <code>true</code> then
158: * the inner part of the log message will take the form
159: * <code>request_uri?query_string</code> otherwise the message will
160: * simply be of the form <code>request_uri</code>.
161: * <p>The final message is composed of the inner part as described
162: * and the supplied prefix and suffix.
163: */
164: protected String createMessage(HttpServletRequest request,
165: String prefix, String suffix) {
166: StringBuffer buffer = new StringBuffer();
167: buffer.append(prefix);
168: buffer.append(request.getRequestURI());
169: if (isIncludeQueryString()) {
170: buffer.append('?');
171: buffer.append(request.getQueryString());
172: }
173: buffer.append(suffix);
174: return buffer.toString();
175: }
176:
177: /**
178: * Concrete subclasses should implement this method to write a log message
179: * <i>before</i> the request is processed.
180: * @param request current HTTP request
181: * @param message the message to log
182: */
183: protected abstract void beforeRequest(HttpServletRequest request,
184: String message);
185:
186: /**
187: * Concrete subclasses should implement this method to write a log message
188: * <i>after</i> the request is processed.
189: * @param request current HTTP request
190: * @param message the message to log
191: */
192: protected abstract void afterRequest(HttpServletRequest request,
193: String message);
194:
195: }
|