Accessing Tomcat Context Path from Servlet - java

In my Servlet I would like to access the root of the context so that I can do some JavaScript minifying.
It would be possible to do the minify as part of the install process but I would like to do it on Servlet startup to reduce the implementation cost.
Does anyone know of a method for getting the context directory so that I can load and write files to disk?

This should give you the real path that you can use to extract / edit files.
Javadoc Link
We're doing something similar in a context listener.
public class MyServlet extends HttpServlet {
public void init(final ServletConfig config) {
final String context = config.getServletContext().getRealPath("/");
...
}
...
}

In my Servlet I would like to access the root of the context so that I can do some JavaScript minifying
You can also access the files in the WebContent by ServletContext#getResource(). So if your JS file is for example located at WebContent/js/file.js then you can use the following in your Servlet to get a File handle of it:
File file = new File(getServletContext().getResource("/js/file.js").getFile());
or to get an InputStream:
InputStream input = getServletContext().getResourceAsStream("/js/file.js");
That said, how often do you need to minify JS files? I have never seen the need for request-based minifying, it would only unnecessarily add much overhead. You probably want to do it only once during application's startup. If so, then using a Servlet for this is a bad idea. Better use ServletContextListener and do your thing on contextInitialized().

I was googling the result and getting no where. In JSP pages that need to use Java Script to access the current contextPath it is actually quite easy.
Just put the following lines into your html head inside a script block.
// set up a global java script variable to access the context path
var contextPath = "${request.contextPath}"

Do you mean:
public class MyServlet extends HttpServlet {
public void init(final ServletConfig config) {
final String context = config.getServletContext();
...
}
...
}
Or something more complex?

Related

HttpServletRequest & HttpServletResponse , how to access in a class library in java

I have a class library project , in which i need to access session and cookies .
So I am trying to use like
public WebContext getContext(){
WebContext ctx = null;
ctx = WebContextFactory.get();
return ctx;
}
But all i get is null in WebContextFactory.get() this statement .
This class library is added to JSP project which invoke this method from a servlet.
I am new to JAVA , so cannot think of much options.
Answear taken from WebContextFactory.get() always returns null
The problem is this when a request comes in for DWR, it's handled by the dwr servlet/controller which sets the proper info inside the WebContext to use in that request (ThreadLocal as said below). If you are accessing WebContext outside a normal DWR request, the WebContext isn't setup for > that thread so it's empty.
There were a few messages in the forum about this same issue, but I don't remember the details. At any rate, you should try to use the ServerContextFactory instead of the WebContextFactory if you're going to access DWR from a non-DWR request. It might be what you need.
See if this helps you get to bottom of the problem.

Serving static content from Spring boot results in 404 whitelabel error page

I have a question regarding Spring boot. I'd like to serve static content, and I have made a ResourceHandler in my configuration:
#Configuration
public class WebApplicationConfig extends WebMvcConfigurerAdapter {
private static final Logger LOG = LoggerFactory.getLogger(WebApplicationConfig.class);
#Bean
public FileSystem fileSystem() {
FileSystem fileSystem = new LocalFileSystem();
return fileSystem;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
LOG.info("Serving static content from " + fileSystem().getBaseFolder());
registry.addResourceHandler("/static/storage/**").addResourceLocations("file:///" + fileSystem().getBaseFolder());
super.addResourceHandlers(registry);
}
}
My application runs in a Docker container and I mounted the host' volume /myapplication/storage. When I ssh into my Docker container, I see that this volume is present and that reflects the fileSystem().getBaseFolder()-call. This directory is also writable, but it is outside my project.
The LOG statement is executed:
"Serving static content from /myapplication/storage", so I know this code is being executed as well.
Further information that can be relevant is:
It is a Linux environment.
Write permissions are correct for that folder.
Folder exists and is writable and readable.
I have a couple of #RestController's annotated. All the methods in there start with #RequestMapping("/api/"), so there is no mapping that starts with /static.
Already dropped off the /// in front of file:, but without any effect.
Does anyone know how do I make those files in that folder readable. It is always returning a 404. The folder must be outside of the project, so don't suggest to put it into /resources/static.
Any help is appreciated.
Ok, I made a beginners mistake. As #chrylis mentioned in the comments, I removed the /// in front of file:. I did some test runs, and as it appeared, I had the following entry in my application.properties: myapplication.picture.basefolder=/myapplication/storage. It missed a trailing slash. So I updated it to myapplication.picture.basefolder=/myapplication/storage/, and my problem was fixed.

