AppEngine domain redirect using web.xml - java

I want to intercept all incoming requests e.g.
http://subdomain.domain.org/path/to/resource
to
https://appengineid.appspot.com/path/to/resource
for any possible /path/to/resource
Is this possible with the app engine web.xml deployment descriptor?
When I search this topic all the documentation or questions/answers relate to transforming/translating the /path/to/resource part of a request rather than the subdomain.domain.tld part?
Thanks
QUESTION EDIT/UPDATE:
Both of the above URLs point to the exact same instance of an app engine application. I don't want to URL pattern match on the /path/to/resource because this would "match" requests to both URLs. I want to URL pattern match on the domain part of the URL, so that any requests to subdomain.domain.org are redirected to appengineid.appspot.com, and then, so that no cycle is encountered any requests to appengineid.appspot.com are ignored by the redirecting filter and are handled by the rest of the web deployment descriptor.

It seems to be that a Filter will solve your problem.
You create a new filter in your web.xml, like this:
<filter>
<filter-name>yourFilterName</filter-name>
<filter-class>com.acme.filter.YourNewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>yourFilterName</filter-name>
<url-pattern>/path/to/resource/*</url-pattern>
</filter-mapping>
Your filter class will be something like this:
public class YourNewFilter extends MyGenericFilter implements Filter {
public void doFilter(final ServletRequest request,
final ServletResponse response,
FilterChain chain)
throws java.io.IOException, javax.servlet.ServletException {
ServletContext context= getServletContext();
req.getRequestURL().toString() // use this method to get the end of the URL
RequestDispatcher rd= context.getRequestDispatcher("https://appengineid.appspot.com/path/to/resource/" + end of the URL
);
rd.forward(request, response);
}
}
It is gonna intercept all requests in one domain and dispatch it to another.

Related

How to avoid request to Java Web Application servlet from outside some network?

I am trying to build a web application which is only meant to be accessed from inside a specific network, lets say a company's network. If anyone tries the URL for the application from outside the company's network then the access should be denied. I know I can use doFilter method for this task. But I am not really sure how to start checking the requests that are only coming from inside the company's network.
Can anyone point me to any useful resource or tell me how to achieve this in Java?
try to implement
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
String validParams = request.getParameter("validParams");
if(!"blockTheRequest".equals(validParams)){
filterChain.doFilter(request, response);
return;
}
HttpResponse httpResponse = (HttpResponse) httpResponse;
httpResponse.getWriter().write("a different response... e.g in HTML");
}
and you need do configure it with in web.xml
<filter>
<filter-name>yourFilterURL</filter-name>
<filter-class>servlets.SimpleServletFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>yourFilterURL</filter-name>
<url-pattern>*.pattern</url-pattern>
</filter-mapping>

Skip request filter for specific resource in jersey

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);
}
}
}

Spring MVC Multiple Controllers with same #RequestMapping

I am trying to make a web app that allows user to login from landing page index.htm. this action is mapped with a LoginController that after successful login takes user back to same index.htm but as logged in user and greets user with welcome message.
index.htm also have another form named itemform, that allows user to add in item name as text. This action is controlled by itemController.
My problem is both my LoginController and itemController have same #RequestMapping and hence I get this error:
Error creating bean with name 'org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping#0' defined in ServletContext resource [/WEB-INF/tinga-servlet.xml]: Initialization of bean failed; nested exception is java.lang.IllegalStateException: Cannot map handler [loginController] to URL path [/index.htm]: There is already handler [com.tinga.LoginController#bf5555] mapped.
Cannot map handler [loginController] to URL path [/index.htm]: There is already handler [com.tinga.LoginController#bf5555] mapped.
How should I go about tackling this problem?
#RequestMapping(value="/login.htm")
public ModelAndView login(HttpServletRequest request, HttpServletResponse response) {
// show login page if no parameters given
// process login if parameters are given
}
#RequestMapping(value="/index.htm")
public ModelAndView index(HttpServletRequest request, HttpServletResponse response) {
// show the index page
}
Finally, you'll need a servlet filter to intercept the requests and if you're not requesting the login.htm page, you'll have to check to make sure the user is logged in. If you, you allow the filterchain to proceed. If not, you issue a forward to /login.htm
public class LoginFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest)request;
boolean loggedIn = ...; // determine if the user is logged in.
boolean isLoginPage = ...; // use path to see if it's the login page
if (loggedIn || isLoginPage) {
chain.doFilter(request, response);
}
else {
request.getRequestDispatcher("/login.htm").forward(request, response);
}
}
}
And in the web.xml
Example from my deployment descriptor:
<filter>
<filter-name>LoginFilter</filter-name>
<filter-class>LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
This is all from memory, but it should give you the general idea of how to go about this.
Request Mapping for all controllers should be unique in Spring MVC.
Maybe in your controllers with the same #RequestMapping you should define the Method (GET, POST...), like this way:
#RequestMapping(value="/index.htm", method = RequestMethod.GET)
#RequestMapping(value="/index.htm", method = RequestMethod.POST)
The controller with the GET method you use to render the form and bind the data (some object) to it. The controller with POST method you usually use to process the submission and validation of the form.
Add an hidden parameter in your forms to differentiate them, then differentiate them by adding the params attribute in the annotation of your post methods.
<form:hidden name="hiddenAction" value="login" />
<form:hidden name="hiddenAction" value="item" />
#RequestMapping(method = RequestMethod.POST, params = {"hiddenAction=login"})
#RequestMapping(method = RequestMethod.POST, params = {"hiddenAction=item"})

How do I specify a query string in Tomcat's <servlet-mapping> <url-pattern>?

I am running Tomcat 5.5.4 and have a servlet running with no problems. However, I'd like to set up a mapping to only launch the servlet when a URL containing a particular query string is submitted.
Right now in web.xml I have:
<servlet-mapping>
<servlet-name>MyServer</servlet-name>
<url-pattern>/go/*</url-pattern>
</servlet-mapping>
If a browser submits http://localhost/MyServer/go?P=123 the servlet is launched and all is well. However, I'd like to only launch that servlet if the URL is exactly as just shown. Unfortunately, right now if the URL is http://localhost/MyServer/go?P=AnyDarnThing the servlet still launches. I have tried setting up the following:
<url-pattern>/go?P=123</url-pattern>
but this results in The requested resource (/MyServer/go) is not available.
I've tried numerous variations (quoting the string, ...) on the above URL pattern but I always get the above error. I notice that if I (for debugging purposes) drop the "?" as in
<url-pattern>/goP=123</url-pattern>
I no longer get the error message and the server launches (but, of course, it doesn't respond to the "query string" because it's not properly formed.) This suggest to me that the "?" is causing a problem in the mapping. I've tried replacing it with its URL special character equivalent as follows:
<url-pattern>/go%3FP=123</url-pattern>
but this gives the same result just described above when I tried dropping the "?" altogether.
I realize I can let the servlet get launched when any query string is submitted and then "ignore" the request for all but the one I care about but there is a reason I'd prefer to not have the servlet launched to begin with. So, my question is, how can I configure the servlet so that it is only launched when a specific query string is included?
Thank you.
You can't do that. The url-pattern is pretty limited.
If you want to have distinct actions taken based on a GET parameter, you can do that manually. In the doGet() method of the servlet have a simple if-clause and invoke different methods depending on the query string / get param.
You can't do that using URL patterns.
You can achive this using filters. Implement a filter which will forward to the Servlet only if the query params exists.
Here is the how the filter will look like:
public class ServletAcessFilter implements Filter
{
public void init(FilterConfig filterConfig) throws ServletException
{
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) throws IOException, ServletException
{
//validate the request, check if the request can be forwarded to servlet.
if(request.getParameter("P").equalsIgnoreCase("123")){
filterChain.doFilter(request, response);
} else {
//write what you want to do if the request has no access
//below code will write 404 not found, you can do based on your requirement
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.setStatus(404);
}
}
public void destroy()
{
}
}
Define the filter in the web.xml like this:
<filter>
<filter-name>ServletAccessFilter</filter-name>
<filter-class>com.ServletAcessFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ServletAccessFilter</filter-name>
<url-pattern>/go/*</url-pattern>
</filter-mapping>
To add to Bozho response, you may also try to move to Clean URLs
This will greatly increase your options in terms of URL pattern matching, and, in particular, may significantly ease configuration of a fronting reverse proxy if you ever need one.

Tomcat - Redirect to Error Page when ServletContextListener fails

When Tomcat starts it calls my ServletContextListener to obtain a database connection, which I will later use in other servlets with getServletContext(). It is called in my web.xml as:
listener
listener-class org.ppdc.database.DBCPoolingListener /listener-class
/listener>
(I removed the < > because they wouldn't display properly in this message.>
If I cannot connect to the database when Tomcat starts up I get a 404 error, because Tomcat cannot start the application.
How can I redirect the user to a custom error page at this point? I tried the following in my web.xml (I have the < > brackets in the original):
(error-page)
(error-code404/error-code)
(location/file_not_found.html/location)
(/error-page)
Any ideas on how to redirect a user to one of my error pages when Tomcat tries to start the application?
Thanks
Vic
If your application fails to load, then that's it. Tomcat is not running it and does not serve your error-pages.
So, if you want to handle a half-dead state, you need to start in a half-dead state. Fortunately, the code in your servlets can be spared checks whether the app is half-dead if you install a Filter, that does it before control is transfered to any servlet.
Declare a filter in web.xml:
<filter>
<filter-name>IsHalfDeadFilter</filter-name>
<filter-class>my.package.IsHalfDeadFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>IsHalfDeadFilter</filter-name>
<url-pattern>*</url-pattern>
</filter-mapping>
Then implement doFilter method to redirect to your error page.
#Override
public void doFilter (
final ServletRequest request,
final ServletResponse response,
final FilterChain chain
) throws
IOException,
ServletException
{
if ( isHalfDead )
{
// redirect to error page
return;
}
chain.doFilter( request, response );
}
Read more about Filters here

Categories

Resources