Static index.html file - is servlet container being hit first? - java

In appengine, is index.html served as a static file or there's a servlet container involved first?
For example, lets assume I have the blabla.com host, war/index.html and a user goes to http:/blbla.com/
I don't want a servlet container being hit first in order to determine that it's part of welocme-file-list configured in web.xml and only then appengine will serve it as a static file. Is the only way to avoid server roundtrip is to have a user hit the url http://blabla.com/index.html ?
As per docs https://developers.google.com/appengine/docs/java/gettingstarted/staticfiles say:
By default, App Engine makes all files in the WAR available as static files except JSPs and files in WEB-INF/. Any request for a URL whose path matches a static file serves the file directly to the browser—even if the path also matches a servlet or filter mapping.
So now the question: Which of the following is true If I have specified "index.html" in welcome-file-list and user hits http://blabla.com
appengine knows that it has to servle index.html directly as a static file and my servlet container is not bothered checking welcome-files-list.
appengine doesn't know that it has to serve index.html from static files and my servlet container gets hit just to only check welcome-files-list and then allows appengine to fetch it as a static file.
In case of 2: the only way to have html files served as a static files is having users hit them directly in url, i.e http://blabla.com/index.html?
This is very important moment because it means that your servlet container may be doing additional job of resolving welcome-files-list on every request time which results in wasted cpu which could be avoided should users have specified direct path to the html files.

By default, App Engine makes all files in the WAR available as static files except JSPs and files in WEB-INF/. Any request for a URL whose path matches a static file serves the file directly to the browser—even if the path also matches a servlet or filter mapping. You can configure which files App Engine treats as static files using the appengine-web.xml file.
But you cannot set as static file the url "/".
See the documentation.

Related

What's the appropriate directory structure for a spring boot web app so that the home page automatically opens when the program is run?

I've created this project through Spring Boot. It's a full stack web app that takes information from a user, validates it, sanitizes it, authorizes it, and then sends it to a database. It also can retrieve data from a database.
The problem is that, when the project runs, it should open the home page automatically. Instead, I have to navigate to it manually through a browser, resulting in Access Control Allow Origin issues (as it appears that AJAX is being sent cross origin).
My current directory structure is like this:
C:\Users\workspace\Repository\Project\src\main\resources\templates
Within this templates folder, I have my webpages and config folders. These config folders contain the Javascript files.
I've looked at other projects I've created, and directory structure is very different, but they all use jsps. They look like this:
C:\Users\workspace\CapstoneProject\src\main\webapp\jsp
This directory has all the jsps in it, and they start with the project.
What is the appropriate directory structure so that they start with the project? I've googled this and looked on Spring's website but have found nothing.
The location is less important and it depends on your ant/maven/gradle/script of building your artifact for example War file which it should be copied to webapps folder and then folder for resource type as jsp/css/js/html
Static resources as html can be outside your war in a separate resource folder.
According to tomcat it depends on your size of the application:
*.html, *.jsp, etc. - The HTML and JSP pages, along with other files that must be visible to the client browser (such as JavaScript,
stylesheet files, and images) for your application. In larger
applications you may choose to divide these files into a subdirectory
hierarchy, but for smaller apps, it is generally much simpler to
maintain only a single directory for these files.

Java Servlet - Mapping a servlet to every URL but a string

