I am beginning to break apart a large JSP file into a some smaller JSP pages so I can reuse this across other areas of the site.
I can take the approach of leaving as a large Monolithic JSP file that takes params and adjusts it's behavior accordingly. The other approach I can take is breaking it apart so that it's called via jsp:include.
What is the performance concern in creating additional request calls that are dispatched from within the server? Is it better performance wise to keep it as one jsp page?
The jsp:include is a runtime directive unlike the <%# include ... %> directive which happens to be a compile time directive (translation time, actually). A compile time include directive is relatively harmless since JSPs are usually precompiled for production, or in the worst case compiled for every deployment of the application. For this reason, it is preferable to use the compile time directive for static files, since the files are not bound to change at runtime.
The runtime include directive on the other head, if misused, can result in some performance hit, especially for static files being included. This is primarily because the JSP container would have to then fetch the contents of the static file and include them in the response. Hence, reserve the usage of the runtime directive for the really useful scenarios where another servlet or jsp's response is to be included in the response, and not merely to make the code look good.
You should be using:
<%# include file="page.jsp" %>
This adds the content of page.jsp at translation time and there is no overhead.
<jsp:include page="page.jsp" />
Your approach adds the content at runtime and adds a lot of overhead.
Static vs Dynamic include
The include directive, makes a copy of the included page and copies it into a JSP page (the "including page") during translation. This is known as a static include (or translate-time include) and uses the following syntax:
<%# include file="/jsp/userinfopage.jsp" %>
The jsp:include action, dynamically includes output from the included page within the output of the including page, during runtime. This is known as a dynamic include (or runtime include) and uses the following syntax:
<jsp:include page="/jsp/userinfopage.jsp" flush="true" />
Performance Considerations
Static includes affect page size; dynamic includes affect processing overhead. Static includes avoid the overhead of the request dispatcher that a dynamic include necessitates, but may be problematic where large files are involved.
A dynamic include does increase processing overhead, with the necessity of the additional call to the request dispatcher.
http://docs.oracle.com/cd/A97336_01/buslog.102/a83726/keydev1.htm#1015959
http://docs.oracle.com/cd/A97336_01/buslog.102/a83726/genlovw3.htm
Should not create a scenario to load lots of data to UI at a time, that will affect the performance whatever way you implement the jsp. Keep it simple. Understand , how much data a user probable to read in that specific scenario. Keep UIs userfriendly ,businessfriendly and techno friendly.
Calculate mow much static/dynamic contents are there and use include as per it's contexts. Use pagination with 10 - 50 records if you want to display records.Better use any framework to address the basic issues instead of addressing it from scratch.
if you don't need to use session in any jsp s make it as session false
<%# page session="false" %>
For include directive, JSP Engine adds the content of the inserted page at translation phase, so it does not have an impact on performance.
For include action, JSP Engine adds the content of the inserted page at run time which imposes extra overhead.
Related
Although I know JSP (basic understanding), I have some doubts on the JSP technology.
Consider the below simple jsp:
<html>
<head>
<title> This is demo</title>
</head>
<body>
<h1> The current time is <%=new java.util.Date()%> </h1>
</body>
</html>
With respect to this, I have some doubts (which I have been keeping at the back of my mind):
1) The basic text of this jsp is same, is it dynamic page because it has JAVA code in it?
2) When a user accesses this jsp page, does the container first execute the java code and replaces the output of java code inside the page?
3) What makes this a jsp page? Do mixing of html and java code make it a jsp?
4) Can the java code (within <% %> ) live independent of html? or they are coupled (the java code has to be present in html page).
They might be basic questions, can anyone help me in understanding them?
Yes it is dynamic because it is computed (even partially) at run time - here the java scriptlet is the dynamic part
Not exactly. JSP is not a template engine. JSP pages are fully translated to java source and then compiled to class files by the servlet container. Then those classes are executed at run time.
the extension .JSP makes it a JSP file. Then it must respect the JSP syntax to be correctly processed by a servlet container.
Reverse the question. Java code normally lies in java source files. A Java class implementing the HttpServlet interface can be directly map to an URL by the servlet container. And Java code can lie in a scriptlet in a JSP
But as you were said in comment, you really should read documentation on that before asking questions here.
1) it's dynamic if it contains any JSP elements, like code snippets, JSP tags etc. If it contains only HTML, then it's pretty static, although if it is processed as a JSP, then the constant response is computed dynamically on each call (safe Caching).
2) yeah much like that. Actually the static text of the JSP goes into out.write() Statements in a Java class; the whole JSP is transpiled to a Java class.
3) funny question. It's all a question of Interpretation. If you name it .jsp or have your web container process it as JSP in some other ways (depends), then you may call it a JSP.
4) this question is not quite clear. The snippets are executed after the static text has been output up to this point.
Per my understanding JSP is something to serve to the client. But is it possible to use JSP simply as a template to dynamically assemble an html page, which I then serve to the client? What I mean is this
A servlet receives the call from the user
After some computation, my servlet calls the JSP to assemble the html page dynamically
The servlet gets or converts the JSP "result" (the resulting html page) to a String
The servlet can now do whatever it wants with that String. It can return it as an html webpage or it can store it in a database, or whatever. After all, the string here is a proper html page/text.
For comparison, Python has Jinja2, which does exactly what I just explained. The closest thing to Jinja2 in Java seems to be JSP.
I need a template to assemble html pages dynamically. If I can use the JSP as above then that will solve my problem in Java. Notice that I don't care for JSP per se. I just need a template similar to Jinja2 (if I could use Jinja2 in Java on App-Engine that would be ideal). Also I am very new to JSP. So if you have an answer, please format it as an example; that would be truly helpful.
I am migrating from Python App-Engine to Java App-Engine for business reasons.
This is possible, but you'll need to jump through quite a few hoops, the details of which are dependent on the specific container - in this case appengine.
A quick summary:
create a fake httpservletresponse, wrapping an output stream you access after rendering. You cannot use a httpservletresponsewrapper, even though the spec permits it this environment won't
store all request attributes in a map, you'll restore these afterwards in case they've been mutated
use requestdispatcher.include, passing in the real request and your synthetic response
restore request attributes
read string from the outputstream
Be particularly careful of side effects to your request/response, for example the constraints around only calling one of getwriter or getoutputstream, as well as finalizing the request (setting status or content length)
Or just use one of velocity, handlebars, freemarker or the various other Java templating languages. They'll all be much more straightforward.
For many projects I have worked on, programming teams work with the style of placholding every piece of static text in an xhtml file into a properties file. For example:
xhtml=
...
<h1>${messages.resourceBundle['key.to.static.text.placeholder']}</h1>
...
messages.properties=
...
key.to.static.text.placeholder=This will be the heading for this page only
...
Would anybody be able to explain what the advantage in this is?
So far, I can only see the following disadvantages:
making changes to any xhtml file requires you to hunt for the correct .properties file, and then the individual property to make the change to
if others have re-used properties, then deleting them becomes tricky as you have to be certain no other page is referencing the property, therefore after several change request rounds, properties files become large with redundant properties
if there are 1000 xhtmls, there will be 1000 .properties files to load, which is more cycles on the cpu to load and inject static pieces of text
if your using WebFlow and have flows that pass into other flows, properties have to be duplicated, meaning that sometimes you must place the same property in many different properties files to render correctly
hard to read code; if you know you want to work on the text 'This will be the heading for this page' only, you'll need to work out where that is on the xhtml from the property files first - you can't simply look at the xhtml and see clearly how the content will be laid out once rendered.
The only advantages I can see are text reuse and possibly html escaping.
Apologies if its coding 101, but I've had a hunt around Google and can't find the reasoning to the pattern.
Many Thanks
This is a common practice for internationalizing content.
You create one property file per language (or locale) and use a dynamic way off resolving which one to load depending on the context. (e.g. Language HTTP header the browser sends).
It is arguably more flexible than providing 1 jsp file per language, and can still deal with complex cases where plurals or stylistic differences might change the way you write localized text.
This is a standard JDK feature, lookup resource bundles.
You do not have to build 1 file per jsp (maybe your framework works this way?), although doing so can help the person writing the translation.
I wonder if there is a way to load, interpret and render a .xhtml file from a servlet.
What I want is to have a xhtml file witch contain for example a custom row within a list, to be loaded from a servlet or a bean, to be interpreted, and to obtain the html result.
Sounds to me like you're not in need of Servlets or JSF, but rather JSP (should look familiar, coming from PHP).
Notice that people here will tumble over themselves telling you to not put the logic into the page (and for good reason), but I think with your background, you'll be helped by starting from a JSP only approach. Than start moving the logic to a servlet. You can use a number of techniques to communicate the data between the servlet and the jsp. I like to use
request.setAttribute("someString", valueObject);
In your jsp you than can use:
<%= request.getAttribute("someString") %>
Calling your jsp from the servlet is done via
RequestDispatcher rd = req.getRequestDispatcher("/path.to.your.jsp");
If you really need a .xhtml file (your original question), you can use this last line as well, but it'll be real xhtml, like it would be served from a plain webserver (!= appserver)
This is the situation:
We have some binary files (PDFs, PPTs, ZIPz, etc.) stored in a server different from where our application is. We need to make them available for the users in our app. But files have extremely sensitive information that can not be read by anyone else but the user that has access to them which means that we need to validate the user that is trying to access the file before s/he can download it.
This is how we solve it:
We get the file from the remote server, store it in a non public location.
We read the file into a byte array, then we delete the file.
We write the file through a JSP using the response's outputStream. (We can not flush it through the servlet because we are using a proprietary MVC that we cannot modify, so all outputs are JSPs, so we get a java.lang.IllegalStateException but it works).
I'm concerned by 3 aspects of this solution; The file size will impact the heap size dramatically, the file size is limited to a max of byte[Integer.MAXSIZE] and finally we get an java.lang.IllegalStateException every time someone downloads a file because we are calling the response.getOutputStream(), so our log is growing a lot.(We can not flush it through the servlet because we are using a proprietary MVC that we cannot modify or extend)
I'm pretty sure there is a more elegant way to do this.
Any ideas?
Indeed just don't store it locally. You're getting it as an InputStream from somewhere else, right? Just write it immediately to the OutputStream of the response. Then there's no need to get hold of it in Java's memory nor local disk file system. This means that you should put the logic for obtaining the file in the JSP file. Bad, bad, but since this is apparently a proprietary framework...
Then the IllegalStateException part, you just need to ensure that there is no whitespace outside the scriptlets, including newlines. It will all implicitly be written through response.getWriter(), but this isn't possible because you already called response.getOutputStream() for the file. Remove everything outside <% %> in the JSP. Glue if necessary multiple scriptlets together. Don't forget to remove the last newline at the bottom of the file.
E.g. not so:
<%# page import="java.io.*" %>
<% ... %>
<% ... %>
<% ... %>
But more so:
<%# page import="java.io.*" %><%
...
...
... %>
Good luck with this webapp.
Skip step 2 and read the file directly into the response's output stream.
Give each file a UUID for a name, so you do not have clashes with the file names. Have a daemon process go and cleanup any files more than 15 minutes old.
Probably the most elegant solution would be to use an existing open source software product. I believe Knowledge Tree would satisfy your requirements.