Actual role of WEB-INF in a java web application? - java

I am creating a web application using Java, Spring, Hibernate and AngularJS.
but I am not clearly understand the role of WEB-INF directory. As per I know WEB-INF is a web directory where we keep our web configuration files. But I have seen some example in AngularJS app where js and html are put in WEB-INF folder and it is known that WEB-INF is not publicly accessed. So why do we put those files in WEB-INF and what actually mean of publicly accessed even when we response for a request html and js are visible to clients, and if we put in WEB-INF folder these files how to access those files.
I need some clarification on these few points before starting my app development.
Please anyone can help me regarding these issues.

As you said, we put configuration files into the WEB-INF folder. But there are cases when you use resource files (e.g. HTML templates) which are not sent to the client as-is, but usually some transformations or parameter substitution happens, which are usually handled by a Servlet.
It is ok to put such templates and resources to the WEB-INF folder because the files as are should not be visible/accessible to the clients but only the result of transformations/parameter substitutions.

Resource files are frequently stored within WEB-INF because the Java servlet container will not directly serve those files. Instead, some Java controller code is being used to serve them indirectly. This is perfectly acceptable, but I would prefer a solution that serves static content from a different server and let the Java container handle dynamic code only. In a pinch, you might just add a reverse proxy and off-load static content handling that way.

In case of Spring you can build your app without WEB-INF directory. For example: spring-boot + thymeleaf, it is possible put all html, css and js files to src/main/resources/static .. so WEB-INF directory is not necessary for all java web applications.

You don't have to use WEB-INF at all.
Here's a simple AngularJS example app (official Spring guide) on how to do this.
Now, like Elliot mentions, sometimes using proxies is a good idea (depending on the kind of traffic your application should support). You could also use a CDN, which is easier to set up and has no configuration requirement in your application.

Related

Java .class files outside of WEB-INF?

I'm reading through the Java EE 7 Tutorial, and I came to the section Packaging Web Archives. I'm already familiar with the way Java web applications and WARs should be structured, but something caught my eye:
A web module has a specific structure. The top-level directory of a web module is the document root of the application. The document root is where XHTML pages, client-side classes and archives, and static web resources, such as images, are stored.
What on earth do they mean by "client-side classes"? If you put a .class file outside of WEB-INF, obviously you can download it using a web browser or other HTTP client. I suppose you could distribute a small application this way. Would these "client-side classes" have any other use?
I believe what the author is getting at is classes which will be executed on the client-side, such as the browser.

folder structure of jsp's?

I have recently started developing my own project from scratch using the Core of J2EE : Servlets & Jsps.
I could not evaluate whether my project folder structure is right or not. Here is my project folder structure.
The question: Is it a good sign to put my jsps outside of web-inf. If not, why is it so? If yes why?
Is there any standard folder structure convention for a J2EE web application, I know maven has brought up some standards but still, we can customize as per the requirement I believe.
What are the points to be considered while laying out the folder structure for a J2EE web application, importantly where should the Jsps, static content should go into & why?
All I can do is tell you the pros and cons to specific ideas. What follows is 100% my opinion. I don't know of any specific requirements or rules. I'm sure somebody will disagree with me.
JSP's
Let's work on whether to put JSP's in WEB-INF or not.
Pros of putting JSP's in WEB-INF:
You control how the JSP's are executed. If you want a JSP to be
parameterized and re-usable (which is really hard with a JSP anyway),
you can put them into WEB-INF and use a servlet or a Struts action
controller or some other front controller to do pre-processing and
then pass control to the JSP, passing in the right environment
context (like request attributes, any security checks, parameter
sanitation, etc.)
You can programmatically or even at a firewall or IDS level block
HTTP requests to *.jsp to reduce the likelihood of somebody uploading
a JSP to the web root and then being able to execute code as the web
server. They'd have to over-write an existing JSP. Not a huge
security gain, but it does make compromise slightly harder.
Enforces good habits, like MVC, front controller, servlet filters,
dependency injection, etc. as opposed to a big monstrous JSP that
does all the work itself and is difficult to read/maintain.
Cons of putting JSP's in WEB-INF:
You cannot access the page directly, even if it is a simple
standalone page which needs no upfront processing. This is because
files under /WEB-INF are not servable by a servlet container.
Static files
In terms of purely static files like HTML, image, stylesheet, javascript, etc. put those under the web root (my_app in your case), but NOT /WEB-INF (because it is not accessible).
Overall layout
As for the overall directory layout, it depends somewhat on your build process. I like storing everything under "src" or "source" because it makes it clear what files are generated by building and which are pure source files. main lets you separate test code like junit classes from your main source code, which is good too. But if you don't have any unit tests (oh no!), then it's a meaningless distinction.
On the other hand, if you don't manipulate the web root at all during build (like if it's all JSP and static files), then perhaps you keep it at the top level, like /webroot or /deploy and copy files in as needed, such as .class or .jar files. It is a habit of human beings (especially developers) to over-organize. A good sign of over-organizing is having lots of folders with only a single sub-folder.
What You've Shown
You've indicated that you are following a convention set by maven, so if you are already using maven, just stick with that layout. There is absolutely nothing wrong with the layout you described.
In case of WEB-INF,
If you put JSPs in WEB-INF then you won't be able to access them directly. i.e. By absolute url
Outside, WEB-INF you can directly access them

