customize web application root context in apache - java

I have web application abc.war and I want to deploy it on Apache Tomcat.
The problem is that, by default, the path to this application is http://<server-name>/abc
but I want to access it as http://<server-name>/xyz.
I put into WAR's META-INF folder the file context.xml that is :
<Context path="/xyz" docBase="abc" override="true" />
The application WAR abc.war is located under %CATALINA_HOME%\webapps and it is extracted to %CATALINA_HOME%\webapps\abc folder.
Also, while deployment, the file context.xml from abc/META-INF is copied to %CATALINA_HOME%\conf\Catalina\localhost as abc.xml
It seems that this should work, but I still can't access my application through http://<server-name>/xyz, but only through http://<server-name>/abc
In addition, I still see in apache log the following line while deployment of abc.war :
context path = /abc
Could anybody, please, help while this doesn't work, or tell if there is any way of deploying of web application on apache such that application could be accessed by customized path (that does not relate to war-file name) ?
Thanks in advance.

Take a look at the docs:
The context path of this web application, which is matched against the beginning of each request URI to select the appropriate web application for processing. All of the context paths within a particular Host must be unique. If you specify a context path of an empty string (""), you are defining the default web application for this Host, which will process all requests not assigned to other Contexts.
The value of this field must not be set except when statically defining a Context in server.xml, as it will be inferred from the filenames used for either the .xml context file or the docBase.

Related

Tomcat set application context using configuration (not war name)

