Статьи

Полное веб-приложение Tomcat JSF Primefaces JPA Hibernate — Часть 1

Мы создали этот пост, который покажет, как создать полноценное веб-приложение, используя следующие инструменты: Tomcat7, JSF2 (Facelets и библиотеки) с Primefaces (с AutoComplete), JPA / Hibernate (с отношением NxN), Войти через Filter.If вы чтобы увидеть полное веб-приложение с JSF + EJB + JPA + JBoss 7, нажмите здесь .

Для запуска кода этого поста вам понадобятся артефакты ниже (все файлы jar вы найдете на последней странице этого поста):

Вы можете использовать любую базу данных, какую захотите, вам понадобится определенный драйвер базы данных и отредактировать URL-соединение в файле persistence.xml.

В конце этого поста вы найдете исходный код со всеми необходимыми библиотеками для скачивания.

Что вы увидите сегодня в этом посте:

  • Сущности классов модели. Отношение NxN (@ManyToMany), NamedQueries с JoinFetch, Enum в качестве атрибута.
  • Универсальный DAO, методы транзакций приложения, универсальные методы для заполнения параметров запроса.
  • Фасады транзакций, используя метод findReferenceOnly, заботятся, используя метод entityManager.merge ().
  • Фильтры.
  • ManagedBeans. Как внедрить ManagedBean в другой ManagedBean, наблюдения за @ViewScoped.
  • JSFMessageUtil.
  • Файл настроек: log4j.properties, messages.properties.
  • HTML-страницы, Facelets.
  • Primefaces AutoComplete, JSF-конвертер с «forClass».
  • Самый простой способ использовать CSS / javascript / images с JSF.
  • «Web.xml» конфигурации.
  • Повышение безопасности вашего приложения.
  • Запуск приложения.

Приложение, которое вы найдете здесь, будет иметь CRUD для собак и людей (создание, чтение, обновление и удаление); только АДМИН будет иметь доступ к собаке CRUD. Перед запуском этого приложения вы должны создать базу данных с именем «JSFCrudDB» .

Модельные классы

Следующие классы являются модельными классами, и они должны быть в пакете «com.model»:

1
2
3
4
5
package com.model;
 
public enum Role {
 ADMIN, USER;
}
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package com.model;
 
import java.io.Serializable;
 
import javax.persistence.*;
 
@Entity
@Table(name = 'USERS')
@NamedQuery(name = 'User.findUserByEmail', query = 'select u from User u where u.email = :email')
public class User implements Serializable {
 private static final long serialVersionUID = 1L;
 
 public static final String FIND_BY_EMAIL = 'User.findUserByEmail';
 
 @Id
 @GeneratedValue(strategy = GenerationType.AUTO)
 private int id;
 
 @Column(unique = true)
 private String email;
 private String password;
 private String name;
 @Enumerated(EnumType.STRING)
 private Role role;
 
 // get and set
 
 public boolean isAdmin() {
  return Role.ADMIN.equals(role);
 }
 
 public boolean isUser() {
  return Role.USER.equals(role);
 }
 
 @Override
 public int hashCode() {
  return getId();
 }
 
 @Override
 public boolean equals(Object obj) {
  if (obj instanceof User) {
   User user = (User) obj;
   return user.getId() == id;
  }
 
  return false;
 }
}
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package com.model;
 
import java.io.Serializable;
import java.util.List;
 
import javax.persistence.*;
 
@Entity
@NamedQuery(name = 'Person.findUserByIdWithDogs', query = 'select p from Person p left join fetch p.dogs where p.id = :personId')
public class Person implements Serializable {
 
 private static final long serialVersionUID = 1L;
 public static final String FIND_USER_BY_ID_WITH_DOGS = 'Person.findUserByIdWithDogs';
 
 @Id
 @GeneratedValue(strategy = GenerationType.AUTO)
 private int id;
 private int age;
 private String name;
 
 @ManyToMany
 private List<Dog> dogs;
 
 // get and set
 
 @Override
 public int hashCode() {
  return id;
 }
 