Design Web application

I want to build a java web application and I don't have any background how to do that.
Can you plz tell me what is the starting point to do that and where can I found useful open source codes that I can use them to design my web application.
There are many different frameworks and without more information it's difficult to know what would suit you.
http://en.wikipedia.org/wiki/Comparison_of_web_application_frameworks#Java is a good starting point.
You have to know concepts such as Servlet, Servlet Container, Application Server(such as Apache tomcat) and little information about Html.
Exist several book for this goal, my opinion is : you start by a book related to Jsp/Servlet concept, these books good explained.
Here you can learn how java web applications work and here is a very basic java web application example to get you started. I hope this helps :)
You should follow the Java EE tutorial, its Web Tier part. I think it's the fastest way to get knowledge that would allow you to understand the base concepts...
The minimal structure of a web application is the following:
/WEB-INF
/classes - stores the compiled Java classes your webapp uses
/lib - contains the additional libraries your webapp may need to run
web.xml - key file in every webapp; explained below
web files and folders (HTML/JSP/CSS/Javascript)
You may want to start out with Eclipse for Java-EE, since it automatically creates the webapp structure for you, so it's the perfect place to start learning, in my opinion; you can find it here.
After you install, the basic steps to create your web application are:
Create your project by accessing File > New > Dynamic Web Project.
Name your project, click Next, Next and check the Generate deployment descriptor checkbox. Now hit Finish.
Now that the structure is created, your main points of interest will be:
Deployment Descriptor - Is an overview of your web.xml file. Here you can declare all your servlets and their URL paths, you can point to specific error pages triggered by specific codes (e.g 404, 500) or exceptions that occur in your Java/JSP code (e.g NullPointerException, FileNotFoundException), plus do many other things to enhance your webapp. You can trigger between text and graphical XML editing in the bottom-left of the code window.
Java Resources - Here you define your Java classes and servlets. The main role of a Java class in a webapp will be to collect and process data. For example you can define your own math class that exposes methods which do basic calculations. A servlet will usually call one of these classes and output the result to the response output stream. Be sure to provide a solid project structure with the help of packages.
WebContent - this will contain all the web pages your webapp will show, including scripts, images and stylesheets. You are free to create your own folder structure in this section.
Some useful tutorials to get you started:
HTML
JSP
Servlets, Server setup
CSS
Once you're done with your webapp, you can either Run it on a server directly from Eclipse, or you can export it as a WAR file and deploy it on the server of choice, which is usually done by copying the WAR file in the webapps folder.
Finally, try to experiment with all the webapp features Eclipse exposes to you. Good luck!

Sharing JSPs between EARs