Simple servlet with annotations in java (image folder)

i have a folder with images on webContent/images.
I Just wanna to know how to provide this folder on the web.
In my project i have just one servlet with annotations:
#WebServlet(urlPatterns = { "/" })
public class IndexCtrl extends HttpServlet {
Every time i try to get a image this servlet get priority and send a index page.
How can I provide images folder on the web?
What I'm doing wrong?
Just don't map the servlet to /. That makes it the default servlet, which catches all the requests. Map it to the URL it must handle (like /index.html for example).

How do I get real path of a folder inside static block of a class

I have a web app and I need to get absolute path of a folder (in my case, WEB-INF) in a static block of a class which is not a servlet. Of course, I could take this value from properties file but can I do this otherwise?
You can use the getRealPath() method of the ServletContext ServletContext.getRealPath to find out the actual folder in your filesystem like
String realPathOfImgFolder=req.getServletContext().getRealPath("/foldername");
You may not get the WEB-INF folder name like this because it is not in the servlet context's exposed directories, you may have to do something like this for it
String rootPath=req.getServletContext().getRealPath("/");
File webInfFolder=new File(rootPath,"WEB-INF");
[EDIT] If you dont have the request object, then you will have to use a ServletContextListener and use its contextInitialized(ServletContextEvent sce) method to grab the ServletContext and store the path into the application scope for retrieving it later.

How do I get URLs of other servlets from within a servlet

I have two servlets (S1 and S2). S1 renders a HTML-Page which acces S2 via an URL (img src="URL"). I know the servlet name of S2, but not the URL. The URL is configured in the web.xml of course, but how can I access that from S1?
Use:
HttpServletResponse.encodeURL(String)
Which in your case should be something like this:
response.encodeURL("/S2");
This method will take care of any URL re-writing that needs to take place to maintain session state and I think will prepend the necessary path info to the URL.
I use JSTL these days so this I'm a little rusty on that last point but if the path info isn't prepended you can get it from the request and add it yourself.
I would guess, that most implementations of the ServletConfig hold that mapping informations (org.apache.catalina.core.StandardWrapper does), but since the ServletConfig-Interface don't provides a getter, you'll have to do some tricks to get it and would bind your application to a specific implementation or application server.
Maybe you just read it from the web.xml. Just select all "servlet-mapping" Elements with the given "servlet-name" and read the "url-pattern". Since this is in the spec, that should work on ever app server out there.
EDIT:
Here is the dirty example. Getting the URL mappings using refelction:
#Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
try {
Class<?> clazz = config.getClass();
Field configField = clazz.getDeclaredField("config");
configField.setAccessible(true);
StandardWrapper standardWrapper = (StandardWrapper) configField.get(config);
clazz = standardWrapper.getClass();
Field mappingsField = clazz.getDeclaredField("mappings");
mappingsField.setAccessible(true);
List<?> mappings = (List<?>) mappingsField.get(standardWrapper);
System.out.println(mappings);
}catch (Exception e) {
logger.error("", e);
}
}
That works in my JSF, Tomcat environment. The config Object is "org.apache.catalina.core.StandardWrapperFacade" and has a field called "config" which hold a "org.apache.catalina.core.StandardWrapper", which has a field called "mappings".
But as I said, this is a dirty hack!
Perhaps you should supply the URL of the second servlet to the first as a servlet parameter. I realise this means encoding the URL twice in the web.xml (which I really abhor), but to avoid problems you can always build the web.xml as part of your build, and populate from a properties file.
A little bit nasty and fiddly, I appreciate, but in the absence of any cross-container API solution, perhaps it's the most pragmatic solution.
You can do it easily in your doGet() or doPost() Method following is the code to be written in doGet() or doPost() metod of servlet to get the mapping associated with a servlet.
public void doGet(HttpServletRequest request,HttpServletResponse response){
String nameOfServlet = "S2";
ServletContext context = getServletContext();
String[] mappinggs=context.getServletRegistration(nameOfServlet).getMappings().toArray();
//mappings will contain all the mappings associated with servlet "S2"
//print take the first one if there is only one mapping
System.out.println(mappings[0]);
}

Categories

Resources