I'm trying to use Bean validation instead of JSF validation since it is a more DRY aproach, i'm using the annotations on my model but when i insert null data on jsf fields it does nothing...
None of the annotations that i'm using is having any effect, its like they are not there....
I'm using Tomcat 8
My xhtml
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Insert title here</title>
</h:head>
<h:body>
<h1>Cadastro de funcionario</h1>
<h:form>
<h:messages/>
<h:panelGrid columns="3">
<h:outputLabel value="Salário: R$ " for="campo-salario"/>
<h:inputText id="campo-salario" value="#{funcionarioBean.funcionario.salario}">
<f:convertNumber locale="pt_BR"/>
</h:inputText>
<h:message for="campo-salario" />
<h:outputLabel value="Código: " for="campo-codigo"/>
<h:inputText id="campo-codigo" value="#{funcionarioBean.funcionario.codigo}"/>
<h:message for="campo-codigo"/>
<h:outputLabel value="Data: " for="campo-aniversario"/>
<h:inputText id="campo-aniversario" value="#{funcionarioBean.funcionario.aniversario}">
<f:convertDateTime pattern="dd/MM/yyyy" />
</h:inputText>
<h:message for="campo-aniversario"/>
<h:commandButton value="Cadastrar" action="#{funcionarioBean.mensagem}"/>
</h:panelGrid>
</h:form>
</h:body>
</html>
My Bean
#ManagedBean
public class FuncionarioBean {
private Funcionario funcionario = new Funcionario();
public void mensagem(){
System.out.println("Pressionado");
}
public Funcionario getFuncionario() {
return funcionario;
}
public void setFuncionario(Funcionario funcionario) {
this.funcionario = funcionario;
}
}
My Funcionario class
import java.util.Date;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
public class Funcionario {
#NotNull(message="{br.com.k19.Funcionario.nome")
#Min(value = 0)
private Double salario;
#NotNull
#Min(value = 5)
#Max(value = 19)
private Integer codigo;
#NotNull
private Date aniversario;
public Double getSalario() {
return salario;
}
public void setSalario(Double salario) {
this.salario = salario;
}
public Integer getCodigo() {
return codigo;
}
public void setCodigo(Integer codigo) {
this.codigo = codigo;
}
public Date getAniversario() {
return aniversario;
}
public void setAniversario(Date aniversario) {
this.aniversario = aniversario;
}
}
My lib
Can't post pictures yet.
Lib
>
antlr-2.7.7.jar
dom4j-1.6.1.jar
hibernate-commons-annotations-4.0.5.Final.jar
hibernate-core-4.3.6.Final.jar
hibernate-jpa-2.1-api-1.0.0.Final.jar
hibernate-validator-5.0.0.final.jar
jandex-1.1.0.Final.jar
javassist-3.18.1-GA.jar
javax.servlet.jsp.jstl-1.2.1.jar
javax.servlet.jsp.jstl-api-1.2.1.jar
jboss-logging-3.1.3.GA.jar
jboss-logging-annotations-1.2.0.Beta1.jar
jboss-transaction-api_1.2_spec-1.0.0.Final.jar
jsf-api-2.2.8.jar
jsf-impl-2.2.8.jar
mysql-connector-java-5.1.23.bin.jar
omnifaces-1.8.1.jar
primefaces-5.0.jar
validation-api-1.0.0.GA.jar
My web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
<display-name>K19-Conversao-e-Validacao</display-name>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<context-param>
<param-name>com.sun.faces.writeStateAtFormEnd</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
<param-value>true</param-value>
</context-param>
</web-app>
Downloaded hibernate jars again to match the versions
Download validator: http://hibernate.org/validator/
Download ORM: http://hibernate.org/orm/
My lib
Working as intend now
ref: Bean Validation #NotNull, #NotBlank and #NotEmpty does not work in JSF+Tomcat
Related
I'm using Jakarta EE 9, Glassfish 6.0, and JSF 3.0 and getting "Target Unreachable, identifier '' resolved to null..." I know questions like this have been asked before but I tried all proposed solutions. Also, I could find very few discussions about version 3.0 of JSF. I would appreciate it if someone could help me spot what wrong is.
BookController.java
import entities.Book;
import jakarta.enterprise.context.RequestScoped;
import jakarta.faces.application.FacesMessage;
import jakarta.faces.context.FacesContext;
import jakarta.inject.Inject;
import jakarta.inject.Named;
#Named
#RequestScoped
public class BookController{
private String test = "dada";
#Inject
private BookEJB bookEJB;
private Book book = new Book();
public String doCreateBook(){
bookEJB.createBook(book);
FacesContext.getCurrentInstance().addMessage(
null, new FacesMessage("Book created"));
return "newBook.xhtml";
}
public void doFindBookById(){
book = bookEJB.findBookById(book.getId());
}
public Book getBook() {
return book;
}
}
BookEJB.java
import entities.Book;
import jakarta.annotation.sql.DataSourceDefinition;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import java.util.ArrayList;
import java.util.List;
#Named
#jakarta.ejb.Stateless(name = "BookEJB")
public class BookEJB {
#PersistenceContext
private EntityManager em;
public BookEJB() {
}
public Book createBook(Book book){
em.persist(book);
return book;
}
public List<Book> findAllBooks() {
return em.createNamedQuery("findAllBooks", Book.class).getResultList();
}
public Book findBookById(Long id){
return em.find(Book.class, id);
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
version="5.0">
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>jakarta.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
</web-app>
faces-config.xml
<?xml version='1.0' encoding='UTF-8'?>
<faces-config version="3.0" xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee
https://jakarta.ee/xml/ns/jakartaee/web-facesconfig_3_0.xsd">
</faces-config>
beans.xml (in both WEB-INF and META-INF)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/beans_3_0.xsd"
version="3.0"
bean-discovery-mode="all">
</beans>
layout.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
<title><ui:insert name="title">Default title</ui:insert></title>
<link rel="icon" href="https://i.loli.net/2021/06/12/im236Uy7FLhxCJ1.png"/>
</h:head>
<h:body>
<h:link value="Create a book" outcome="newBook.xhtml"/>
<h1><ui:insert name="title">Default title</ui:insert></h1>
<hr/>
<!-- <h:message for="errors"/>-->
<ui:insert name="content">Default content</ui:insert>
<hr/>
<h:outputText value="APress"></h:outputText>
</h:body>
</html>
newBook.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<ui:composition template="layout.xhtml">
<ui:define name="title">Create a new book</ui:define>
<ui:define name="content">
<h:outputText value="#{bookController.test}"/>
<h:form id="bookForm">
<h:outputLabel value="Title: "/>
<h:inputText value="#{bookController.book.title}"/>
<h:outputLabel value="Price : "/>
<h:inputText value="#{bookController.book.price}"/>
<h:commandButton value="Create a book" action="#{bookController.doCreateBook}">
<f:ajax execute="#form" render=":booklist :errors"/>
</h:commandButton>
</h:form>
<hr/>
<h1>List of Books</h1>
<h:dataTable id="booklist" value="#{bookEJB.findAllBooks()}" var="bk">
<h:column>
<f:facet name="header">
<h:outputText value="Title"/>
</f:facet>
<h:link outcome="viewBook.xhtml?id=#{bk}" value="#{bk.title}"/>
</h:column>
</h:dataTable>
</ui:define>
</ui:composition>
</html>
It is because of Application Server that cannot fully support to JSF-3.0. I've got same error when I tested jakartaee-tutorial-examples/web/jsf/guessnumber-jsf project. I've tried guessnumber-jsf.war file on WildFly 24.0.0.Final and wildfly-23.0.2.Final Application servers. I got same error on both servers. But when I tested on Wildfly-preview-23.0.2.Final which supports JakartaEE 9.1 and JDK 11, it is working well.
I tried solutions from topics with same issue but that didn't work for me. So here is my story. I created very simple web project:
project
Here the code:
package user.bean;
import javax.annotation.ManagedBean;
#ManagedBean
public class User {
private String firstName;
private String lastName;
private String email;
User() {
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
First JSF:
<!DOCTYPE html>
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
<title>User Registration Form</title>
<style>
.error {color:red}
</style>
</h:head>
<h:body>
<h:form>
<h:messages styleClass="error"/>
First Name: <h:inputText value="#{user.firstName}"
label="First name"/>
<br/><br/>
Last Name: <h:inputText value="#{user.lastName}"
label="Last name"
required="true"/>
<br/><br/>
Email: <h:inputText value="#{user.email}"
label="Email"
required="true"/>
<br/><br/>
<h:commandButton value="Submit" action="user_response"/>
</h:form>
</h:body>
</html>
Second JSF:
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>
<title>User Confirmation</title>
</h:head>
<h:body>
<h:form>
User is confirmed: #{user.firstName} #{user.lastName}
<br/><br/>
Email: #{user.email}
</h:form>
</h:body>
</html>
At
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
I have: NLS missing message: CANNOT_FIND_FACELET_TAGLIB in:
org.eclipse.jst.jsf.core.validation.internal.facelet.messages
I tried:
Close/reopen project.
Rightclick project > Validate.
Project > Clean... and clean selected project.
Restart Eclipse.
Its didnt worked.
When I run it I faced: HTTP Status 404
So I tried this:
Click on Window > Show view > Server or right click on the server in
"Servers" view, select "Properties".
In the "General" panel, click on the "Switch Location" button.
The "Location: [workspace metadata]" should replace by something else.
Open the Overview screen for the server by double clicking it.
In the Server locations tab , select "Use Tomcat location".
Save the configurations and restart the Server.
Than I add JSF 2.2 (Mojarra 2.2.0) by properties -> Java Build Path. No changes. So I delete it from Build Path and add to WEB-INF->lib. Run on server and face: HTTP Status 500 - Servlet.init() for servlet Faces Servlet threw exception. I added url-pattern and listener to my web.xmp:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>JSF</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<listener>
<listener-class>com.sun.faces.config.ConfigureListener</listener-class>
</listener>
</web-app>
and faced HTTP Status 404 - /JSF/user_form.xhtml
Well I'm complete newbe right now and will be very greatful for little help here. Thanks.
In RichFaces, inorder to upload a file I used rich:fileUpload. By using rich:fileUpload Add, Upload and Clear All buttons are automatically generating in the richfaces livedemo example but for me Add, Upload and Clear All are appearing as text in my browser where should I change so that Add,upload and clearAll can be clickable. Do I have to change any settings in web.xml / pom.xml file.
I am using RichFaces 4 and JSF 2.
This is my web.xml :
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>Sample RichFaces 4 Application</display-name>
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<context-param>
<param-name>javax.faces.SKIP_COMMENTS</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>org.richfaces.skin</param-name>
<param-value>#{skinBean.skin}</param-value>
</context-param>
<context-param>
<param-name>org.richfaces.fileUpload.maxRequestSize</param-name>
<param-value>1000000000</param-value>
</context-param>
<context-param>
<param-name>org.richfaces.fileUpload.createTempFiles</param-name>
<param-value>true</param-value>
</context-param>
<listener>
<listener-class>com.sun.faces.config.ConfigureListener</listener-class>
</listener>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<mime-mapping>
<extension>ecss</extension>
<mime-type>text/css</mime-type>
</mime-mapping>
<welcome-file-list>
<welcome-file>index.jsf</welcome-file>
</welcome-file-list>
<login-config>
<auth-method>BASIC</auth-method>
</login-config>
Hi, i am getting those add and update buttons now correctly by simply providing h:head and h:body tags but i am getting this exception javax.faces.event.AbortProcessingException and files are not being uploaded as shown in the example provided in the link "FileUpload example".Can anyone plz help me out from this issue
This is my xhtml page
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org /TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:a4j="http://richfaces.org/a4j" xmlns:rich="http://richfaces.org/rich">
<ui:composition>
<h:head>
<h:outputStylesheet>
.top {
vertical-align: top;
}
.info {
height: 202px;
overflow: auto;
}
</h:outputStylesheet>
</h:head>
<h:body>
<h:form>
<h:panelGrid columns="2" columnClasses="top,top">
<rich:fileUpload fileUploadListener="#{fileUploadBean.listener}" id="upload" acceptedTypes="jpg, gif, png, bmp"
ontyperejected="alert('Only JPG, GIF, PNG and BMP files are accepted');" maxFilesQuantity="5">
<a4j:ajax event="uploadcomplete" execute="#none" render="info" />
</rich:fileUpload>
<h:panelGrid id="info" layout="block">
<rich:panel bodyClass="info">
<f:facet name="header">
<h:outputText value="Uploaded Files Info" />
</f:facet>
<h:outputText value="No files currently uploaded" rendered="#{fileUploadBean.size==0}" />
<rich:dataGrid columns="1" value="#{fileUploadBean.files}" var="file" rowKeyVar="row">
<rich:panel bodyClass="rich-laguna-panel-no-header">
<h:panelGrid columns="2">
<a4j:mediaOutput element="img" mimeType="image/jpeg" createContent="#{fileUploadBean.paint}"
value="#{row}" style="width:100px; height:100px;" cacheable="false">
<f:param value="#{fileUploadBean.timeStamp}" name="time" />
</a4j:mediaOutput>
<h:panelGrid columns="2">
<h:outputText value="File Name:" />
<h:outputText value="#{file.name}" />
<h:outputText value="File Length(bytes):" />
<h:outputText value="#{file.length}" />
</h:panelGrid>
</h:panelGrid>
</rich:panel>
</rich:dataGrid>
</rich:panel>
<br/>
<a4j:commandButton action="#{fileUploadBean.clearUploadData}" render="info, upload" value="Clear Uploaded Data"
rendered="#{fileUploadBean.size>0}" />
</h:panelGrid>
</h:panelGrid>
</h:form>
</h:body>
</ui:composition>
</html>
This is my FileUploadBean Class
package com.acc.upload;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import com.acc.fileupload.utils.FileUploadEvent;
import com.acc.fileupload.utils.UploadedFile;
#ManagedBean(name = "fileUploadBean")
#SessionScoped
public class FileUploadBean{
private ArrayList<File> files = new ArrayList<File>();
private int uploadsAvailable = 5;
private boolean autoUpload = false;
private boolean useFlash = true;
public int getSize() {
if (getFiles().size()>0){
return getFiles().size();
}else
{
return 0;
}
}
public FileUploadBean() {
}
public void paint(OutputStream stream, Object object) throws IOException {
stream.write(getFiles().get((Integer)object).getData());
}
public void listener(FileUploadEvent event) throws Exception{
UploadedFile item = event.getUploadedFile();
File file = new File();
file.setLength(item.getData().length);
file.setName(item.getName());
file.setData(item.getData());
files.add(file);
uploadsAvailable--;
}
public String clearUploadData() {
files.clear();
setUploadsAvailable(5);
return null;
}
public long getTimeStamp(){
return System.currentTimeMillis();
}
public ArrayList<File> getFiles() {
return files;
}
public void setFiles(ArrayList<File> files) {
this.files = files;
}
public int getUploadsAvailable() {
return uploadsAvailable;
}
public void setUploadsAvailable(int uploadsAvailable) {
this.uploadsAvailable = uploadsAvailable;
}
public boolean isAutoUpload() {
return autoUpload;
}
public void setAutoUpload(boolean autoUpload) {
this.autoUpload = autoUpload;
}
public boolean isUseFlash() {
return useFlash;
}
public void setUseFlash(boolean useFlash) {
this.useFlash = useFlash;
}
}
File Class
package com.acc.upload;
public class File {
private String Name;
private String mime;
private long length;
private byte[] data;
public byte[] getData() {
return data;
}
public void setData(byte[] data) {
this.data = data;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
int extDot = name.lastIndexOf('.');
if(extDot > 0){
String extension = name.substring(extDot +1);
if("png".equals(extension)){
mime="image/png";
}else {
mime = "img/unknown";
}
}
}
public long getLength() {
return length;
}
public void setLength(long length) {
this.length = length;
}
public String getMime(){
return mime;
}
}
Thanks a lot.Now that error is gone for me .
I set the createTemp files to true in web.xml but i am unable to find the uploaded file in the temp folder in my local system.And also is it possible to store the uploaded file to a desired location in our local system by changing any settings in web.xml file ?
Please help in these two issues.
Regarding your buttons icons problem, I'm pretty sure you don't manage yourself the skin of RichFaces, so you can remove this from your web.xml :
<context-param>
<param-name>org.richfaces.skin</param-name>
<param-value>#{skinBean.skin}</param-value>
</context-param>
RichFaces will now use the default skin option.
According to your comment, you where missing h:head which is mandatory in order to include necessary resources CSS and JavaScript for RichFaces.
Moreover, your last problem is related to your imports that are bad :
import com.acc.fileupload.utils.FileUploadEvent;
import com.acc.fileupload.utils.UploadedFile;
should be replaced for :
import org.richfaces.event.FileUploadEvent;
import org.richfaces.model.UploadedFile;
Other info :
The example you are based on is from RichFaces 3.3.3 (this is shown in the footer). Double check your view code with this example for RichFaces 4.3.2.
I also get this problem with richface 4.0.0 and spring 4. When upload the file I alway get this error message "Request prolog cannot be read".
And I solved this problem by: set multipart resolever to
instead of CommonsMultipartResolver
for DispatcherServlet. Because the CommonsMultipartResolver of spring is not consistent with richface 4.0.0
Hope this help!
I was trying to create a secure login page with jsf, and I used these code snippets as the solution, found in this question. My problem is, that I can access the /restricted/secret.xhtml without logging in, there is no redirect it's like the filter is not applied, because if I go directly to the /restricted/secret.xhtml the #{user.loggedIn} evaluates to false and I still can view the page. Here is my code:
AuthFilter.java
public class AuthFilter implements Filter {
private FilterConfig config;
#Override
public void destroy() {
this.config = null;
}
#Override
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain ch) throws IOException, ServletException {
HttpSession s = ((HttpServletRequest) req).getSession();
if (s.getAttribute(UserBean.CREDENTIAL)==null)
{
((HttpServletResponse) resp).sendRedirect("/login.faces");
}else
{
ch.doFilter(req, resp);
}
}
#Override
public void init(FilterConfig config) throws ServletException {
this.config = config;
}
}
UserBean.java
#ManagedBean(name="user")
#SessionScoped
public class UserBean implements Serializable {
private String name;
private String password;
protected static final String CREDENTIAL = "ontherun";
private static final long serialVersionUID = 1L;
public String getName()
{
return this.name;
}
public void setName(String newName)
{
this.name = newName;
}
public String getPassword()
{
return this.password;
}
public void setPassword(String newPassword)
{
this.password = newPassword;
}
public boolean isLoggedIn()
{
return FacesContext.getCurrentInstance().getExternalContext()
.getSessionMap().get(CREDENTIAL) != null;
}
public String logout() {
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove(CREDENTIAL);
return null;
}
public String login()
{
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(CREDENTIAL, this.name);
return "secret";
}
}
Here is my login.xhtml ; the page works correctly, so there is no problem with the template file.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html">
<head><title>IGNORED</title></head>
<body>
<ui:composition template="/templates/masterLayoutTemplate.xhtml">
<ui:define name="windowTitle">
#{msgs.window_title}
</ui:define>
<ui:define name="header">
<ui:include src="/sections/login/header.xhtml"></ui:include>
</ui:define>
<ui:define name="footer">
<ui:include src="/sections/login/footer.xhtml"></ui:include>
</ui:define>
<ui:define name="content">
<h:form>
<h:panelGrid columns="2">
#{msgs.namePrompt}
<h:inputText id="name" value="#{user.name}"/>
#{msgs.passwordPrompt}
<h:inputSecret id="password" value="#{user.password}"/>
</h:panelGrid>
<p>
<h:commandButton value="#{msgs.loginButtonText}" action="#{user.login }"/>
</p>
<p>
You are logged in : #{user.loggedIn}
</p>
<p>
<h:commandButton value="logout" action="#{user.logout }"/>
</p>
</h:form>
</ui:define>
</ui:composition>
</body>
</html>
Here is the secret.xhtml which is supposed to be restricted:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html">
<head><title>IGNORED</title></head>
<body>
<ui:composition template="/templates/masterLayoutTemplate.xhtml">
<ui:define name="windowTitle">
#{msgs.window_title}
</ui:define>
<ui:define name="content">
<h:head></h:head>
<h:body>
<p>You are #{user.loggedIn}</p>
</h:body>
</ui:define>
</ui:composition>
</body>
</html>
And here are my config files: web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
<display-name>OnTheRun</display-name>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>faces/index.xhtml</welcome-file>
</welcome-file-list>
<filter>
<filter-name>AuthFilter</filter-name>
<filter-class>on.run.AuthFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AuthFilter</filter-name>
<url-pattern>/restricted/*</url-pattern>
</filter-mapping>
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
</web-app>
and faces-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<faces-config
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
version="2.0">
<application>
<resource-bundle>
<base-name>on.run.messages</base-name>
<var>msgs</var>
</resource-bundle>
</application>
<navigation-rule>
<from-view-id>/index.xhtml</from-view-id>
<navigation-case>
<from-outcome>login</from-outcome>
<to-view-id>/profile.xhtml</to-view-id>
<redirect/>
</navigation-case>
</navigation-rule>
<navigation-rule>
<from-view-id>/login.xhtml</from-view-id>
<navigation-case>
<from-outcome>secret</from-outcome>
<to-view-id>/restricted/secret.xhtml</to-view-id>
<redirect/>
</navigation-case>
</navigation-rule>
</faces-config>
My directory structure looks like this: dirStruct 2
You've mapped FacesServlet on /faces/* instead of *.xhtml. So all JSF requests will have the /faces prefix in the URL. But you've mapped the AuthFilter on /restricted/* instead of /faces/restricted/*, so it will never kick in on /faces/* URLs.
You can solve this in 2 ways:
Map FacesServlet on *.xhtml instead of on /faces/*. This has the additional advantage that the enduser won't ever be able to see the raw JSF source code when the enduser purposefully removes the /faces path from the URL in browser address bar.
Map AuthFilter on /faces/restricted/* instead of on /restricted/*.
I personally recommend the first way. You end up with a shorter and nicer URL and you immediately also prevent the JSF source code leak.
I am to do a web application with JSF, just to get and put a value from the JSF to bean and vice versa. I think I have done everything properly but when I start the server and try to access my first page I get the following error
SEVERE: Servlet.service() for servlet [jsp] in context with path [/SimpleJSF] threw exception [/greeting.jsp (line: 20, column: 85) #{...} is not allowed in template text] with root cause
org.apache.jasper.JasperException: /greeting.jsp (line: 20, column: 85) #{...} is not allowed in template text
I am using Eclipse Helios with JDK 1.6 , apache Tomcat 7 and JSF 2.0 framework
Here is my code snippet
greeting.jsp
<?xml version="1.0" encoding="ISO-8859-1" ?>
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>Guess Number Facelets Application</title>
</h:head>
<h:body>
<h:form>
<h2>
Hi, my name is Duke. I am thinking of a number from
0 to 10.
Can you guess it?
</h2>
<p><h:inputText id="userNo" title="Type a number from 0 to 10:" value="#{resultNumber.userNumber}">
<f:validateLongRange minimum="#{resultNumber.minimum}" maximum="#{resultNumber.maximum}"/>
</h:inputText>
<h:commandButton id="submit" value="Submit" action="response.jsp"/>
</p>
<h:message showSummary="true" showDetail="false" style="color: #d20005; font-family: 'New Century Schoolbook', serif; font-style: oblique; text-decoration: overline"
id="errors1"
for="userNo"/>
</h:form>
</h:body>
</html>
response.jsp
<?xml version="1.0" encoding="ISO-8859-1" ?>
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Insert title here</title>
<h:head>
<title>Guess Number Facelets Application</title>
</h:head>
<h:body>
<h:form>
<h2>
<h:outputText id="result" value="#{resultNumber.response}"/>
</h2>
<h:commandButton id="back" value="Back" action="greeting.xhtml"/>
</h:form>
</h:body>
</html>
Java bean, ResultNumber.java
package guessNumber;
import java.util.Random;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
/**
* Session Bean implementation class ResultNumber
*/
#Stateless(mappedName = "resultNumber")
#LocalBean
public class ResultNumber {
Integer randomInt = null;
Integer userNumber = null;
String response = null;
private long maximum=10;
private long minimum=0;
public ResultNumber() {
Random randomGR = new Random();
randomInt = new Integer(randomGR.nextInt(10));
System.out.println("Duke's number: " + randomInt);
}
public void setUserNumber(Integer user_number) {
userNumber = user_number;
}
public Integer getUserNumber() {
return userNumber;
}
public String getResponse() {
if ((userNumber != null) && (userNumber.compareTo(randomInt) == 0)) {
return "Yay! You got it!";
} else {
return "Sorry, " + userNumber + " is incorrect.";
}
}
public long getMaximum() {
return (this.maximum);
}
public void setMaximum(long maximum) {
this.maximum = maximum;
}
public long getMinimum() {
return (this.minimum);
}
public void setMinimum(long minimum) {
this.minimum = minimum;
}
}
Now for the configuration files
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
<display-name>SimpleJSF</display-name>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<context-param>
<description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
<context-param>
<param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
<param-value>resources.application</param-value>
</context-param>
<listener>
<listener-class>com.sun.faces.config.ConfigureListener</listener-class>
</listener>
<welcome-file-list>
<welcome-file>faces/greeting.jsp</welcome-file>
</welcome-file-list>
</web-app>
facet-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<faces-config
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
version="2.0">
<managed-bean>
<managed-bean-name>resultNumber</managed-bean-name>
<managed-bean-class>guessNumber.ResultNumber</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
</faces-config>
In JSF 2.0, JSP is been deprecated as view technology and succeeded by Facelets. You need to rename your .jsp files to .xhtml files. In your case you also need to remove the entire <%# page %> line in both JSPs. Then you need to invoke them with the .xhtml extension in the URL.
Further, you also need to remove the ConfigureListener from web.xml and you need to rename the JSP welcome file to XHTML. I'd also suggest to use *.xhtml instead of /faces/* as FacesServlet URL pattern. This way you don't need to put a /faces/* in URLs everytime. Finally you need to remove the bean from faces-config.xml and annotate the bean as follows instead of those javax.ejb annotations:
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
#ManagedBean
#RequestScoped
public class ResultNumber {
After all, it seems that you were reading JSF 1.x tutorials and mixing it up with JSF 2.x. You should be extremely careful what JSF version the JSF book/tutorial you're reading target. Since JSF 2.0 a lot of things are done differently.
You are using .jsp files,so you should import the taglibs manually.Add these two lines right above your opening html tag.
<%# taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%# taglib uri="http://java.sun.com/jsf/html" prefix="h"%>