My question is this - Say I have a war file called my-app-123.war. I want to deploy it on a Tomcat server (9.0.x), let it auto unpack.
The application would then be accessible by http://localhost:8080/my-app-123
Is there a way, without renaming the war file, to make the application accessible from http://localhost:8080/my-app?
I will preface this by saying I realize the easiest solution is to just name the war file. I'm curious if there is a way to do this in Tomcat configurations.
I did do this already (inside the host section of my server.xml file):
<Context path="/my-app" docBase="my-app-123"></Context>
But I read this online (https://tomcat.apache.org/tomcat-7.0-doc/config/context.html) in the path variable description:
Even when statically defining a Context in server.xml, this attribute must not be set unless either the docBase is not located under the Host's appBase or both deployOnStartup and autoDeploy are false. If this rule is not followed, double deployment is likely to result.
And I can access the app now at http://localhost:8080/my-app and http://localhost:8080/my-app-123, which isn't a real solution.
The following works for Tomcat deployments I have used - there are no double-deployment issues.
In the example I will use here, I have a simple "hello world" webapp in TomcatDemo-1.0-SNAPSHOT.war. It is deployed on Tomcat 9.0 in the standard location (webapps directory).
I want the application's context path to be /my-foo-app.
I use the following context entry in server.xml:
<Context path="/my-foo-app" docBase="TomcatDemo-1.0-SNAPSHOT.war"></Context>
I also use the following in server.xml:
<Host name="localhost"
appBase="webapps"
deployOnStartup="true"
deployIgnore="TomcatDemo-1.0-SNAPSHOT.war"
unpackWARs="true"
autoDeploy="false">
The important item here is deployIgnore. It is described here:
https://tomcat.apache.org/tomcat-9.0-doc/config/host.html#Automatic_Application_Deployment
When using automatic deployment, the docBase defined by an XML Context file should be outside of the appBase directory. If this is not the case, difficulties may be experienced deploying the web application or the application may be deployed twice. The deployIgnore attribute can be used to avoid this situation.
Alternatively, if you don't mind about automatic start-up deployments, you can set deployOnStartup="false" - in which case you don't need deployIgnore.
In these scenarios, the web app is available only here:
http://localhost:8080/my-foo-app/ <-- OK
Otherwise, as you note, with double-deployment the web app would also be available here (and you would see two exploded directories in webapps):
http://localhost:8080/TomcatDemo-1.0-SNAPSHOT/ <-- BAD!
Hope that helps.
Finally, it can get a little complicated, with all the various auto-deployment options. This page provides a set of summary tables and explanations:
https://tomcat.apache.org/tomcat-9.0-doc/config/automatic-deployment.html

How to set up Tomcat to use the config file in conf/Catalina/localhost?

so my question is how can I set up a Tomcat Server to use this configuration file conf/Catalina/localhost/MyApp.xml?
It works like a charm if my application is named like this: MyApp.war so tomcat will extract the archive to MyApp.
But I want to use a name with the version inside like MyApp##1.0-SNAPSHOT.war.
Is it possible to configure the tomcat so it will use the MyApp.xml anyway?
You can set path and docBase attributes of Context element as described in the docs.
Create a directory outside $CATALINA_HOME/webapps and place war files there, let's say /opt/tomcat/wars/. Then set docBaseattribute to the full path to your war. Make user tomcat user has read permissions on that directory. If war is inside webapps directory you could end up with a double deployment depending on deployOnStartup and autoDeploy attributes of Host element.
<Context path="/MyApp" docBase="/opt/tomcat/wars/MyApp##1.0-SNAPSHOT.war">
...
</Context>
You can try also naming the xml the same as the war file.

Where is Spring MVC context path set?

I am not sure how context path is set.
When I rename my .war file in tomcat on autodeploy, the web page goes to localhost:8080/newDirectory as expected, however for some reason wherever there's a call to pageContext.request.contextPath in a Spring based page, it still returns the old context path.
I tried to override the context path by setting:
<context path="/newDirectory" docBase="appName" override="true"></context>
in server.xml but it doesn't work.
My question is, where does Spring read its context path from? I used Maven and I did see there's a
<appContext>/${project.artifactId}</appContext>
in the pom.xml, does this mean I need to rename the artifactId to newDirectory ?
I have also tried adding that <context path="/newDirectory"...> in /META-INF/context.xml (which now I know will be ignored anyway due to my server.xml changes).
Thanks in advance for your answer.
It not depends on Spring maybe you are using a maven plugin to build your war that reads the appContext property. You can read about definig ServletContext in this thread.
Every PageRequest will get current HttpServletRequest object and get context path of current request and append your .jsp (that will work even if the context-path this resource is accessed at changes).
Eg,
if you have war file as MyCompany.war and having a page with ${pageContext.request.contextPath}/MyJspPage.jsp.
Then your context path is http://abc/MyCompany and it works as http://abc/MyCompany/MyJspPage.jsp.
Suppose if you change your war file as OurCompany.war,
then your context path changes to http://abc/OurCompany and Jsp will work as http://abc/OurCompany/MyJspPage.jsp.
It means context path will change automatically to name of the application(War file name) with out any changes.
In your case,after renaming war file name with newDirectory,your webserver will deploy newDirectory application but still newDirectory application exist in the web server.I think you should delete old application from webapp and then check by reloading your newDirectory application.

Tomcat: Get short URL for Jersey based Rest Service

I have a Jersey based Rest service running on a tomcat server. There is no UI, just a server that offers some rest services. Now, to access this service the URL that i have to type in is pretty long. Something like localhost:8080/MyApp/url_pattern/classPath/method where MyApp is the webapp that i deployed, url_pattern is the pattern that i defined in the servlet-mapping in web.xml, classPath and method being the #Path annotations for the Class and method respectively. Is it possible to shorten it such that I get rid of the MyApp and url_pattern part of this URL. Something like localhost:8080/classPath/method.
PS: There is just one webApp running on this server, so no point having the MyApp part
I don't think you can remove all what you desire from the url but you can definitely remove the MyApp part by making it the root application for tomcat.
Answer on this related link describes it pretty well, how to set your application as the root application. So you can access your REST services without having the app name in url:
Setting default application in tomcat 7
Content copied from the above link:
First Method:
first shutdown your tomcat [from the bin directory (sh shutdown.sh)]
then you must delete all the content of your tomcat webapps folder (rm
-fr *) then rename your WAR file to ROOT.war finally start your tomcat [from the bin directory (sh startup.sh)]
Second Method:
leave your war file in CATALINA_BASE/webapps, under its original name
- turn off autoDeploy and deployOnStartup in your Host element in the server.xml file. explicitly define all application Contexts in
server.xml, specifying both path and docBase. You must do this,
because you have disabled all the Tomcat auto-deploy mechanisms, and
Tomcat will not deploy your applications anymore unless it finds their
Context in the server.xml.
Note:
that this last method also implies that in order to make any change to
any application, you will have to stop and restart Tomcat.
Third Method:
Place your war file outside of CATALINA_BASE/webapps (it must be
outside to prevent double deployment). - Place a context file named
ROOT.xml in CATALINA_BASE/conf//. The single element in this context
file MUST have a docBase attribute pointing to the location of your
war file. The path element should not be set - it is derived from the
name of the .xml file, in this case ROOT.xml. See the Context
Container above for details.

Traverse Deployed Folder from the Web Application

Is it possible for a web application to access its own deployed folder. I am using JSF 1.2 framework and i need to access some of the files which i have it in the deployed directory.
Does JSF has any in built method to give us the deployed folder and the files in it?
Use ExternalContext.getResourcePaths("/"). In a servlet container, this will delegate to ServletContext.getResoucePaths(String). As the documentation notes:
For example, for a web application
containing:
/welcome.html
/catalog/index.html
/catalog/products.html
/catalog/offers/books.html
/catalog/offers/music.html
/customer/login.jsp
/WEB-INF/web.xml
/WEB-INF/classes/com.acme.OrderServlet.class
/WEB-INF/lib/catalog.jar!/META-INF/resources/catalog/moreOffers/books.html
getResourcePaths("/") would return
{"/welcome.html", "/catalog/",
"/customer/", "/WEB-INF/"}, and
getResourcePaths("/catalog/") would
return {"/catalog/index.html",
"/catalog/products.html",
"/catalog/offers/",
"/catalog/moreOffers/"}.
For portable code, do not assume you can access resources via the file system:
This method (getResource(String)) allows the servlet container to make a resource available to servlets from any source. Resources can be located on a local or remote file system, in a database, or in a .war file.
You can get access to resources in the classpath, but the servlet API does not guarantee their physical representation. In other words, if you deploy a WAR file, the container may explode the WAR file or keep it as is, or do something completely different depending on its needs.
In this particular context it mean that you introduce a subtle container dependency by assuming that a web application is deployed to a folder, which you should be very careful about.
If all you need, however, is to get some items you have in the classpath you should have a look at this question: Getting the inputstream from a classpath resource (XML file)
FacesContext.getCurrentInstance().getExternalContext().getResource("/").toString();
you will get the path to your WEB-INF/classes dir traverse using parent(); method from File class to get the location

Categories

Resources