Статьи

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

Primefaces AutoComplete, JSF Converter

Этот пост продолжается с части 1 и части 2 .

JSF имеет инструмент Converter, который помогает нам получить некоторые данные из пользовательского представления и преобразовать их в объект, загруженный из базы данных или из кэша.

В пакете «com.converter» создайте следующий класс:

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
package com.converter;
 
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.*;
 
import com.facade.DogFacade;
import com.model.Dog;
 
@FacesConverter(forClass = com.model.Dog.class)
public class DogConverter implements Converter {
 
 @Override
 public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) {
  DogFacade dogFacade = new DogFacade();
  int dogId;
 
  try {
   dogId = Integer.parseInt(arg2);
  } catch (NumberFormatException exception) {
   throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, 'Type the name of a Dog and select it (or use the dropdow)', 'Type the name of a Dog and select it (or use the dropdow)'));
  }
 
  return dogFacade.findDog(dogId);
 }
 
 @Override
 public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) {
 
  if (arg2 == null) {
   return '';
  }
  Dog dog = (Dog) arg2;
  return String.valueOf(dog.getId());
 }
}

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

  • В аннотации @Converter есть атрибут с именем «forClass». Этот атрибут указывает de JSF, что все классы, указанные в «forClass», будут вызывать конвертер. DogConverter помечается как « forClass = com.model.Dog.class », каждый раз, когда JSF требуется конвертер для класса Dog, JSF будет вызывать DogConverter. Нет необходимости писать какой-либо код в файле «web.xml».

Код конвертера требуется в автозаполнении Primefaces. Ниже вы увидите, как легко использовать автозаполнение:

personUpdateDialog.xhtml

PersonMB.java

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

  • Функция автозаполнения имеет несколько параметров, таких как минимальная длина запроса, задержка для запуска запроса, раскрывающийся список для отображения всех значений и многое другое. Стоит увидеть все варианты: http://primefaces.org/showcase/ui/autoCompleteBasic.jsf и http://primefaces.org/showcase/ui/autocompleteHome.jsf
  • Метод « complete » имеет кэш значений, найденных в базе данных. Метод переходит к каждому объекту List <Dog> и сохраняет совпадения.
  • Обратите внимание, что конвертер всегда будет вызываться, потому что « itemValue =» # {dog} », который вы найдете в компоненте AutoComplete.

Ниже вы можете увидеть работу автозаполнения:

CSS / Javascript / изображения с JSF

Посмотрите на рисунки ниже, они покажут, как приложение этого поста обрабатывает ресурсы:

« Master.xhtml »

«Index.xhtml»

С JSF очень легко обращаться с такими ресурсами. Разработчику больше не нужно использовать относительный путь к файлу. Чтобы использовать ваши ресурсы, создайте ваши файлы, как показано ниже:

JSF отобразит все ресурсы, найденные в папке «/ WebContent / resources», и разработчик сможет использовать ресурсы, как показано выше.

«Web.xml» конфигурации

В папке « WebContent / WEB-INF / » создайте файлы ниже:

