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
Related
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.
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!
Due project requirements, I need to create a webapp that, when executing, will allow some users to upload zip files which are like small apps and will contain .class files, resources (images, css, js, ...) and even lib files. That zip file is almost like a war file.
Any way to code it easily? AFAIK I think I know how to code the custom ClassLoader to load classes from inside the zip file ( Java - Custom ClassLoader - trying to load a class using class file full path ) and even code the resource retrieval when requested by the browser but no idea of how to execute JSP files which will be inside the zip file or load the jar lib files inside the zip file.
EDIT: the webapp must manage applications loaded, there is no way to implement this as answered below because the webapps need the "master" webapp to live. Also that "master" webapp allows versioning of applications. The user will be able to upload a new version and upgrade to it and even do a downgrade if the new version starts to fail.
There is no easy way to do this. It's a lot of work. Classloaders are very finicky beasts. Arguably the bulk of the work of creating something like Tomcat is wrangling the class loaders, the rest is just configuration. And even after all these years, we still have problems.
Tomcat, for example, is very aggressive on how it tries to unload existing webapps, using internal information of the Java class libraries to try and hunt down places for class loader leaks, etc. And despite their efforts, there's still problems.
The latest version of Glassfish has (or will have) the ability to version application deployments. You might have good luck simply hacking on Tomcats internal routing and mapping code to manage versioning.
If you're running an EJB container, you could put your core services in the EJBs and let the WARs talk to them (you could do this with web services in a generic servlet container, but many EJB containers can convert Remote semantics in to Local semantics for calls in to the same container).
You can also look at OSGI. That's another real pain to manage, but it might have enough granularity to even give you versioning, but none of your users will want to use it. Did I mention it's a real pain to manage? We do this for dynamic loading of web content and logic, but we don't version this.
If you must have everything under control of a single WAR, then your best bet is to punt on Java and instead use a scripting language. You tend to have a bit more control over the runtime of scripting environment, particularly if you DON'T let them access arbitrary Java classes.
With this you can upload whatever payload you want, handle all of the dispatch yourself to static resources and logic (which means you get to handle the versioning aspect). Use something like Velocity for your "JSP" pages, and then use Javascript or whatever for logic.
The versioned environment can be pain to pull off. If you don't care about doing it atomically, it's obviously easier. If you can afford "down time" (bring v1 offline then bring up v2), it's a lot easier. If you're uploading the full contents of each version, it's really easy. My system allowed incremental changes and had copy-on-write semantics, so it was a lot harder. But I didn't really want to upload several Gb of media for each version.
The basic takeaway is that when dealing with Classloaders, there be dragons -- nothing is easy with those and there are alternatives that actually get code in to production rather than creating scars and pissed off dragons. Using a scripting language simplifies that immensely. All the rest is dispatch, and that can be done with a filter or servlet.
You WILL get the great joy of reimplementing a solid chunk of the HTTP protocol doing this, that's always a treat as well since the servlet container doesn't really expose that functionality to you. That is, you'll want to do that if you want to be a good citizen on the web. You could always just continually shove content down the clients throat, caching and proxies be damned.
You could manually create a WAR-like structures inside your web container webapps directory and put classes, JARs and JSPs there.
Given that hot redeployment is enabled in your web container it would automatically designate a separate classloader to this new web application that it finds.
In most cases web containers consider any folder having a WEB-INF subfolder containing a valid web.xml file to be a web application. You can restrict access to this new webapp by modifying its context configuration, located in META-INF/context.xml in case of Tomcat.
Controlling hot redeployment, classloader policies etc is dependent on the type of your web container, but I hope your is not worse than Tomcat which could handle all of that.
I have a multi WAR web application that was designed badly. There is a single WAR that is responsible for handling some authorization against a database and defines a standard web page using a jsp taglib. The main WAR basically checks the privileges of the user and than based on that, displays links to the context path of the other deployed WARS. Each of the other deployed WARs includes this custom tag lib.
I am working on redesigning this application, and one of the nice things that I want to retain is that we have other project teams that have developed these WAR modules that "plug into" our current system to take advantage of other things we have to offer.
I am not entirely sure how to handle the page templates though. I need a templating system that would be easy enough to use across multiple wars (I was thinking of jsp fragments??). I really only need to define a consistent header and main navigation section. Whatever else is displayed on the page is up to the individual web project.
Any suggestions?
I hope that this is clear, if not I can elaborate more.
Have done something similar in the past using Sitemesh
we defined a new web app called skins-app which only has the common header, footer, navbar which all other need.
Sitemesh is configured via a file named WEB-INF/decorators.xml in the skins-app
then in any consuming webapp, you add a WEB-INF/decorators.xml as well.
And point your pages to be 'decorated' by the skins from another app
<decorator name="main" page="/decorators/layout.jsp" webapp="skins-app">
<pattern>/*</pattern>
</decorator>
You can have detailed include/exclude as well in your consuming webapp, if any pages needed to be excluded from the 'decoration'. Take a look at the Visual Example on the Sitemesh link page.
I am starting a new Java Web Project which is using Hibernate and a standard MVC Architecture.
I have just started to layout the projects structure and while doing this I started to look around to see if there was any standards in this area, about where Controllers should go and generally the best way to lay everything out. However I have not really found any guidelines.
So what I am curious to know is
Is anyone aware of any best practise guidelines for the layout of a Java Web Project?
Does anyone have a particular set of hard rules that they always follow for different types of project?
Do people tend to split packages by the different layers such as presentation, business, and application?
It really depends on your web framework.
For example if you use Wicket, java files and webpages co-exist in the same directory while
in most other frameworks, pages (.jsp files or whatever is your presentation engine) and
code-behind stuff (java files ) are completely separate.
So read the documentation that comes with your framework (Spring MVC, Struts, JSF e.t.c).
Another good proposal is to use Maven Archetypes to generate a skeleton for your specific framework. Some web frameworks (such as seam) have even their own code generation tool that lays the foundations for your web project.
My only good suggestion (that is not mentioned by Yoni) for the src directory is
to make packages according to business purpose and NOT according to type/layer
That means packages for
com.mycompany.myproject.customers
com.mycompany.myproject.departments
com.mycompany.myproject.billing
com.mycompany.myproject.reports
com.mycompany.myproject.admin
and NOT
com.mycompany.myproject.entities
com.mycompany.myproject.tables
com.mycompany.myproject.graphs
com.mycompany.myproject.dialogs
com.mycompany.myproject.servlets
The second structure is too generic, tends to resolve around huge packages with unrelated stuff and is hard to maintain.
To continue my previous answer, I have many web projects. In all of them the structure under src is more or less the same. The packages are roughly separated to 3 logical layers.
First is the presentation layer, as you said, for servlets, app listeners, and helpers.
Second, there is a layer for the hibernate model/db access layer. The third layer for business logic. However, sometimes the boundary between these layers is not clear. If you are using hibernate for db access then the model is defined by hibernate classes so I put them in the same area as the dao objects. E.g. com.sample.model holds the hibernate data objects and com.sample.model.dao hold the dao objects.
If using straight jdbc (usually with Spring), then sometimes I find it more convenient to put the data objects closer to the business logic layer rather than with the db access layer.
(The rest of the stuff typically falls under the business layer).
First, the to follow the conventional structure of a popular ide, ala Eclipse, Netbeans, etc.
In Eclipse, for example, everything is arranged already with a WEB-INF and META-INF folders, so packaging and deployment is easy. Classes source code (typically under src) is automatically copied to WEB-INF/classes.
There are a few other considerations:
If you are using MVC, then it is possible that you don't need to access your JSPs directly. If so, keep the JSP source code under WEB-INF/jsp, for security reasons.
Similarly, keep custom tag files under WEB-INF/tags.
Keep javascript files in js folder, css files in style folder, etc. All folders should be at the same level as WEB-INF to mimic a real deployment.
It is good to separate your code into packages according to layers. Obviously your Hibernate daos don't need to be at the same package as your servlets.
If you end up with too many servlets in the same package, consider sub-packaging them accord to functionality, but it is nice that they have a common ancestor package - it helps with readability.
Java Web Structure
Use the Maven webapp archetype layout.
project
|-- pom.xml
`-- src
`-- main
|-- java
`-- webapp
|-- WEB-INF
| `-- web.xml
`-- index.jsp
I've included the java folder in the example here, maybe it was obvious, but it was left out in the above link for some reason.