 @Override
 public boolean equals(Object obj) {
  if (obj instanceof Person) {
   Person person = (Person) obj;
   return person.getId() == id;
  }
 
  return false;
 }
}
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package com.model;
 
import java.io.Serializable;
import java.util.List;
 
import javax.persistence.*;
 
@Entity
public class Dog implements Serializable{
 private static final long serialVersionUID = 1L;
 
 @Id
 @GeneratedValue(strategy = GenerationType.AUTO)
 private int id;
 private int age;
 private String name;
 
 @ManyToMany(mappedBy='dogs')
 private List<Person> persons;
 
 // get and set
 
 @Override
 public int hashCode() {
  return id;
 }
 
 @Override
 public boolean equals(Object obj) {
  if (obj instanceof Dog) {
   Dog dog = (Dog) obj;
   return dog.getId() == id;
  }
 
  return false;
 }
 
 @Override
 public String toString() {
  return name;
 }
}

О приведенном выше коде:

  • Класс Person имеет именованный запрос «Person.findUserByIdWithDogs». Этот запрос с готовностью загрузит список Dog класса Person. Если мы попытаемся получить доступ к списку собак без транзакции и этот запрос произойдет исключение LazyInitializationException. Другим решением этой ситуации будет шаблон OpenSessionInView; этот шаблон может генерировать эффект N + 1 запросов. Если вы хотите узнать больше об этом исключении, нажмите здесь.
  • Очень легко сопоставить Enum с JPA / Hibernate. Как вы можете видеть, есть опция с аннотацией @Enumerated, которая устанавливает поле таблицы базы данных как String. Если вы хотите узнать больше об этой аннотации и посмотреть, как отобразить Enum как ORDINAL, нажмите здесь .
  • Всегда переопределяйте методы equals / hashCode. Эти методы часто вызываются несколькими структурами. Многие «ошибки» Primefaces были решены с помощью этих методов.

Вам нужно будет создать файл «persistence.xml» внутри папки «src / META-INF»:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version='1.0' encoding='UTF-8'?>
 
<persistence version='2.0'
 
 <persistence-unit name='JSFCrudPU' transaction-type='RESOURCE_LOCAL'>
  <provider>org.hibernate.ejb.HibernatePersistence</provider>
 
  <properties>
   <property name='javax.persistence.jdbc.driver' value='org.postgresql.Driver' />
   <property name='javax.persistence.jdbc.url' value='jdbc:postgresql://localhost:5432/JSFCrudDB' />
   <property name='javax.persistence.jdbc.user' value='postgres' />
   <property name='javax.persistence.jdbc.password' value='postgres' />
   <property name='hibernate.dialect' value='org.hibernate.dialect.PostgreSQLDialect' />
   <property name='hibernate.connection.shutdown' value='true' />
   <property name='hibernate.hbm2ddl.auto' value='update' />
   <property name='hibernate.show_sql' value='false' />
            <property name='hibernate.format_sql' value='false'/>
  </properties>
 </persistence-unit>
</persistence>

О приведенном выше коде:

  • Свойство «hibernate.hbm2ddl.auto» со значением «update» указывает JPA на обновление, когда это необходимо, базы данных в соответствии с классами модели. Не рекомендуется оставлять эту опцию как « обновление » или с любым другим значением, которое может обновить базу данных производства / клиента. Всегда полезно использовать опцию « validate » в производственной среде, а также создавать и выполнять сценарий sql вручную.
  • Свойства hibernate.show_sql и hibernate.format_sql используются для отображения запроса в консоли. В файле log4j.properties (стр. 08) есть опция, которая позволит отображать значения параметров запроса.

DAO

В пакете «com.dao» вам нужно будет создать следующие классы:

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package com.dao;
 
import java.io.Serializable;
import java.util.*;
import java.util.Map.*;
 
import javax.persistence.*;
import javax.persistence.criteria.CriteriaQuery;
 
abstract class GenericDAO<T> implements Serializable {
 private static final long serialVersionUID = 1L;
 
 private static final EntityManagerFactory emf = Persistence.createEntityManagerFactory('JSFCrudPU');
 private EntityManager em;
 
 private Class<T> entityClass;
 
