We are using OSGI Equinox "org.eclipse.equinox.http.registry.resources" extension to define resources accessible in our different JAR in our OSGI Equinox server. Most of them are just to point to static HTML content so there's no Servlet implementation. I was wondering what was the easiest way to define the default page for a sub folder (defining the "Welcome" file usually defined in a web.xml in standard Servlet packaging). Basically, I define a resource at /mynewresource and would link the user to be directed to index.html when he enters instead of getting a server error.
If you just want to have a default behavior of going to index.html on your resource, you can create that simple filter:
public class WelcomFilter implements javax.servlet.Filter {
/** {#inheritDoc} */
#Override
public void init(FilterConfig filterConfig) throws ServletException {
}
/** {#inheritDoc} */
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
if (request instanceof HttpServletRequest) {
HttpServletRequest r = (HttpServletRequest) request;
if ("/".equals(r.getPathInfo())) {
r.getRequestDispatcher("index.html").forward(request, response);
} else {
chain.doFilter(request, response);
}
} else {
chain.doFilter(request, response);
}
}
/** {#inheritDoc} */
#Override
public void destroy() {
}
}
You have two choices: you can register this filter once at the root (/) but keep in mind that any request with no path info will get redirected to index.html or you can register it for the sub-domain where you want it. In any case, you need to use the equinox http filter extension.
<extension
point="org.eclipse.equinox.http.registry.filters">
<filter
alias="/mydomain"
class="com.abc.filters.WelcomeFilter">
</filter>
</extension>
There is no standardised way yet to define a default (or welcome) page in an OSGi server.
Coincidentally, I faced the same and decided to add this functionality to the Amdatu-Web project. Aside allowing non-Java resources to be served through the web, it now also allows you to define a default page like:
X-Web-Resource-Default-Page: index.html
or a default page for a specific directory:
X-Web-Resource-Default-Page: /path=index.html
The default page(s) will be served in case no file is requested.
It is not entirely done yet, as it needs some reviewing and I need to update the documentation and examples a bit on the Amdatu website. But, you can already take a look at the code (especially the demo project in the BitBucket project) to get an idea of how it should work.
Filters didn't work for me (using Kura/Equinox) however, using a custom HttpContext implementation I was able to add the required logic in getResources.
Related
I am capturing URLs requested for my website. I need to see what all pages were requested from my website.
To achieve this I created a basic filter, and started logging page requests from there.
Now, this filter catches all the requests specific to a page.
For e.g. abc.com/page1, abc.com/resources/myjs.js, etc.
My problem is that for each page request, subsequent resources(js,css) are requested too. I want to capture only the relevant requests.
Right now, I check for patterns like /resources to ignore such requests, but I am looking for a more clean approach.
Also, will interceptors be more useful here?
I have seen filter patterns as well. But those are not useful, since I would have to create patterns for my filter.
If you want to capture the urls accessed from your website, you can configure spring boot to generate access logs in following way until you don't want more advance information:
server.tomcat.accesslog.directory=/logs/ #absolute directory path for log files\
server.tomcat.accesslog.enabled=false #Enable access log.
server.tomcat.accesslog.pattern=any_pattern # log string format pattern for access logs.
To perform any operation based on any request pattern, you can go ahead with filters.
I'm using filters for such requirements in following way:
public class CustomFilter extends OncePerRequestFilter{
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
String url = request.getRequestURI();
if (url.startsWith("/resources/")) {
//your business logic
}
filterChain.doFilter(request,response);
}
}
Iam working on a jersey project and Iam using token authentication and am using ContainerRequestFilter for filtering all the request and checking whether it has a token with it, but the requests includes Login and registration request, but we need to skip these request.. How i can skip the filtering for login and registration requests? Is there any mechanism in jersey for achieving this?
thank you
As far as I know, there is no facility fo such a behavior using a raw deployment descriptor (web.xml).
However, if that was a custom filter, you can get it skip the excluded paths using a simple check on request url in your doFilter() method. But since you are using a third party filter, that won't be the way to go with but still can have this functionality achieved:
Change your third party filter (ContainerRequestFilter) mapping to another path rather than a wildcard one:
<filter-mapping>
<filter-name>containerRequestFilter</filter-name>
<url-pattern>/tokenizedpaths/*</url-pattern>
</filter-mapping>
Declare a new filter (you will see in a moment what it looks like), that will be mapped to a wildcard path to filter all requests and be delegated to dispatch requests to your containerRequestFilter only if the request path does not match the excluded path(s) (I've choosen register as a sample):
<filter>
<filter-name>filteringFilter</filter-name>
<filter-class>com.sample.FilteringServletFilter</filter-class>
<init-param>
<param-name>excludedPaths</param-name>
<param-value>/register</param-value>
</init-param>
</filter>
The FilteringServletFilter will look like somthing like the following:
public class FilteringServletFilter implements Filter {
private List<String> excludedPaths = new ArrayList<String>();
public void init(FilterConfig config) throws ServletException {
// You can declare a comma separated list to hold your excluded paths
this.excludedPaths = Arrays.asList(config.getInitParameter("excludedPaths").split(","));
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
String path = ((HttpServletRequest) request).getRequestURI();
// If the url is one of excluded paths, then just continue with next filter
if (this.excludedPaths.contains(path)) {
chain.doFilter(request, response);
return;
}
// Otherwilse, forward the request to the needed filter
else {
request.getRequestDispatcher("/tokenizedpaths" + path).forward(request, response);
}
}
}
I have got a website, with really badly implemented Vanity URL module and really high loads at certain periods of time. Due to some bugs in the url module, the system needs to be restarted every so often. So, I want to rewrite a bloody module to make it nice and less buggy...
Is there are a good pattern to implementing Vanity URL system ?
What is the best approach when dealing with Vanity URL's for high performance ?
What is the best library to look at the sources ?
Cheers.
Ako
I'm not sure about the specific implementation details of your application, but as a general sketch I would write a Filter mapped to the space of URL of interest (perhaps /*).
Such Filter would check if the URL is a fancy one, and in that case would forward the request to the appropiate resource (either a URL dispatcher or a named one). You will need to save the filterConfig.getServletContext() passed in init(FilterConfig) in order to create the request dispatchers. If the URL is not fancy, the filter would invoke chain.doFilter(req, resp), then serving a non-mapped resource.
public class ExceptionFilter implements Filter {
private ServletContext servletContext;
public void destroy() {}
public void doFilter(ServletRequest req,
ServletResponse resp,
FilterChain chain)
throws IOException, ServletException {
String mapping = getMappingFor((HttpServletRequest)req);
if(mapping!=null) servletContext.getRequestDispatcher(mapping).forward(req,resp);
else chain.doFilter(req, resp);
}
public void init(FilterConfig filterConfig) throws ServletException {
this.servletContext = filterConfig.getServletContext();
}
private String getMappingFor(HttpServletRequest req) {...}
How getMappingFor is implemented, depends on the application, but it would probably open a connection to a database and ask whether URL /foo/bar is mapped, returning the mapped URL or nullif there is no mapping. If the mappings are known not to change, you may cache those mappings already retrieved.
You may go with more detailed implementations, such as setting some request attributes depending on the given URL or information from the database, and then forwarding the request to some servlet that knows what to do.
I have SpringMVC project with Freemarker as view resolver. In some templates I have to generate links including hostname, but I can't get it.
In JSP I may to do like this:
`<% String hostName=request.getServerName();%>`
I tried to use "requestContextAttribute", but requestContext.getContextPath() returned path without hostname.
Where can I get full path or hostname separately?
We can do this in JSTL. Try adapting it in FreeMarker:
${pageContext.request.serverName}
It's important to understand that Freemarker is intentionally designed to not have knowledge of the context in which it's used, to make it more generic. That means that unlike JSPs, it has no access to the HttpServletRequest and Response objects by default. If you want it to have access, you'll need to provide it.
The way I solved this was to create a Servlet Filter to add the HttpServletRequest object as a Request Attribute which Freemarker does have access to.
/**
* This simple filter adds the HttpServletRequest object to the Request Attributes with the key "RequestObject"
* so that it can be referenced from Freemarker.
*/
public class RequestObjectAttributeFilter implements Filter
{
/**
*
*/
public void init(FilterConfig paramFilterConfig) throws ServletException
{
}
public void doFilter(ServletRequest req,
ServletResponse res, FilterChain filterChain)
throws IOException, ServletException
{
req.setAttribute("RequestObject", req);
filterChain.doFilter(req, res);
}
public void destroy()
{
}
}
You'll need to define this in your web.xml in order for it to work:
<filter>
<filter-name>RequestObjectAttributeFilter</filter-name>
<filter-class>com.foo.filter.RequestObjectAttributeFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>RequestObjectAttributeFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Then, in my .ftl files, I can use the following:
${Request.RequestObject.getServerName()}
This code should work in freemarker:
<#assign hostname = request.getServerName() />
bar
But with freemarker it's better to get server name in java and push it into template as string.
I have a web application with the following structure:
TOMCAT_HOME
|
webapps
|_myapp
|-html/
|-various directories
|-WEB-INF/
|-index.html
The application has various servlets that are registered over various paths.
The application itself can be accessed via http://IP:PORT/myapp/
This of courses causes to get the index.html (in the welcome list).
My question is, how would I register a filter for specifically the access of the root directory but not the subdirectories i.e. the url-mapping not to be /*
If I place as url-pattern / seems not to work.
So the filter would intercept only this request http://IP:PORT/myapp/ and not http://IP:PORT/myapp/path or http://IP:PORT/myapp/servlet/path.
Additionally the filter would intercept a request like http://IP:PORT/myapp/index.html which is equivalent to the one I aim.
Thanks
Why not set the filter as /index.html then? It will not cause your subdirectories to be filtered.
You can easily test for / and do your thing, otherwise let it pass through. With a /* URL pattern.
#Override
public void doFilter(ServletRequest req,ServletResponse res,FilterChain chain)
throws IOException,ServletException{
HttpServletRequest request=(HttpServletRequest)req;
String path=request.getServletPath();
if(path.equals("/") || path.equals("/index.html"){
// do your thing
}
chain.doFilter(req,res);
}