Is it possible to share JSPs between EARs, similar to the way that we can share Java files between EARs by using .jar files?
I have a large J2EE app on JBoss with many different EARs, and they all should have the same header, footer, etc... I would rather not copy and paste these files a dozen times whenever a change needs to be made.
Tag files can be packaged in a jar.
They are JSP files with a ".tag" extension. They can be parameterized.
I have never tried but logically speaking you can very well do it by putting all your JSP's into a common folder
I think of it as accessing a different servlet context from the one you are in. Something like
Enterprise.ear
WAR1 /somewhere
WAR2 /somewhereElse
WAR3 /shared
Assuming a JSP in WAR1 bound to /somewhere:
Reference the shared context with the optional 'context' attribute of the c:import tag (Standard JSTL tag). By default c:import uses the context it is in, which in war1 is /somewhwere.
<c:import url="/header.jsp" context="/shared"/>
There are probably other ways... Perhaps just ignore your ear and just go with a full http request:
<c:import url="http://www.somewhere.com/header.jsp"/>
I'm not certain on the syntax of the context attribute on the c:import tag. But I believe that is the correct syntax (with the slash verse without, it might not matter).
Use sitemesh.
There is no need to change anything in the existing application. Create a fresh war with sitemesh. It can decorate content from multiple urls dynamically.
http://raibledesigns.com/rd/entry/use_sitemesh_to_decorate_multiple
--Kiran.kumar

Tomcat parent webapp shared by configurable children webapps

Currently, we support many clients using the same web app, but each client has a different configuration for accessing their database, setting files etc. As the client list grows, updating the web apps is becoming increasingly arduous, and the duplication of resources is a waste of memory, file space, etc..
What we'd like to do is have a parent web app which is shared by all children web apps. Then have each child web app carry only files specific to them. When the child web app starts up, Tomcat loads the web app from the parent web app and then overrides any files defined in the child web app following an identical package structure.
We've been googling around and haven't found a ready or complete solution. Solutions we've looked at:
Tomcat common/share - could handle class and JAR files, but we don't see a way to handle static and JSP resources residing above the WEB-INF dir.
CATALINA_BASE appears to be more suited for running multiple instances of Tomcat which we'd rather avoid
A Maven possible solution, but we are not big fans of Maven, so would rather avoid it also.
Anybody have suggestions or ideas on how to solve this? If Tomcat configuration is not possible, what about a different application server (such as Glassfish) or a tool for doing dynamic file updated (such as OSGi, rsync). Would like to remove the resource duplication if possible.
Thank you.
There is no such thing as "parent" or "child" webapps. It's not part of J2EE spec and AFAIK it's not supported by any application server.
That said, your problem is twofold:
1) Having shared resources. This part is pretty easy assuming "resources" means static resources (images / CSS / javascript / etc...).
If they are truly shared (e.g. you don't need to have a separate version in some of your webapps), host them elsewhere (separate "common" webapp or put Apache in front of your Tomcat and host them there.
If you do need to have "local" versions of some of those resources you may be able to do some clever conditional URL rewriting or simply write a servlet that would check whether particular resource exists locally and, if not, take it from "common" location.
Precompile your JSPs so you only have to deal with JARs.
If your Tomcat instance only hosts your apps, you can indeed put your JARs in shared (or lib in the latest version); otherwise you can deploy them with each application .
2) Simplifying deployment. I'm not really sure what the big problem is here... It's rather trivial to write an Ant (batch, shell, what have you) script that would assemble and deploy WARs based on "common" and "per-app" directory structures.
Alternatively, you may want to take a look at using JNDI to severely reduce the number of files that have to be deployed (in theory, to a single context.xml for each application).
You can build parent-child hierarchy if you use Spring at your web-apps - Using a shared parent application context in a multi-war Spring application.
I.e. you can define all shared stuff at the 'parent' context and have 'child' contexts just to use it.
If all you had was setting file and configuration changes you could manage these through the context.xml and then you can point the docBase of each application context at a common directory for all the applications to share the same source.
the drawback to this is changes to the application will require a tomcat restart.
This does not however solve your problem if you want to override logic.
A option that I am exploring for a similar scenario is to move the client custom portion into ajax widgets / gadgets. Then have it be part of the configuration files to tell the application which version of the gadget to pull for which client.
you can review documentation for having applications share a docbase here http://tomcat.apache.org/tomcat-5.5-doc/config/context.html

Categories

Resources