 public void beginTransaction() {
  em = emf.createEntityManager();
 
  em.getTransaction().begin();
 }
 
 public void commit() {
  em.getTransaction().commit();
 }
 
 public void rollback() {
  em.getTransaction().rollback();
 }
 
 public void closeTransaction() {
  em.close();
 }
 
 public void commitAndCloseTransaction() {
  commit();
  closeTransaction();
 }
 
 public void flush() {
  em.flush();
 }
 
 public void joinTransaction() {
  em = emf.createEntityManager();
  em.joinTransaction();
 }
 
 public GenericDAO(Class<T> entityClass) {
  this.entityClass = entityClass;
 }
 
 public void save(T entity) {
  em.persist(entity);
 }
 
 public void delete(T entity) {
  T entityToBeRemoved = em.merge(entity);
 
  em.remove(entityToBeRemoved);
 }
 
 public T update(T entity) {
  return em.merge(entity);
 }
 
 public T find(int entityID) {
  return em.find(entityClass, entityID);
 }
 
 public T findReferenceOnly(int entityID) {
  return em.getReference(entityClass, entityID);
 }
 
 // Using the unchecked because JPA does not have a
 // em.getCriteriaBuilder().createQuery()<T> method
 @SuppressWarnings({ 'unchecked', 'rawtypes' })
 public List<T> findAll() {
  CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
  cq.select(cq.from(entityClass));
  return em.createQuery(cq).getResultList();
 }
 
 // Using the unchecked because JPA does not have a
 // query.getSingleResult()<T> method
 @SuppressWarnings('unchecked')
 protected T findOneResult(String namedQuery, Map<String, Object> parameters) {
  T result = null;
 
  try {
   Query query = em.createNamedQuery(namedQuery);
 
   // Method that will populate parameters if they are passed not null and empty
   if (parameters != null && !parameters.isEmpty()) {
    populateQueryParameters(query, parameters);
   }
 
   result = (T) query.getSingleResult();
 
  } catch (NoResultException e) {
   System.out.println('No result found for named query: ' + namedQuery);
  } catch (Exception e) {
   System.out.println('Error while running query: ' + e.getMessage());
   e.printStackTrace();
  }
 
  return result;
 }
 
 private void populateQueryParameters(Query query, Map<String, Object> parameters) {
  for (Entry<String, Object> entry : parameters.entrySet()) {
   query.setParameter(entry.getKey(), entry.getValue());
  }
 }
}
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
package com.dao;
 
import java.util.*;
 
import com.model.Person;
 
public class PersonDAO extends GenericDAO<Person> {
 
 private static final long serialVersionUID = 1L;
 
 public PersonDAO() {
  super(Person.class);
 }
 
 public Person findPersonWithAllDogs(int personId) {
  Map<String, Object> parameters = new HashMap<String, Object>();
  parameters.put('personId', personId);
 
  return super.findOneResult(Person.FIND_USER_BY_ID_WITH_DOGS, parameters);
 }
}
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
package com.dao;
 
import java.util.*;
 
import com.model.User;
 
public class UserDAO extends GenericDAO<User> {
 
 private static final long serialVersionUID = 1L;
 
 public UserDAO() {
        super(User.class);
    }
 
    public User findUserByEmail(String email){
        Map<String, Object> parameters = new HashMap<String, Object>();
        parameters.put('email', email);    
 
        return super.findOneResult(User.FIND_BY_EMAIL, parameters);
    }
}
01
02
03
04
05
06
07
08
09
10
11
12
package com.dao;
 
import com.model.Dog;
 
public class DogDAO extends GenericDAO<Dog> {
 
 private static final long serialVersionUID = 1L;
 
 public DogDAO() {
        super(Dog.class);
    }
}

О приведенном выше коде:

  • В классах DAO есть методы, позволяющие фасадам контролировать транзакции. Этот шаблон применяется, чтобы избежать шаблона OpenSessionInView; шаблон OpenSessionInView может вызвать эффект N + 1 запросов. С транзакцией, контролируемой разработчиком, легче понять поток транзакций, но у нас есть более подробный код. Если вы хотите узнать больше об OpenSessionInView и эффекте N + 1, вы можете нажать здесь .
  • Вы найдете метод с именем «populateQueryParameters» в классе GenericDAO. Этот метод будет динамически заполнять все параметры запроса, если это необходимо. Классы PersonDAO и UserDAO имеют пример кода того, как вызвать этот метод.

