Primefaces FileUpload: handle firewall error blocking upload - jsf

We have a JSF application that is currently working and live that uses Primefaces 7.0. The application allows users to upload files using the Primefaces FileUpload component which we then handle and process.
The firewall team is forcing a firewall to sit in front of the upload process which will block upload requests from hitting the application if it deems the file to not be suitable and return a 503 error to the browser. I am struggling to work out how we can handle the 503 error within the JSF application as the request never hits the server and I can't find a suitable attribute we can add to the FileUpload component that would listen for the 503 (tried using onerror as shown in code below but unfortunately it doesn't get called when the 503 error occurs). Without handling this error, nothing is presented to the user to suggest anything happened. Ideally we would present a growl message to the user asking them to try a different file type.
Below is the code currently for the FileUpload component however I'm not sure if it's any use as I'm looking more for advice than a code fix.
Anyone have any idea on how to potentially handle the 503?
Thanks
<p:fileUpload widgetVar="upload" id="upload"
disabled="#{user.filesRemaining eq 0}" label="SELECT FILES"
fileUploadListener="#{controller.handleFileUpload}"
styleclass="smallCommandButton" mode="advanced"
dragDropSupport="true" auto="true"
allowTypes="/(\.|\/)(jpeg|jpe|jpg|png|pdf)$/i" sizeLimit="10485760"
invalidSizeMessage="Image files must be under 10MB in size"
invalidFileMessage="Only JPG, PNG or PDF files can be uploaded"
onerror="#{controller.handleUploadError()}"
onstart="PF('uiBlocker').show()"
oncomplete="PF('uiBlocker').hide()">
</p:fileUpload>

Found a solution, I needed to add the below code to my fileUpload component, 'arguments' carries the information for the error:
onerror="handleUploadError(arguments)"
and then create the corresponding javascript function to handle the error e.g.
function handleUploadError(arguments) {
if(arguments[0].status === 503) {
**create message for user here**
}
}

Related

JSF inputFile Refused to display 'mypage.xhtml' in a frame because it set 'X-Frame-Options' to 'deny'

I was following this answer by BalusC to try and upload a file to the server. I am using his code as-is.
When using JSF 2.2, the #{bean.save} was never reached, and the file was never saved.
The server's console showed nothing. But the js console showed this error:
Refused to display 'http://localhost:8080/my_app/hello.xhtml' in a frame because it set 'X-Frame-Options' to 'deny'.
jsf.js.xhtml?ln=javax.faces:1 Uncaught DOMException: Blocked a frame with origin "http://localhost:8080" from accessing a cross-origin frame.
at FrameTransport.callback (http://localhost:8080/my_app/javax.faces.resource/jsf.js.xhtml?ln=javax.faces:1:5109)
at HTMLIFrameElement.<anonymous> (http://localhost:8080/my_app/javax.faces.resource/jsf.js.xhtml?ln=javax.faces:1:5759)
I saw this answer which suggested it was a bug in JSF 2.2. So I uploaded to 2.3.
With JSF 2.3 the #{bean.save} is reached, and the file is successfully saved. But the js error remains, and I can't upload a second file.
Any ideas?
EDIT in case it helps: I don't know why, but after selecting the file to upload in the dialog, an <iframe> is added to my page somehow.
EDIT 2
BalusC and Selaron suggested I try to change the X-Frame-Options header to not 'DENY'. I tried adding a #WebFilter and setting the header there, like this:
public void doFilter(...)
{
HttpServletResponse response = (HttpServletResponse) res;
response.addHeader("X-Frame-Options", "sameorigin");
response.setHeader("MyHeader", "whatever");
chain.doFilter(req, res);
}
I added a second header MyHeader with value "whatever" to check if the response contained that header when getting to the browser.
Turns out MyHeader gets to the browser correctly, but X-Frame-Options still remains as 'DENY'.
As I'm using Spring Security, I figured maybe there was some other filter messing with my response?
So, I have this:
#Configuration
#EnableWebSecurity
public class BasicConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
...
http.addFilterAfter(
new CustomFilter(), SwitchUserFilter.class);
...
}
}
My CustomFilter works as the previous one I showed: MyHeader remains, but X-Frame-Options does not.
I added it after SwitchUserFilter because the doc for HttpSecurity.addFilter says that is the last filter in the chain.
I am a bit lost now. My couple of questions:
Am I right to assume the X-Frame-Options header is getting overwritten by some other filter?
How could I ensure the X-Frame-Options I set remains? Or, how can I put my filter at the end of the chain?
I found this issue where the Mojarra team planned to Implement "ajax" file upload #2577 and the commit actually implementing it to the jsf javascript.
Madly the documentation on issue 2577 are not accessible anymore and thus it does not explain the background on why an iframe is needed here.
The first passage of this blog gives a brief explanation on why AJAX file upload is/was(?) not possible directly:
Ajax Style File Uploading using Hidden iFrame
by Viral Patel · November 18, 2008
File uploading using AJAX is not possible. AJAX doesn’t actually post
forms to the server, it sends selected data to the server in the form
of a POST or GET request. As javascript is not capable of grabbing the
file from the users machine and sending it to the server, it’s just
not possible with AJAX. You have to resort to regular old form submit.
If you have read/seen it somewhere, then it is not through AJAX. File
uploading occurs through an iframe in this case. You have to use a
iframe to upload the files. So, you can use iframe to asynchronous
upload (Like AJAX , but its not AJAX).
So finally your options are to either - as BalusC commented - relax your X-Frame-Options header setting or to change your upload to not use AJAX:
<h:form enctype="multipart/form-data">
<h:inputFile value="#{bean.file}" />
<h:commandButton value="upload" action="#{bean.save}"/>
</h:form>

