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.
Related
Often when developing, I come across the following: -
<%%>
Totally empty scriptlet tags.
In the past, removing this "mere nuisance" polluting the codebase has caused my JSP's not to work.
What is the purpose of these empty scriptlet tags?
Ultimately JSP pages are compiled to .java files which compile to .class files.
I seem to remember that literal strings in a .java file have a maximum size limit. I'm guessing that <%%> was added to the middle of a very long piece of static html in the JSP to force two or more string literals in the resultant .java file.
It might be related to this question which suggests:
The value of the code_length item must be less than 65536.
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)
I am building a web application with JSP and Java Servlet. Currently I am using JSTL fmt for the internationalization using a property file (messages.properties). But my costumer wants to be able to update text live so I need to move keys/value from the property file to the database. The problem is I don't know how I can read text from the database into for exemple
<fmt:message> tag in the JSP file.
Any help is very welcome, thanks
//Momo
<fmt:message> can make use of a LocalizationContext which, in turn, makes use of a ResourceBundle. So, really, you should focus on how to create a ResourceBundle that meets your needs. If you absolutely have to use a database, perhaps someone's already created a ResourceBundle implementation to handle that. One thing to make sure you investigate, as long as you're using at least Java 6, is ResourceBundle.Control. It may turn out that you can keep using property files but customize the caching behavior.
Not with fmt. You either write your own tag or you change the code of fmt.
Could this be a solution? Instead of reading from the database för every key/value pair I read them into a map and refresh every knight.
Database backed i18n for java web-app
I am trying to refactor my JSP code so that a small conditional test condition gets reused through a *.tag file.
There are some big parts of my UI that depend on the value of a two-state property of an object present in the request. Let's say the property is 'gender' and the object is of type Person.
Like I said, I would like to simplify & centralize the test on the gender property using a tag. For this purpose, I created two tag files:
/WEB-INF/tags/if-male.tag
/WEB-INF/tags/if-female.tag
Now, I have another tiny spot that gets repeated in all over my application; let's say is the salutation to my site user. With this idea, I created a tag like this:
/WEB-INF/tags/salutation.tag
As you can imagine, I am trying to use the if-male/if-female test within the salutation.tag file to output 'Mrs.' or 'Mr.' like this:
<%# tag body-content="empty" %>
<%# taglib prefix="g" uri="/WEB-INF/tags" %>
<g:if-male> Mr. </g:if-male>
<g:if-female> Mrs. </g:if-female>
Is the use of the if-male/if-female tags legal within the salutation.tag file?
I have tried with such arrangement, but it looks like the JDeveloper 10.1.3.4 compiler gets confused and cannot deal with the salutation.tag tag invoking the other two tags in the same 'library' (folder under /WEB-INF/tags).
The reference works perfectly in Jetty 6 and it looks like it works as well if I deploy the application to OC4J directly without relying on JDeveloper to pre-compile all my JSPs.
I hope someone can shed some light on this.
Thanks,
YJ
Including tag declarations inside of other custom tags--I do this all the time and with syntax matching yours.
This is absolutely legal, and is part of the attraction of tag files.
If JDeveloper doesn't like it, that's JDeveloper's problem. You should consider using a modern IDE (eclipse, netbeans, intellij) instead, JDeveloper's time (if it ever had one) is long gone.
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.