Фасады

В пакете «com.facade» вам нужно будет создать классы ниже:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
package com.facade;
 
import com.dao.UserDAO;
import com.model.User;
 
public class UserFacade {
 private UserDAO userDAO = new UserDAO();
 
 public User isValidLogin(String email, String password) {
  userDAO.beginTransaction();
  User user = userDAO.findUserByEmail(email);
 
  if (user == null || !user.getPassword().equals(password)) {
   return null;
  }
 
  return user;
 }
}
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package com.facade;
 
import java.io.Serializable;
import java.util.List;
 
import com.dao.DogDAO;
import com.model.Dog;
 
public class DogFacade implements Serializable{
 private static final long serialVersionUID = 1L;
 
 private DogDAO dogDAO = new DogDAO();
 
 public void createDog(Dog dog) {
  dogDAO.beginTransaction();
  dogDAO.save(dog);
  dogDAO.commitAndCloseTransaction();
 }
 
 public void updateDog(Dog dog) {
  dogDAO.beginTransaction();
  Dog persistedDog = dogDAO.find(dog.getId());
  persistedDog.setAge(dog.getAge());
  persistedDog.setName(dog.getName());
  dogDAO.update(persistedDog);
  dogDAO.commitAndCloseTransaction();
 }
 
 public Dog findDog(int dogId) {
  dogDAO.beginTransaction();
  Dog dog = dogDAO.find(dogId);
  dogDAO.closeTransaction();
  return dog;
 }
 
 public List<Dog> listAll() {
  dogDAO.beginTransaction();
  List<Dog> result = dogDAO.findAll();
  dogDAO.closeTransaction();
  return result;
 }
 
 public void deleteDog(Dog dog) {
  dogDAO.beginTransaction();
  Dog persistedDog = dogDAO.findReferenceOnly(dog.getId());
  dogDAO.delete(persistedDog);
  dogDAO.commitAndCloseTransaction();
 }
}
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
package com.facade;
 
import java.io.Serializable;
import java.util.List;
 
import com.dao.DogDAO;
import com.dao.PersonDAO;
import com.model.Dog;
import com.model.Person;
 
public class PersonFacade implements Serializable {
 private static final long serialVersionUID = 1L;
 
 private PersonDAO personDAO = new PersonDAO();
 private DogDAO dogDAO = new DogDAO();
 
 public void createPerson(Person person) {
  personDAO.beginTransaction();
  personDAO.save(person);
  personDAO.commitAndCloseTransaction();
 }
 
 public void updatePerson(Person person) {
  personDAO.beginTransaction();
  Person persistedPerson = personDAO.find(person.getId());
  persistedPerson.setName(person.getName());
  persistedPerson.setAge(person.getAge());
  personDAO.commitAndCloseTransaction();
 }
 
 public void deletePerson(Person person){
  personDAO.beginTransaction();
  Person persistedPersonWithIdOnly = personDAO.findReferenceOnly(person.getId());
  personDAO.delete(persistedPersonWithIdOnly);
  personDAO.commitAndCloseTransaction();
 
 }
 
 public Person findPerson(int personId) {
  personDAO.beginTransaction();
  Person person = personDAO.find(personId);
  personDAO.closeTransaction();
  return person;
 }
 
 public List<Person> listAll() {
  personDAO.beginTransaction();
  List<Person> result = personDAO.findAll();
  personDAO.closeTransaction();
 
  return result;
 }
 
 public Person findPersonWithAllDogs(int personId) {
  personDAO.beginTransaction();
  Person person = personDAO.findPersonWithAllDogs(personId);
  personDAO.closeTransaction();
  return person;
 }
 