« Web.xml »

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
<?xml version='1.0'?>
<web-app version='3.0' xmlns='http://java.sun.com/xml/ns/javaee'
 <display-name>JSFCrudApp</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>
 <welcome-file-list>
  <welcome-file>/pages/protected/index.xhtml</welcome-file>
 </welcome-file-list>
 <context-param>
  <param-name>javax.faces.PROJECT_STAGE</param-name>
  <param-value>Development</param-value>
 </context-param>
 
 <filter>
  <filter-name>LoginCheckFilter</filter-name>
  <filter-class>com.filter.LoginCheckFilter</filter-class>
  <init-param>
   <param-name>loginActionURI</param-name>
   <param-value>/JSFCrudApp/pages/public/login.xhtml</param-value>
  </init-param>
 </filter>
 <filter-mapping>
  <filter-name>LoginCheckFilter</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>
 
 <filter>
  <filter-name>AdminPagesFilter</filter-name>
  <filter-class>com.filter.AdminPagesFilter</filter-class>
 </filter>
 <filter-mapping>
  <filter-name>AdminPagesFilter</filter-name>
  <url-pattern>/pages/protected/admin/*</url-pattern>
 </filter-mapping>
 
 <filter>
  <filter-name>DefaultUserPagesFilter</filter-name>
  <filter-class>com.filter.DefaultUserPagesFilter</filter-class>
 </filter>
 <filter-mapping>
  <filter-name>DefaultUserPagesFilter</filter-name>
  <url-pattern>/pages/protected/defaultUser/*</url-pattern>
 </filter-mapping>
</web-app>

Faces-config.xml

01
02
03
04
05
06
07
08
09
10
11
12
13
14
<?xml version='1.0' encoding='UTF-8'?>
 
<faces-config xmlns='http://java.sun.com/xml/ns/javaee'
 version='2.0'>
 <application>
  <resource-bundle>
   <base-name>messages</base-name>
   <var>bundle</var>
  </resource-bundle>
  <message-bundle>messages</message-bundle>
 </application>
</faces-config>

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

  • Все фильтры безопасности вы найдете в файле web.xml. Вы также можете использовать аннотации @Filter, которые будут работать так же.
  • Свойство « javax.faces.PROJECT_STAGE » имеет значение DEVELOPMENT. Одним из преимуществ этой конфигурации является то, что JSF добавит «h: message», если на экране ничего не найдено. Если происходит какое-то исключение и нет компонента для его отображения, JSF добавит на страницу компонент ah: message.
  • Внутри «лица-конфигурации» существует тег с именем «пакет сообщений». Этот тег позволяет разработчику переопределять сообщения JSF по умолчанию, значение этого тега будет указывать на файл с ключом сообщений JSF по умолчанию. В файле «message.properties» (стр. 08) есть ключ « javax.faces.component.UIInput.REQUIRED », любое значение, которое вы вводите в этот ключ, повлияет на все сообщения «обязательного поля», отображаемые в приложении.

Повышение безопасности вашего приложения

Не объединять запросы

Не используйте обычный код «где id =» + id sql. Этот вид кода допускает хакерскую атаку « SQL-инъекция ». Разработчик, который работает с ORM, также уязвим для такого рода атак, но с другим именем: «HQL Injection». Лучший способ выполнить запрос вы можете найти в классе Person и User:

Неважно, используете вы JPA или нет, никогда не объединяйте ваш запрос со строками.

Разработчик должен знать, что « SQL-инъекция может произойти в любом запросе вашего приложения », а не только в запросе на вход в систему. Если у пользователя есть действительный логин для вашего приложения, он может выполнять « SQL-инъекцию » во всех ваших запросах.

Автозаполнение выключено

На странице « login.xhtml » есть следующий код:

Отключение тега «автозаполнение» сообщает браузеру, что это поле не следует сохранять. Хорошие браузеры (Firefox, Chrome, IE) уважают этот тег и помогают защитить ваше приложение.

Если вы разрешаете браузеру сохранять пароль, браузер должен где-то хранить этот пароль. Если хакер узнает, где хранится этот ключ, он может попытаться взломать его.

Проверить все входящие запросы

Если бы приложение требовалось только для проверки, зарегистрирован ли пользователь или нет, классу пользователя не понадобится роль Enum.

Если не было проверки роли, обычный пользователь мог бы получить доступ к любой области системы, например к страницам администратора. Обратите внимание, что в этом приложении есть фильтры, которые всегда проверяют роль пользователя для всех запросов. « Сокрытие ссылки не является мерой защиты. Разработчик должен всегда проверять все входящие запросы ». Разработчик может скрыть URL-адрес или кнопку, но пользователь может получить доступ к любому экрану вашего приложения, если он введет URL-адрес в браузере или имитирует вызовы / посты.

Всегда используйте компонент h: outputText

Простой способ избежать межсайтового скриптинга — использовать компонент h: outputText для отображения данных из базы данных. Обратите внимание, что в этом посте все значения, отображаемые для пользователя, которые поступают из базы данных, используют компонент h: outputText. Ситуация, в которой можно избежать компонента h: outputText, — это когда приложение отобразит системные сообщения из файла, такого как «message.properties».

Запуск приложения

Запустите Tomcat и проверьте базу данных; обратите внимание, что в базе данных еще нет таблицы.

Введите следующий URL в браузере: http: // localhost / JSFCrudApp / .

Будет отображен следующий экран:

Введите любое значение и нажмите кнопку входа, не беспокойтесь, если нет пользователя или таблиц. Просто нажмите на него. Вы увидите сообщение об ошибке, подобное этому:

Проверьте вашу базу данных еще раз, и вы увидите, что все таблицы были созданы. Приложение контролирует все транзакции вручную, поэтому JPA / Hibernate просто создает таблицу при первом вызове.

Вам нужно создать пользователя с ролью ADMIN (я назвал этого пользователя Реал Мадрид) и другого пользователя с ролью USER (я назвал его Барселона). Пользователь ADMIN будет иметь доступ ко всей системе во всех папках, но пользователь с ролью USER будет иметь доступ к страницам в папке defaultUser.

Если вы войдете в систему с пользователем ADMIN, вы увидите:

Зарегистрируйтесь сейчас с пользователем с ролью USER:

Кнопка Собаки были скрыты. Даже без кнопки пользователь может получить доступ к URL-адресам собак, и экран собак должен быть разрешен только для ролей ADMIN.

Чтобы увидеть, как приложение будет вести себя с незаконным доступом, войдите в систему с ролью USER и попробуйте получить доступ к следующей ссылке: http: //localhost/JSFCrudApp/pages/protected/admin/adminIndex.xhtml

Будет отображен следующий экран:

Этот экран будет отображаться, потому что AdminPagesFilter проверяет, поступил ли запрос от пользователя ADMIN. Если пользователь не в роли ADMIN, наша ниндзя кошка получит его! знак равно

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