Externalizing links in servlets to a constant - java

I have lots of servlets that redirects through
response.sendRedirect(URL)
And URL has a absolute path starting with http://localhost:8080.
Well, I need to change URL so I make this server online, but don't want to change
all instances of URL in all servlets.
Needed to know if there's a way to externalize this constant neatly.
Thanks in advance.

You can either use a Properties file or make use of context parameters in your web.xml. Using properties is preferred if you would like to later provide language translations for your web application. If there are only a few constants that need to be externalised like the server url and admin email etc. context parameters is an equally good choice.
<context-param>
<param-name>server-hostname</param-name>
<param-value>http://www.domain.com/</param-value>
</context-param>
You can access this parameter globally from any Servlet as
response.sendRedirect(
getServletContext().getInitParameter("server-hostname") + "page.php"));

Related

Tomcat web.xml: restrict access to specific methods of a servlet

I'm running a web application under Tomcat server. Different servlets are configured using Tomcat's web.xml.
I'm looking for a convenient way to restrict access to specific METHODS of specific URLS so that only these METHODS can be accessed using an Authorization header while others can be accessed without any restriction.
For instance, for url http://localhost:8080/my/servlet1 - GET and OPTIONS can be accessed by any user, while POST and PUT must be authorized with a username and a password, but for url http://localhost:8080/my/servlet2- all methods are open.
How can I implement that?
Thanks
The most low level API that allows you to do all sorts of filtering based on the context of the HTTP request in the javax/servlet/Filter
You implement a filter class that can restrict on the basis of HTTP method and any other criteria you choose. You register the filter on your web.xml and you add rules for which paths it is filtering.
Here is an walk through on applying such a filter.
If you happen to be using more than just a naked Tomcat for your application and you are using Spring Boot on top of it you could use their flavor of filters. This is an example for that case.

Configuring servlet url-patterns without web.xml

I know this can be done in servlet 3.0 with the #Webservlet annotation where you just assign the url-patterns and not have to do any configurations within a web.xml. Is there a way to programmatically assign a servlets url-pattern for applications running servlet 2.5?
I am creating a library which multiple applications will depend on and trying to make it so each of these applications do not have to explicitly configure any servlet url mappings for the servlets in the library I am creating within their respective web.xml file.
Thanks,
Since the web.xml and #Webservlet are both mechanisms for the server to know where to route requests by examining the war, you would have to be able to manipulate the server if you wanted to do it in code. This is at least theoretically possible, since the server could offer for example a JMX endpoint for configuration or you could go directly into the innards of the server.
However while it might be possible, it would be a non-standard way and you would have to write different tricks for all the servers you want to support. That's not something you want to do.
Finally, if you're creating a library, why does it have servlets in it? It shouldn't be the responsibility of the library to create servlets or decide which urls they're assigned to.

Changing servlet location on Init()

Is it possible to change the init parameters so that the servlet is created at a different path? I need to create a servlet at a certain path. Furthermore, would it be possible to artificially pass the path inside the init parameters?
As already shown in other answers, the servlet mapping is not controlled by the servlet, therefore you can't change that from within a servlet instance.
However, you can work around this by introducing a level of indirection (something like a "dispatcher" servlet): map your servlet to a wildcard pattern (like /app/*) and inside your servlet decide the actual action based on the request url path: /app/X will trigger some X action, while /app/Y will trigger Y.
Lots of web frameworks will provide the full functionality out of the box: you can have a look at Spring MVC's DispatcherServlet and its HandlerMapping concept, for instance.
Servlets aren't created at a certain path. They are Java objects that the servlet container Java application creates. If you are running Tomcat, for example, your application will run from the /webapps directory. The most you can do is change the Tomcat configuration to run it from some other path, but you'll have to do this before actually starting the application.
Short answer - you can't change anything related to servlet path mapping in init, since servlet container has already read mapping from web.xml.
Longer answer - you may want to look at servlet loader in Tomcat for example, perhaps it's possible to either invoke it's methods through JMX or do something else.
If you just want to have several mappings and choose which one to serve depending on configuration - use Servlet Filter

Tomcat adds context-path to urls

In my application every link generated is surrounded by response.ecodeURL. On some servers encodeURL adds the context-path to the URL.
The application is named "appl". Creating a link /a/b/c.jsp creates on DEV-system the url /a/b/c.jsp, on Prod it creates /appl/a/b/c.jsp
The tomcat is behind an Apache Webserver which connects via ajp, not sure if thats a relevant fact.
EDIT:
The Webserver isn't relevant. I tried going directly on port 8080 and the same happend again.
<c:url> always pre-pends the context path to URLs: this is standard practice and should always be done. If you are using <c:url> then you shouldn't add your own prefix. Also note that <c:url> runs the URL through HttpServletResponse.encodeURL for you. That method adds URL-based session-tracking information (e.g. the ";jsessionid" path parameter) if appropriate.
You should always add the context prefix to all URLs, whether you use something like <c:url> or do it yourself. You just shouldn't do both. When you use the ROOT context, the context path with be "" (i.e. empty string) and nothing will be pre-pended to your URLs.

Spring MVC REST : static files unaccessible because of url-pattern

My Spring Dispatcher servlet url-pattern is /* (as spring MVC REST suggests)
Now all the request are resolved by this Servlet. even CSS/JS/Images also get resolved and handled by servlet..
So, Spring MVC tries to find controller.. :(
How to bypass this? Is there any standard way out of this problem??
& Don't want to change url-pattern to /rest/* (so, other static resources get accessed by /css/ or /js etc.)
You can map your controllers to a smaller set of URLS (i.e. /app/*), and then rewrite the URLs that your users actually see so that they don't even know about. Have a look at the mvc-basic webapp sample, particularly web.xml and urlrewrite.xml to see how this is done.
Map the Spring dispatcher to some subsection of the URL space, and use Tuckey to rewrite URLs the user deals with.
http://www.example.org/app/controller/action -> http://www.example.org/controller/action
Just a heads-up update on this: the default rewrite configuration as defined in the Spring sample did not work out of the box for me. The rewrite rules for stylesheets, scripts, etc. were still processed to the /app/* rule, and subsequently handled by the DispatchServlet, which is not desirable.
I had to add the last="true" attribute to the styles/scripts/images rules to indicate that other rules should not apply, and I had to use the FreeMarker Spring URL macro in any CSS/JS include paths.
Just in case someone encounters the same problem.

Categories