User Home relative path in a servlet init-parm - servlets

Can a path relative to user home be specified in a servlet init-parm?
I want to have the servlet load a property file from a path relative to the user running the server (likely tomcat).

No they can't by themselves. However, I could see an init-param that:
Includes something like ${user.home}/filename. In this case you'd have to parse the ${user.home} to do a System.getProperty() with the contents of the string between the curly brackets.
Is known to be a path relative to the user home directory. So if the init-param is "/filename", your code will read the parameter and know that it has to prepend System.getProperty("user.home").
Either of these methods would be in the init() method of the servlet and either set a static variable in the servlet or interact with the property file there.

Related

URL Pattern with Spring MVC and Spring Security

I have seen some url-pattern in my xml e.g, in filter-mapping, intercept-url, mvc:resources, etc. Are these patterns always the same ? What's the difference among these URL patterns /, /*, /** ?
It depends in which context you ask this question:
Servlet/Filter mappings
Spring Security mappings
Servlet/Filter mappings
In the Web application deployment descriptor, the following syntax is used to define mappings:
A string beginning with a ‘/’ character and ending with a ‘/*’ suffix is used for
path mapping.
A string beginning with a ‘*.’ prefix is used as an extension mapping.
The empty string ("") is a special URL pattern that exactly maps to the
application's context root, i.e., requests of the form http://host:port/<contextroot>/. In this case the path info is ’/’ and the servlet path and context path is
empty string (““).
A string containing only the ’/’ character indicates the "default" servlet of the
application. In this case the servlet path is the request URI minus the context path
and the path info is null.
All other strings are used for exact matches only
This comes from the Servlet Specification (JSR 315) (section 12.2).
In a Servlet/Filter mapping scenario / means the "default" servlet, normally this is where the DefaultServlet (in Tomcat that is) is mapped to. Basically it handles all incoming requests and doesn't pass them on further down the chain for processing (basically this is the last-catch-all mapping).
/* in the servlet mapping scenario means all incoming URLs (when it cannot be processed it will be handed of the the last-catch-all-mapping).
Spring Security mappings
Now when talking about Spring, /, /* and /** have a different meaning. They refer to so called Ant-style path expressions.
Where / means only / (the root of your application), where /* means the root including one level deep and where /** means everything.
So /foo/* will match a URL with /foo/bar but will not match /foo/bar/baz. Whereas /** or /foo/** would match all of them.

OVerride a url mapping defined in a controller present in a jar

I am using spring-security-oauth2 jar file. During the oauth verification process it makes a call to "/oauth/token" and hence the method. I want to modify the method..
Is it possible if i can override the url mapping already present? or exlcude the class from jar..
Thanks
Harshit

Difference between / and /* in servlet mapping url pattern

The familiar code:
<servlet-mapping>
<servlet-name>main</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>main</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
My understanding is that /* maps to http://host:port/context/*.
How about /? It sure doesn't map to http://host:port/context root only. In fact, it will accept http://host:port/context/hello, but reject http://host:port/context/hello.jsp.
Can anyone explain how is http://host:port/context/hello mapped?
<url-pattern>/*</url-pattern>
The /* on a servlet overrides all other servlets, including all servlets provided by the servletcontainer such as the default servlet and the JSP servlet. Whatever request you fire, it will end up in that servlet. This is thus a bad URL pattern for servlets. Usually, you'd like to use /* on a Filter only. It is able to let the request continue to any of the servlets listening on a more specific URL pattern by calling FilterChain#doFilter().
<url-pattern>/</url-pattern>
The / doesn't override any other servlet. It only replaces the servletcontainer's built in default servlet for all requests which doesn't match any other registered servlet. This is normally only invoked on static resources (CSS/JS/image/etc) and directory listings. The servletcontainer's built in default servlet is also capable of dealing with HTTP cache requests, media (audio/video) streaming and file download resumes. Usually, you don't want to override the default servlet as you would otherwise have to take care of all its tasks, which is not exactly trivial (JSF utility library OmniFaces has an open source example). This is thus also a bad URL pattern for servlets. As to why JSP pages doesn't hit this servlet, it's because the servletcontainer's built in JSP servlet will be invoked, which is already by default mapped on the more specific URL pattern *.jsp.
<url-pattern></url-pattern>
Then there's also the empty string URL pattern . This will be invoked when the context root is requested. This is different from the <welcome-file> approach that it isn't invoked when any subfolder is requested. This is most likely the URL pattern you're actually looking for in case you want a "home page servlet". I only have to admit that I'd intuitively expect the empty string URL pattern and the slash URL pattern / be defined exactly the other way round, so I can understand that a lot of starters got confused on this. But it is what it is.
Front Controller
In case you actually intend to have a front controller servlet, then you'd best map it on a more specific URL pattern like *.html, *.do, /pages/*, /app/*, etc. You can hide away the front controller URL pattern and cover static resources on a common URL pattern like /resources/*, /static/*, etc with help of a servlet filter. See also How to prevent static resources from being handled by front controller servlet which is mapped on /*. Noted should be that Spring MVC has a built in static resource servlet, so that's why you could map its front controller on / if you configure a common URL pattern for static resources in Spring. See also How to handle static content in Spring MVC?
I'd like to supplement BalusC's answer with the mapping rules and an example.
Mapping rules from Servlet 2.5 specification:
Map exact URL
Map wildcard paths
Map extensions
Map to the default servlet
In our example, there're three servlets. / is the default servlet installed by us. Tomcat installs two servlets to serve jsp and jspx. So to map http://host:port/context/hello
No exact URL servlets installed, next.
No wildcard paths servlets installed, next.
Doesn't match any extensions, next.
Map to the default servlet, return.
To map http://host:port/context/hello.jsp
No exact URL servlets installed, next.
No wildcard paths servlets installed, next.
Found extension servlet, return.
Perhaps you need to know how urls are mapped too, since I suffered 404 for hours. There are two kinds of handlers handling requests. BeanNameUrlHandlerMapping and SimpleUrlHandlerMapping. When we defined a servlet-mapping, we are using SimpleUrlHandlerMapping. One thing we need to know is these two handlers share a common property called alwaysUseFullPath which defaults to false.
false here means Spring will not use the full path to mapp a url to a controller. What does it mean? It means when you define a servlet-mapping:
<servlet-mapping>
<servlet-name>viewServlet</servlet-name>
<url-pattern>/perfix/*</url-pattern>
</servlet-mapping>
the handler will actually use the * part to find the controller. For example, the following controller will face a 404 error when you request it using /perfix/api/feature/doSomething
#Controller()
#RequestMapping("/perfix/api/feature")
public class MyController {
#RequestMapping(value = "/doSomething", method = RequestMethod.GET)
#ResponseBody
public String doSomething(HttpServletRequest request) {
....
}
}
It is a perfect match, right? But why 404. As mentioned before, default value of alwaysUseFullPath is false, which means in your request, only /api/feature/doSomething is used to find a corresponding Controller, but there is no Controller cares about that path. You need to either change your url to /perfix/perfix/api/feature/doSomething or remove perfix from MyController base #RequestingMapping.
I think Candy's answer is mostly correct. There is one small part I think otherwise.
To map host:port/context/hello.jsp
No exact URL servlets installed, next.
Found wildcard paths servlets, return.
I believe that why "/*" does not match host:port/context/hello because it treats "/hello" as a path instead of a file (since it does not have an extension).
The essential difference between /* and / is that a servlet with mapping /* will be selected before any servlet with an extension mapping (like *.html), while a servlet with mapping / will be selected only after extension mappings are considered (and will be used for any request which doesn't match anything else---it is the "default servlet").
In particular, a /* mapping will always be selected before a / mapping. Having either prevents any requests from reaching the container's own default servlet.
Either will be selected only after servlet mappings which are exact matches (like /foo/bar) and those which are path mappings longer than /* (like /foo/*). Note that the empty string mapping is an exact match for the context root (http://host:port/context/).
See Chapter 12 of the Java Servlet Specification, available in version 3.1 at http://download.oracle.com/otndocs/jcp/servlet-3_1-fr-eval-spec/index.html.

HttpHandler to download txt files (ASP.NET)?

Hey, I created a HttpHandler for downloading files from the server. It seems it is not handling anything...I put a breakpoint in the ProcessRequest, it never goes there.
public class DownloadHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
//download stuff and break point
}
}
It never stops there, as mentioned. I also registered it in the web.config.
<add verb="*" path="????" type="DownloadHandler" />
I am not sure about the path part of that entry. What do I have to enter there? I am downloading txt files, but the URL does not contain the filename, I somehow have to pass it to the handler. How would I do this? Session maybe?
Thanks
Have you read How to register Http Handlers? Are you using IIS 6 or 7?
The path part should contain a (partial) url, so if in your case you are using a static url without the filenames, you should put that there. You can end the url in the name of a non-existent resource and map that to path
e.g. the url is http://myserver.com/pages/downloadfiles
and the path="downloadfiles"
If you do POST, you can put the filename in a hidden field, and extract it in the handler. If you're using GET, I'm not sure, either cross-post the viewstate or put the filename in the session like you said.
Any reason why you can't put the filename in the url?
The path for a handler needs to be the path you are trying to handle - bit of a tautology I know but it's as simple as that. Whatever path on your site (real or much more likely virtual) you want to be handled by this handler.
Now unless the kind of file at the end of that path is normally handled by ASP.NET (e.g. .aspx, .asmx but not a .txt) ASP will never see the request in order for it to go through it's pipeline and end up at your handler. In that case you have to bind the extension type in IIS to ASP.NET.
As far as identifying what file the handler is supposed to respond with you could achieve this any number of ways - I would strongly recommend avoiding session or cookies or anything temporal and implicit. I would instead suggest using the querystring or form values, basically anything which will show up as a request header.
Fianlly, I have to ask why you're using a handler for this at all - .txt will serve just fine normally so what additional feature are you trying to implement here? There might well be a better way.

URLs for e-mailing in ASP.NET MVC

How would I generate a proper URL for an MVC application to be included in an e-mail?
This is for my registration system which is separate from my controller/action. Basically, I want to send an email verification to fire an Action on a Controller. I don't want to hardcode the URL in, I would want something like the Url property on the Views.
In your Controller, the UrlHelper is just called "Url" - so:
void Index() {
string s = this.Url.Action("Index", "Controller");
}
The "this" is unnecessary, but it tells you where this Url variable comes from
I used:
Html.BuildUrlFromExpression<AccountController>(c=>c.Confirm(Model.confirmedGUID.Value))
It is part of the HTMLHelper (I think in the MVC Futures) so you may have to pass an instance of the HTMLHelper to your service layer, not sure. I use this directly in my view which renders to an email. That gives you the absolute URL and then I store the domain (http://www.mysite.com) in the config file and append it before the URL.
You should probably make the URL part of the configuration of your application.
I know you can do stuff with e.g. the Server property on your web application, but the application will never know if its IP or domain name is reachable from the outside as it might be hidden behind a proxy or a load balancer.
If I'm reading the question correctly, you need to controller/action outside the MVC code. If so, you will need to simply configure the URL in Application Configuration or some such place, unless you have access to the controller classes and use reflection to get the names.

Resources