I have a servlet configured to handle all URLs (*):
<servlet>
<servlet-name>MyServ</servlet-name>
<servlet-class>MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyServ</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
I need that for URLS beginning with /static/, it should serve them from the static WEB-INF. That is, MyServ should serve everything but /static.
How can I do that?
UPDATE: To clarify, what I'd like is:
/*/ - Goes to MyServ
/static/dir/file.css - Jetty serves the static file.css from the /dir/.
I'm not sure what web.xml to do, or where to put the static files.
I tried adding this:
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/static/*</url-pattern>
</servlet-mapping>
But, when I go to a /static/ URL, I just get:
HTTP ERROR 404
Problem accessing /static/dir/file.css. Reason:
Not Found
Powered by Jetty://
I'm not sure if my web.xml is wrong, or if I'm simply putting the files in the wrong place (I've tried under src/main/webapp and src/main/webapp/lib/META-INF/resources/)
Jetty
I am using Jetty. I want to avoid any other layers, such as Nginx, Apache, etc.
To win the bounty, please make sure you answer works for Jetty.
Your best bet is probably to have a rule for static that occurs before the rule for *.
Rule for URL path mapping:
It is used in the following order. First successful match is used with no further attempts.
The container will try to find an exact match of the path of the request to the path of the servlet. A successful match selects the servlet.
The container will recursively try to match the longest path-prefix. This is done by stepping down the path tree a directory at a time, using the ’/’ character as a path separator. The longest match determines the servlet selected.
If the last segment in the URL path contains an extension (e.g. .jsp), the servlet container will try to match a servlet that handles requests for the extension. An extension is defined as the part of the last segment after the last ’.’ character.
If neither of the previous three rules result in a servlet match, the container will attempt to serve content appropriate for the resource requested. If a “default” servlet is defined for the application, it will be used.
So it will match the rule for /static/, and stop there.
Your problem can by solved using the Nginx. Nginx serves static content HTML files, images (.jpg, .png, .gif), stylesheets (.css) and JavaScript (.js). These files need not to be processed by the web server. Nginx will do this job.
server {
listen 80;
server_name YOUR_DOMAIN;
root /PATH/TO/YOUR/WEB/APPLICATION;
location / {
index index.jsp;
}
location ~ \.jsp$ {
proxy_pass http://localhost:8080;
}
location ^~/servlets/* {
proxy_pass http://localhost:8080;
}
}
To serve static content you dont even need to have a servlet. You can put your static content in a folder which is directly accessible through your server.
For example if your application name is TestApp than you can place your content in TestApp/static/dir directory. Based on that your directory structure would be :
TestApp
|
|_____ WEB-INF
|
|_____ static
|
|____ dir
By doing above directory structure all your static content e.g. Sample.css will be accessible through below URL:
/TestApp/static/dir/Sample.css
Please look at this question for more information How to serve static content from tomcat
Note that by doing this your static directory will be open to everyone without any restriction which means anyone will be able to access your static content without any authentication. But as its your static content I guess its fine unless you have any reason for it.
First, files that are located in "WEB-INF" directory aren't directly web accessible.
Also, I noticed that your entry "src/main/webapp/lib/META-INF/resources/" does not include a extracted WAR directory, aka web application folder.
Example:
src/main/webapp/[WAR folder]/lib/META-INF/resources/
I assumed that you are using Tomcat. So, after you create your WAR file drop it into "webapp" directory, then start Tomcat. The WAR file should extract into a web application folder of the same name as the WAR file. Now from a browser you should has access to any files outside of "WEB-INF".
example: localhost:8080/[web app folder name]/[some file]
Hope this helps,
Simply put your static content into webapp Directory.
That part can be directly access. using localhost:port/yourAppName/ResourceName
Based on my experience (as already suggested by Srinivasu Talluri), reverse proxy is the answer to your problem.
You could use Nginx See detail configuration or configure Apache to work as reverse proxy.
Detail configuration for serving static content thru Nginx could be find here
When static contents will be handled by the web server itself, then your servlet configuration could be used as is. Thus your servlet will serve only the dynamic resources.
Hope it helps.

Use Spring 3 filters to embed timestamp in resource paths?

Would it work to setup some filters using Spring 3 MVC where the paths for javascript files and css files are modified when streamed to the client, by embedding some timestamp in the filename. And then when those resources are later requested another filter then strips those timestamps out?
This would be an attempt to prevent problems of cached js/css files when an application is redeployed
What would I need to do to set this up? How do I setup the filter to replace the paths with a timestamp and then how to I setup the filter to later strp the timestamps out?
I just need info on the Spring 3 MVC configuration for it in the web.xml, I am ok with what the actual code in the filter will need to do
It may be simpler to use Spring's resource mapping <mvc:resources>, that maps a virtual path to the real location of your CSS and Javascript files. The virtual path can contain the version of your application. This means that when you deploy a new version of your application, the path of the CSS and Javascript that gets sent to the browser is different than before and this fools the browser into thinking that they're new resources - and so it reloads them.
For example to map CSS and Javascript files in /resources:
<mvc:resources location="/resources" mapping="/resources-1.2.0/**"/>
This says that any request that comes in with the URL pattern /resources-1.2.0 followed by anything (e.g. /resources-1.2.0/css/styles.css), look for the file in the folder named resources in the web root.
When you update the application version between deployments the virtual path to the CSS and Javascript resources will change and so browsers will be forced to reload the files - even though the real files are in the same old location.
You can make the application version dynamic too - so you don't need to modify your config file.
There's a more in-depth write up of this whole approach here.

Servlet Generated Web Pages Finding Images Inside Of A *.war?

I'm maintaining a legacy Java servlet webapp ( nwp ). My goal is to learn Spring and gradually update the webapp to use Spring as much as possible.
The servlet webapp, nwp, now runs on WebLogic 9.2. It is packaged and deployed as nwp.war. Every HTTP Request gets submitted to a unique servlet, which process the request and prints out a web page/screen. Each servlet will read in various resource files from a remote location outside of nwp.war to use for headers, footers, etc.
Yes, it is primative, which is why I want to update it. It also made sense to have the "include files" in a remote location outside of the war as 3 applications use those files. However, as part of updating the nwp app I plan on consolidating the other two ( similarly primative ) apps into just the nwp. Eventually.
As a first step in converting this application to Spring I have rearranged the directory tree to have these subdirectories under the WEB-INF dir:
images
js
css
The servlet generated HTML references images as
"
My problem is that right now the servlet generated HTML can not find images in the WEB-INF/images directory inside of the nwp.war.
Right now, the nwp.war file contains a file called weblogic.xml to map the URLs for images to where they sit on the server:
<wls:virtual-directory-mapping>
<wls:local-path>/common/resources/images</wls:local-path>
<wls:url-pattern>/images/*</wls:url-pattern>
<wls:url-pattern>*.jpg</wls:url-pattern>
<wls:url-pattern>*.gif</wls:url-pattern>
</wls:virtual-directory-mapping>
I'm new to WebLogic and WebLogic 9.2.
I've tried changing that mapping in a number of was so that the servlet generated HTML will look for the pictures in the WEB-INF/images directory inside of the war.
Is this (servlet generated html finding images ) even possible or am I going to have to use the current system of getting images until I can convert the servlets into JSPs?
Thanks
Steve
The HTML won't be able to directly reference images inside the WEB-INF folder. This is for security. So you have 2 options:
Move the images so that they're directly under / rather than /WEB-INF/
Create another servlet to serve those images
If you decide to use a servlet, you can use ServletContext getResourceAsStream to access images from the /WEB-INF/images directory. For example:
servletContext.getResourceAsStream("/WEB-INF/images/test.jpg");

How to publish non-Java resources generated at runtime on a Tomcat server?

I have a Java webapp running on Tomcat.
At runtime, I create images files that I want to be publicly published on the tomcat server.
1/ How can I get the local URL where I want to copy my image files? (ie /mylocalpath/to/where/i/should/store/the/file/)
2/ How can I know the URL where other machines can access this public files? (ie http://mydomainname/myapp/myresource.png)
Keep the path in a servlet init-param, a JNDI string, or in a property file. (Or whatever is provided by your framework that allows simple configuration.)
Create a servlet/action/controller/etc. that's mapped to a known URL. Either pass in a param with the filename or make the filename part of the URL. Stream the contents of the file back to the user. (Search for "image servlet" for examples.)
Bear in mind the mime type of the file and set the appropriate header. If necessary, check if the requesting user has access to the file in question. (There are several ways to implement that.)
I've figured a much simpler way to do this (which may sound obvious to Tomcat experts but useful to others).
In Tomcat 6 "server.xml" file, I've added this line in the <Host> element :
<Context docBase="/mylocalpath/to/where/i/should/store/the/file" path="/uploads" />
Then, when i create my resource i copy it in this local directory and figure out the public URL pretty easily : http://myserver/uploads/myfilename
Hope it can help other people.
(I even think the context can be defined in a context.xml included in the WAR rather than in Tomcat's global configuration but a global definition was enough for my needs).

Categories