Linux Server deployed JSP - Http 404 the requested resouce is not available

I am working on a web based project in eclipse on a system with jre 1.8 and Tomcat 8.
My application works fine on my system.
Now I have to deploy my application on a linux server machine.. As I am a novice I am facing some difficulties.
My server machine has Tomcat 7 installed.
For deployment , i was copying the sources from wtpwebapps from my system to /var/lib/tomcat7/webapps on my server machine.
But now only html webpages are showing up and all the jsp files are giving the HTTP: 404 The requested resource is not available.
My Folder Structure is MyProject/WebContent/(DisplayResults.jsp & Homepage.html) & servlet is located at MyProject/src/Utility/Servlet.java
Homepage.html
<form method="get" action="/MyProject/Servlet">
<input type='text' name='q' value='Type your text'><br>
<br> <input type="submit" value="Search">
</form>
Servlet.java
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
String query = request.getParameter("q");
System.out.println("query is " + query);
request.setAttribute("itemList", list);
request.setAttribute("q", query);
RequestDispatcher view = request
.getRequestDispatcher("/DisplayResults.jsp");
view.forward(request, response);
}
DisplayResults.jsp
<%#page import="Utility.*"%>
<html>
<body bgcolor="#fdf5e6">
<table>
<td><c:forEach var="d" items="${itemList}">
<b><a href='<c:out value="${d.itemLink}"/>'>${d.itemTitle}</a></b>
<br>
<small>${d.itemLink}</small>
<p>${d.itemDesc}</p>
</c:forEach></td>
</table>
</body>
</html>
On server machine, the html file opens up but for jsp file it gives resource not available error.
I have read across through several related posts, I could not find the exact scenario being answered.I guess the issue is related to the class files for the jsp not being found. As I am copying the wtpwebapps folder manually , i think something is getting missed.
Kindly please help.
Also I would like to know where can I check errors on the server machine.
Since you are using eclipse you can create War file and deploy the same to your server machine's tomcat/webapps folder. Restart your Tomcat server and let tomcat auto load your application.
yourProject(Right Click)->export->web->war
There select your project, Provide name of the war file to be generated.
Note: Your application context will be same as your War file name.
In this way you can avoid any mistakes happening due to direct file transfer.
Another thing I noticed is that you are using your action url as /MyProject/Servlet.
Try using this in your form action Servlet.
Your form tag will become
<form method="get" action="Servlet">

does not display the result (Java)

Hello trying to figure out the Jsf (primefaces) and little that goes viz. Compiled war archive in maven try to run through the Glassfish, the server starts but in the beginning writing "Artifact qwe-1.0-SNAPSHOT.war: Server is not connected. Deploy is not available." But in the late writes "Artifact qwe-1.0-SNAPSHOT.war: Artifact is being deployed, please wait... Artifact is deployed successfully." It seems like everything is normal, then opened my page in the browser is empty although in my index.xhtm and my pom.xml and web.xml link pastebin
and should be a button with styles that are connected in primefaces tell me if I'm doing something wrong?
here's a screenshot of the result in the browser. link1
<p:button outcome="productDetail" value="Bookmark" icon="ui-icon-star"> targets you to the productDetail page. If you do not have productDetail.xhtml page at the currect path, the index.xhtml page cannot resolve NavigationCase for outcome. Thus, Create page productDetail.xhtml and put into the same directory of index.xhtml.
In addition, You should use JSF Standard tags(h:head, h:body).

java.lang.NoClassDefFoundError: org/apache/poi/ss/usermodel/RichTextString at org.primefaces.component.export.ExporterFactory.getExporterForType

I used the same sample code Primefaces has in its web page:
<h:commandLink value="Excel">
<p:dataExporter type="xls" target="dataTable" fileName="boo" pageOnly="true"/>
</h:commandLink>
But does not work.
In Internet Explorer browser gives the following message:
Details of the errors of the web page Message: Unexpected call to
method or property access.
Nothing ever happens in Mozilla Firefox.
What might be happening?
javax.servlet.ServletException: org/apache/poi/ss/usermodel/RichTextString
Look further down in the stacktrace. I bet that the root cause is either a NoClassDefFoundError or ClassNotFoundException? In that case, this just means that you forgot to install Apache POI.
Download this Apache POI zip file, extract it, put poi-3.8-20120326.jar in /WEB-INF/lib folder and rebuild/redeploy/restart the webapp.
Try to to put this jar file.I show the link,because i solved this problem.
http://apache.mirrors.pair.com/poi/release/bin/poi-bin-3.9-20121203.zip

jsf navigation question

I have a JSF2 project with a "view user" page that reads the currently selected user from a session bean; userHandler.selectedUser.
The page is intended to be visited by navigating with links in the app.
However, if the user attempts to hit the "view user" page directly by this URL ...
http://localhost:8080/webapp/userView.jsf
... they see the page with no data on it (because there's no selected user in the userHandler).
I think what I'd like to do is redirect the user to the main page of the app if they try to hit it directly like that. What is a simple and elegant way of handling this problem?
Thanks,
Rob
You'd like to hook on the preRenderView event and then send a redirect when this is the case.
<f:metadata>
<f:event type="preRenderView" listener="#{bean.preRenderView}" />
</f:metadata>
with
public void preRenderView() throws IOException {
if (userHandler.getSelectedUser() == null) {
FacesContext.getCurrentInstance().getExternalContext().redirect("home.jsf");
}
}
A way to avoid this problem from the start is to have pages that you don't want to be accessed directly via URL into the WEB-INF folder of your project.
This way, your pages aren't accessible directly via URL.

Resources