In this blog post, we will focus on how to create and configure a custom servlet filter in Liferay using the @Component annotation. Servlet filters are useful for intercepting HTTP requests and responses, allowing you to add additional processing before or after the request reaches the target servlet.
Objective of Servlet Filter
A Servlet Filter is an object that intercepts HTTP requests to perform pre-processing tasks (before the request reaches the backend) or post-processing tasks (before the response reaches the client). Filters are often used for operations such as logging, authentication, and modifying request/response headers.
Filters can be useful when you need to perform certain tasks before the request reaches the backend, such as checking user credentials, logging request data, or modifying request headers. Similarly, they can also be used to modify responses or add additional information before sending the response to the client.
When to Use Servlet Filters
You might need to use a servlet filter when you want to apply functionality to multiple servlets without the servlets themselves needing to know about it. Some common use cases for servlet filters include:
- Logging: Record details of incoming requests, such as request headers, URL paths, or query parameters.
- Auditing: Track and log user activities, like login attempts, access to sensitive resources, etc.
- Transaction management: Manage database transactions across multiple servlets or requests.
- Security: Implement security features like authentication, authorization, or input validation before passing the request to the target servlet.
Servlet filters can be applied in a chain, where one filter processes the request first and passes it to the next. By mapping filters to specific URLs, you ensure that the filters only apply to requests that match those patterns.
Some typical types of filters you might encounter or create include:
- Authentication Filters: Ensures that the user is authenticated before proceeding with the request.
- Compression Filters: Compresses responses to improve performance and reduce bandwidth usage.
- Encryption Filters: Encrypts request or response data for security purposes.
- Image Compression Filters: Reduces the size of images to improve loading times.
- Tokenizing Filters: Splits or tokenizes data as it is processed through the filter.
Filters are a powerful tool for modifying both request and response objects, and can be configured to apply only to specific URLs or servlets, ensuring flexibility and scalability in web applications.
Creating Your Custom Servlet Filter
Code Example
@Component(
immediate = true,
property = {
"before-filter=Absolute Redirects Filter",
"servlet-context-name=",
"servlet-filter-name=Custom Filter",
"url-pattern=/*"
},
service = Filter.class
)
public class CustomFilterServlet extends BaseFilter {
private static final Log _log = LogFactoryUtil.getLog(CustomFilterServlet.class);
@Override
protected void processFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws Exception {
HttpServletRequest httpRequest = (HttpServletRequest) request;
// Example of reading query string from the request
System.out.println(httpRequest.getQueryString());
// Here you could process other parameters as well
// long someParameter = ParamUtil.getLong(request, "someParameter");
_log.info("Filter is invoked");
// Continue the filter chain, allowing other filters or servlets to process the request
super.processFilter(request, response, filterChain);
}
@Override
protected Log getLog() {
return _log;
}
}
Explanation of the Code:- Component Annotation:
@Component
: This annotation registers the filter as a service in Liferay.immediate = true
: Ensures the filter is loaded immediately when the application starts.property
: Specifies several properties for the filter.service = Filter.class
: Indicates that this class is a filter.
- processFilter Method:
- This method intercepts the incoming request and response. It allows you to perform any processing before the request reaches the target servlet.
- In the example, we print the query string from the request using
httpRequest.getQueryString()
. - After performing any custom logic, we call
super.processFilter(request, response, filterChain)
to continue the filter chain. - We can also redirect the URL if needed using
httpServletResponse.sendRedirect("https://www.redirecturl.com")
.
- Logging:
- We use Liferay's
LogFactoryUtil
to log when the filter is invoked. This helps to track when and how the filter is being triggered.
- We use Liferay's
Component Configuration
The@Component
annotation configures your filter and specifies its execution context. It defines:- The order and scope of the filter.
- The URL pattern that the filter should apply to (in this case, all URLs).
- The filter’s name and context for identification within the application.
Key Properties in the @Component
Annotation:
- before-filter and after-filter: The filter that should be run before the custom filter you're creating and the filter that should be run after, respectively (Not required). To learn more about filters, check Liferay-web.xml.
- servlet-context-name: This should always be set to an empty string.
- servlet-filter-name: The name of your filter, in this case, it’s
"Custom Filter"
. - url-pattern: The URL pattern to match, such as
"/*"
to apply the filter to all URLs. You can adjust this to target specific paths.
By setting up your filter like this, you ensure that the filter is invoked whenever any request matches the URL pattern defined in url-pattern
.