 public void addDogToPerson(int dogId, int personId) {
  personDAO.beginTransaction();
  dogDAO.joinTransaction();
  Dog dog = dogDAO.find(dogId);
  Person person = personDAO.find(personId);
  person.getDogs().add(dog);
  dog.getPerson().add(person);
  personDAO.commitAndCloseTransaction();
 }
 
 public void removeDogFromPerson(int dogId, int personId) {
  personDAO.beginTransaction();
  dogDAO.joinTransaction();
  Dog dog = dogDAO.find(dogId);
  Person person = personDAO.find(personId);
  person.getDogs().remove(dog);
  dog.getPerson().remove(person);
  personDAO.commitAndCloseTransaction();
 }
}

О приведенном выше коде:

  • Каждая транзакция контролируется разработчиком. Разработчик несет ответственность за то, чтобы никогда не забывать открытую транзакцию.
  • Класс PersonFacade использует метод с именем « findReferenceOnly ». Этот метод имеет лучшую производительность, чем метод « найти » с операциями, которые включают только операции, в которых требуется только идентификатор объекта. Запрос будет запущен в базе данных, чтобы получить только идентификатор этой сущности. Если вызывается какой-либо другой атрибут, в базе данных будет запущен новый запрос для получения этой информации. Согласно книге « Pro JPA 2: Освоение API персистентности Java ™ », этот метод также можно использовать для редактирования элементов в списке. Например, в методе Person.addDoAgToPerson метод « find » можно заменить на « findReferenceOnly »
  • Оба метода « Person.addDogToPerson » и « Person.removeDogFromPerson » вызывают метод « joinTransaction » в классе DogDAO. EntityManager в DogDAO будет использовать ту же транзакцию, которая была запущена в PersonDAO.

Забота о EntityManager.merge ()

Посмотрите на код ниже:

Было бы проще просто вызвать метод, подобный этому: « entityManager.merge (dog) », вместо того, чтобы запрашивать постоянный объект и обновлять данные. Если вы вызовете метод слияния в файле, полученном из представления, вы можете повредить целостность данных вашей базы данных. Разработчик должен позаботиться об этом методе слияния; если ленивое отношение не загружено и это значение равно нулю в объединенном объекте, JPA / Hibernate сотрет это отношение в базе данных. Например, если разработчик вызывает метод entityManager.merge (dog) и dog.getPersons () == null, JPA / Hibernate удалит все отношения между ними в базе данных.

Лучше всего найти объект в базе данных, чем редактировать его.

В этом проекте объект был загружен из базы данных, и он находится в отключенном состоянии; для этой конкретной ситуации, когда вы обнаружите, что объект отсоединен, а ленивое отношение не равно нулю, JPA не сотрет связь с данными базы данных. Если объект был создан вручную и отношение имеет значение List <Person> == null, JPA удалил бы данные базы данных.

Фильтр

В пакете «com.filter» вам нужно создать следующие классы:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.filter;
 
import java.io.IOException;
 
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
 
public class AbstractFilter {
 
 public AbstractFilter() {
  super();
 }
 
 protected void doLogin(ServletRequest request, ServletResponse response, HttpServletRequest req) throws ServletException, IOException {
  RequestDispatcher rd = req.getRequestDispatcher('/pages/public/login.xhtml');
  rd.forward(request, response);
 }
 
 protected void accessDenied(ServletRequest request, ServletResponse response, HttpServletRequest req) throws ServletException, IOException {
  RequestDispatcher rd = req.getRequestDispatcher('/pages/public/accessDenied.xhtml');
  rd.forward(request, response);
 }
}
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package com.filter;
 
import java.io.IOException;
import java.util.*;
 
import javax.servlet.*;
import javax.servlet.http.*;
 
import com.model.User;
 
/**
 * Servlet Filter implementation class UserCheckFilter
 */
public class LoginCheckFilter extends AbstractFilter implements Filter {
 private static List<String> allowedURIs;
 
