This question already has answers here:
How to use PrimeFaces p:fileUpload? Listener method is never invoked or UploadedFile is null / throws an error / not usable
(11 answers)
Closed 7 years ago.
First of all, I have to say, that I've read all (at least a lot :)) questions here and on primefaces forums about fileuploader issues.
My configuration:
Primefaces 4
JSF 2.2
Spring
Apache Tomcat 7
Maven
I am converting a richfaces project to primefaces, and I'm stuck with a fileUpload component that is not calling the handler method.
I have tried (altough I know that from Primefaces 4 it is not necessary) putting filters in the web.xml. I've also tried without filters. I have spring security filters and a language filter among some others, but the PF was first. I've also tried setting the dispatcher to FORWARD.
I have all the needed dependecies in Maven (commons - I know that from version 4 it is not required, but nevertheless I tried)
The xhtml part:
<h:form enctype="multipart/form-data">
... /* not relevant code here */ ...
<p:graphicImage value="#{systemParamsController.image}"
id="logo" />
<p:fileUpload
fileUploadListener="#{systemParamsController.listener}"
fileLimit="1" allowTypes="/(\.|\/)(gif|jpe?g|png)$/"
uploadLabel="#{msg['button.upload.jpg']}"
cancelLabel="#{msg['button.cancel']}"
invalidFileMessage="alert('#{msg['upload.invalidtype']}');"
update="logo" mode="advanced">
</p:fileUpload>
<p:growl id="messages" showDetail="true" />
</h:panelGrid>
</h:panelGroup>
<p:commandButton value="#{msg['button.save']}" onclick="this.disabled=true" oncomplete="this.disabled=false"
action="#{systemParamsController.save}" styleClass="qs-button"
ajax="false" />
</h:panelGrid>
</p:panel>
</center>
</h:form>
The backing bean:
public synchronized void listener(FileUploadEvent event) throws Exception {
logger.debug("uploadListener!");
UploadedFile item = event.getFile();
getModel().getCustomer().setLogo(imageResizer.doResize(item.getContents(), 30, Side.HEIGHT));
}
If I click on choose, I can select a file, but after that nothing happens. The handler is not called, because there is no log message, the upload file button is inactive. I have used this component before for more complex issues without problem, so I'm sure I'm missing something obvious.
Thanks in advance for any kind of help!
Make sure you have the PrimeFaces FileUpload Filter as the first filter in your web.xml:
<filter>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
If you're having trouble with the default primefaces uploader you can try the commons fileupload:
<context-param>
<param-name>primefaces.UPLOADER</param-name>
<param-value>commons</param-value>
</context-param>
We're using this Maven dependency:
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
Also, try putting the file upload in its own form.
Related
I have a jsf web application. I use primefaces ver. 5.3 and pretty-faces ver. 3.3.3
I have a page, catalogue.xhtml, where there is a file uploader in primefaces:
<p:fileUpload onstart="start()" oncomplete="stop()" id="image" styleClass="#{!catalogueBean.form.headerInsert ? '' : 'hidden'}" auto="true"
fileUploadListener="#{catalogueBean.imageLoad}" mode="advanced" skinSimple="true" sizeLimit="10000000" allowTypes="/(\.|\/)(gif|jpe?g|png)$/"
update="imageOnline" />
My CatalogueBean:
#ManagedBean
#SessionScoped
#BeanPage(name = "/admin/catalogue")
public class CatalogueBean {
....
}
My pretty-config:
<pretty-config xmlns="http://ocpsoft.org/schema/rewrite-config-prettyfaces"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://ocpsoft.org/schema/rewrite-config-prettyfaces
http://ocpsoft.org/xml/ns/prettyfaces/rewrite-config-prettyfaces.xsd">
....
<url-mapping id="adminCatalogue">
<pattern value="/admin/catalogue" />
<view-id value="/page/admin/catalogue.xhtml" />
</url-mapping>
....
</pretty-config>
When I upload the file, I got no error, and the image is not uploaded.
I saw already other discussion, but them didn't solve my problem.
In particular I tried to add in my web.xml
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
where I declare PrimeFaces FileUpload Filter:
<filter-mapping>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
EDIT:
If I change the annotation in class CatalogueBean :
#BeanPage(name = "/page/admin/catalogue.xhtml")
in the console, after the upload, I see admin/catalog and I don't understand why...
Please let me know what I wrong, and if it's possible to map, for id = adminCatalogue, only calls in GET
Thanks
How can I call a specific method in a class using this tag?
<jsp:useBean id="user" scope="??" class="com.example.User" type="com.example.User" />
Assuming your bean User has a method called getName()
<jsp:useBean id="user" scope="request" class="com.example.User" />
// ...
<h1>Hello <jsp:getProperty name="user" property="name" /></h1>
The scope could be something else than request : depends on what you want (session, page, etc)
EDIT: your second question was about calling a business method in your jsp
The fact is, you should not call business method into your JSPs. Your JSP pages should only display static (html, etc) and dynamic (beans for example) content. If you follow MVC pattern, business job is delegated to servlets. Your JSPs are only simple views (reading properties of beans) and are forbidden (in directory WEB-INF).
For your JSP pages, proceed as following:
Action of html form is your servlet controller (method POST)
Add hidden input to help servlet recognize what to do: <input
type="hidden" name="action" value="update" /> or <input
type="hidden" name="action" value="register" />
You can also display dynamic content (beans). For that, you should consider using JSTL.
Example (servlet sends an ArrayList of Movie beans on request scope):
<c:forEach items="${requestScope.results}" var="movie">
// ${movie.title}
// etc
</c:forEach>
For your servlet controller, proceed as following:
In doPost method (because we're using POST method in html form), you can dispatch business logic depending on action received: request.getParameter("action")
If action is update, then we perform update business logic.
If action is register, then we perform register business logic.
etc ...
Now, we can store some data in request scope to communicate to jsp page:
ArrayList<Movie> results = new ArrayList<Movie>();
results.add(new Movie(...));
// etc...
request.setAttribute("results", results);
And finally, send data and display jsp:
request.getRequestDispatcher("/WEB-INF/update.jsp").forward(request, response);
An example of web.xml (with a servlet mapped as welcome file index.jsp)
<servlet>
<servlet-name>Search</servlet-name>
<servlet-class>Servlets.Search</servlet-class>
</servlet>
<servlet>
<servlet-name>Register</servlet-name>
<servlet-class>Servlets.Register</servlet-class>
</servlet>
<servlet>
<servlet-name>Update</servlet-name>
<servlet-class>Servlets.Update</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Search</servlet-name>
<url-pattern>/index.jsp</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Register</servlet-name>
<url-pattern>/Register.do</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Update</servlet-name>
<url-pattern>/Update.do</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<jsp:useBean id="user" scope="request" class="com.example.User" type="com.example.User" />
<jsp:setProperty name="user" property="*" />
<c:set var="saveStatus" value="${user.save()}" />
I've tried to create a new action class and add it to struts.xml, the action class successfully get compiled but when I run tomcat it shows The requested resource is not available 404 error on index page itself.
CreateUser.jsp
<s:form action = "CreateUserAction" >
<s:textfield name = "name" label = "Name" />
<s:textfield name = "userName" label = "User Name" />
<s:submit value = "Register" />
</s:form>
CreateUserAction.java
public String execute() {
setMessage("Hello " + getUserName());
return "SUCCESS";
}
Struts.xml
<package name="default" extends="struts-default">
<action name="CreateUserAction" class="com.ecommerce.action.CreateUserAction">
<result name="SUCCESS">/success.jsp</result>
</action>
</package>
Actions in Struts2 are mapped to the URLs that are built from the configuration. When the url of the request match the action name and namespace then it is executed, otherwise error code 404 is returned by the dispatcher. Struts2 is implemented as a filter and it's looking for the requests that are mapped in it's configuration. For example if I want it to filter all URLs I will write in web.xml
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
If you say the error 404 on index page itself, then you should ask yourself which URL corresponds to it and what action is mapped via configuration to that URL. If you need more detailed picture of what configuration is and what URLs you could enter to execute an action install the config-browser plugin.
for the above issue:"The requested resource is not available in struts2 when action class is configured in struts.xml"
I have a suggestion.
Copy and paste all the external jars in in the folder lib(WebContent-->WEB-INF-->lib)
remove all external jars from Build path (Project -->buildpath-->Configure Build path)
I found this solution is working fine for eclipse Luna with Tomacat 7
I am trying to get my spring + hibernate + spring-security and tiles2 - "HelloWorld" application to work, following this guide (its in german unfortunately).
My problem is that I get a "404" error message when logging into my application. Redirection to the login page works as intended, but I can't reach "http://localhost:8080/App/j_spring_security_check" when I hit the login button.
My web.xml looks this way:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/defs/applicationContext.xml
/WEB-INF/defs/applicationContext-security.xml
</param-value>
</context-param>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>
and applicationContext-security.xml file looks this way ...
<http use-expressions="true">
<intercept-url pattern="/index.html" access="permitAll" />
<intercept-url pattern="/timeout.html" access="permitAll" />
<intercept-url pattern="/redirect.html" access="permitAll" />
<intercept-url pattern="/media/**" access="permitAll" />
<intercept-url pattern="/includes/**" access="permitAll" />
<intercept-url pattern="/office/**" access="hasRole('ROLE_USER')" />
<intercept-url pattern="/office/admin/**" access="hasRole('ROLE_ADMIN')" />
<form-login login-page="/index.html"
authentication-failure-url="/index.html?login_error=1"
default-target-url='/office/kunden.html'
always-use-default-target='true'
/>
<logout logout-success-url="/index.html" />
<remember-me />
<session-management invalid-session-url="/index.html">
<concurrency-control max-sessions="2" error-if-maximum-exceeded="true" />
</session-management>
</http>
<authentication-manager>
<authentication-provider>
<jdbc-user-service data-source-ref="mysqldataSource"
authorities-by-username-query="select username, authority from benutzer where username = ?"
users-by-username-query="select username, password, enabled from benutzer where username = ?"/>
</authentication-provider>
</authentication-manager>
The database connection seems to be O.K.
I would be very glad if someone could give me a hint on that, because I already did a lot of googling, but didn't find a solution yet.
I use spring 3.1 and tomcat 7.0.23
I would check two things:
Request dispatch
Spring-security config
To check request dispatch just make sure that your application is accessible in the servlet container in the first place. Meaning, you have mentioned http://localhost:8080/App/j_spring_security_check. Is your application accessible under that URL? Does http://localhost:8080/App show proper content (HTTP 200)?
Also make sure that dispatcher servlet is configured properly. In tutorial you have provided, there is this section:
<!-- Spring Hauptteil -->
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
If you have not provided it in your web.xml, then your request might not even be dispatched properly before it ends up being examined via spring-security.
If this doesn't help you, try this.
Following documentation, the minimal configuration should be enough to check if your setup is correct. If you have followed tutorial, you might make some minor mistake (typeo, for instance) that will cause spring-security not to launch properly. Then it is easy to skip some error info in logger output.
I suggest you do the following.
Change your applicationContext-security.xml to support minimal configuration provided in documentation.
Launch the application and go to http://localhost:8080/App/j_spring_security_check
If you get proper response - try modifying config until you are done.
Point to learn
What DelegatingFilterProxy (defined in web.xml) really does is delegating request to some other filter managed by Spring's IoC. This filter is being defined in applicationContext-security via security namespace. If this won't work for some reason, the filter will not be initialized, and you may end up in seeing http 404 regardless the fact, that the rest of application starts properly.
Uffff, lots of text ;)
Your configuration looks ok. One thing that can case the 404 is if the default-target-url='/office/kunden.html' points to an controller or view that does not exist.
Check that the url /office/kunden.html works -- therefore deactivate the security stuff (just add <security:intercept-url pattern="/**" access="permitAll" />) and try it.
An other thing that may goes wrong, is that the tutorial is for spring 3.0 but not spring 3.0. I would not expect that this is the cause, but give it a try and downgrade.
For those people who face the same symptoms, but for a different situation, those who are behind a load balancer which does SSL offloading, the following answer might put you in the right direction. I had a similar problem and it turned out that the incoming request was handled correct, however as a response spring security sends a redirect to an absolute URL which is defined by the default-target-url attribute (starting with http instead of https)
<security:form-login login-page="/login.jsp" default-target-url="/index.jsp" authentication-failure-url="/login.jsp?error=true" />
Now the client browser tries to open the redirected location on http, fails on the loadbalancer (which only accepts https traffic) and reports a 404 NOT FOUND
We solved this problem by adding the following mod_header directive for all incoming requests on port 443 (https) in the load balancer:
RequestHeader set X-Forwarded-Proto "https"
The will add an extra header. If you run an application server like Jetty, it will recognize this header and translate the incoming request. (see http://www.gossamer-threads.com/lists/apache/users/407272)
I am following the official Spring reference for setting up security. However I receive a resource not found error for spring security login when it should load the default spring login jsp, right ?
here is my web.xml snippet:
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/index</url-pattern>
</filter-mapping>
and also the relevant section of applicationContext.xml:
<security:http auto-config='true'>
<security:intercept-url pattern="/index" access="ROLE_USER" />
</security:http>
<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<security:user name="user" password="mypassword" authorities="ROLE_USER, ROLE_ADMIN" />
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
I think I have all the relevant dependcies loaded (as well as the others such tx & core) I have:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>
You want to map every URL in your app to be filtered through the Spring Security interceptor like so:
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
The interceptor will handle the login URL when it encounters it, and before it reaches any of your servlets or JSPs.
Similar to the answer that Pavel gave, it is the Spring Security filter chain that will process certain, specific, URLs such as j_spring_security_check and perform functions based on these particular URLs. Therefore, you will need to make sure, if you do not have a url-pattern of /* for your <filter-mapping>, that you at least explicitly include those particular URLs that are important to the Spring Security workflow that you are using. Depending on your authentication mechanism (username/password, OAuth, OpenID, etc.), these may or may not require you to dig into source code. Alternatively, you could experiment with a wildcard like /j_* or something. That should resolve your issue.
I have a suspicion that you need a DispatcherServlet, because something (a servlet?) needs to return the login page in the response and I'm pretty sure its not a filter. I'll try to do exactly what you did and see what happens.
In the mean time you could start from the sample application bundled in the spring-security archive and strip it down to what you need. This always worked for me so far.