 /**
  * @see Filter#init(FilterConfig)
  */
 public void init(FilterConfig fConfig) throws ServletException {
  if(allowedURIs == null){
   allowedURIs = new ArrayList<String>();
   allowedURIs.add(fConfig.getInitParameter('loginActionURI'));
   allowedURIs.add('/JSFCrudApp/javax.faces.resource/main.css.xhtml');
   allowedURIs.add('/JSFCrudApp/javax.faces.resource/theme.css.xhtml');
   allowedURIs.add('/JSFCrudApp/javax.faces.resource/primefaces.js.xhtml');
   allowedURIs.add('/JSFCrudApp/javax.faces.resource/primefaces.css.xhtml');
   allowedURIs.add('/JSFCrudApp/javax.faces.resource/jquery/jquery.js.xhtml');
   allowedURIs.add('/JSFCrudApp/javax.faces.resource/messages/messages.png.xhtml');
   allowedURIs.add('/JSFCrudApp/javax.faces.resource/images/ui-icons_2e83ff_256x240.png.xhtml');
   allowedURIs.add('/JSFCrudApp/javax.faces.resource/images/ui-icons_38667f_256x240.png.xhtml');
  }
 }
 
 /**
  * @see Filter#destroy()
  */
 public void destroy() {
 }
 
 /**
  * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
  */
 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
  HttpServletRequest req = (HttpServletRequest) request;
  HttpSession session = req.getSession();
 
  if (session.isNew()) {
   doLogin(request, response, req);
   return;
  }
 
  User user = (User) session.getAttribute('user');
 
  if (user == null && !allowedURIs.contains(req.getRequestURI())) {
   System.out.println(req.getRequestURI());
   doLogin(request, response, req);
   return;
  }
 
  chain.doFilter(request, response);
 }
}
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.filter;
 
import java.io.IOException;
 
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
 
import com.model.User;
 
public class AdminPagesFilter extends AbstractFilter implements Filter {
 
 @Override
 public void destroy() {
 
 }
 
 @Override
 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
  HttpServletRequest req = (HttpServletRequest) request;
  User user = (User) req.getSession(true).getAttribute('user');
 
  if (!user.isAdmin()) {
   accessDenied(request, response, req);
   return;
  }
 
  chain.doFilter(request, response);
 }
 
 @Override
 public void init(FilterConfig arg0) throws ServletException {
 
 }
}
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.filter;
 
import java.io.IOException;
 
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
 
import com.model.User;
 
public class DefaultUserPagesFilter extends AbstractFilter implements Filter {
 
 @Override
 public void destroy() {
 
 }
 
 @Override
 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
  HttpServletRequest req = (HttpServletRequest) request;
  User user = (User) req.getSession(true).getAttribute('user');
 
  if(!user.isUser() && !user.isAdmin()){
   accessDenied(request, response, req);
   return;
  }
 
  chain.doFilter(request, response);
 }
 
 @Override
 public void init(FilterConfig arg0) throws ServletException {
 
 }
}

О приведенном выше коде:

  • Классы, которые реализуют интерфейс Filter, отвечают за Авторизацию и Аутентификацию пользователя. На странице 13 будет больше информации о том, зачем нам проверять, вошел ли пользователь в систему и его роль при каждом запросе.
  • Метод « fConfig.getInitParameter (« loginActionURI »); ”, Который вызывается внутри класса LoginCheckFilter, загружает свойство из файла« web.xml ». Свойство loginActionURI имеет значение, указывающее страницу входа в Фильтр; Фильтр будет использовать это свойство, чтобы разрешить каждому пользователю (зарегистрированному или нет) доступ к этой конкретной странице (значение свойства вы увидите на странице 12). Это значение свойства добавляется в список URL-адресов, которые можно вызывать без необходимости входа в систему. Рекомендуется иметь этот список разрешенных URL-адресов в файле «web.xml», но для товара в этот пост был добавлен только один товар, чтобы показать, как это сделать.
  • Каждый фильтр отслеживает каталог, к которому пользователь может получить доступ. Другой подход заключается в том, чтобы иметь файл со всеми разрешенными URL-адресами и разрешенными ролями, например, «JSFCrud / protected / manager; admin-manager».

Продолжить ко второй части .

Ссылка: полноценное веб-приложение с Tomcat JSF Primefaces JPA Hibernate от нашего партнера JCG Хеберта Коэльо в блоге uaiHebert .