Статьи

Полное веб-приложение JSF EJB JPA JAAS – часть 2

View — создание и настройка JSF

Этот урок продолжается с первой части .

Давайте создадим новый динамический веб-проект . Создайте его как изображение ниже:

Обратите внимание: в какой-то момент Eclipse спросит вас, хотите ли вы добавить JSF Capabilities (автозаполнение), включите его. Как скрины ниже:

После создания проекта, давайте отредактируем файл «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
54
55
56
57
58
59
<?xml version='1.0' encoding='UTF-8'?>
 id='WebApp_ID' version='3.0'>
 <display-name>CrudJSF</display-name>
 <welcome-file-list>
  <welcome-file>pages/protected/user/listAllDogs.xhtml</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>*.jsf</url-pattern>
  <url-pattern>*.xhtml</url-pattern>
 </servlet-mapping>
 
 <!-- Protected area definition -->
 <security-constraint>
  <web-resource-collection>
   <web-resource-name>Restricted Area - ADMIN Only</web-resource-name>
   <url-pattern>/pages/protected/admin/*</url-pattern>
  </web-resource-collection>
  <auth-constraint>
   <role-name>ADMIN</role-name>
  </auth-constraint>
 </security-constraint>
 <security-constraint>
  <web-resource-collection>
   <web-resource-name>Restricted Area - USER and ADMIN</web-resource-name>
   <url-pattern>/pages/protected/user/*</url-pattern>
  </web-resource-collection>
  <auth-constraint>
   <role-name>USER</role-name>
   <role-name>ADMIN</role-name>
  </auth-constraint>
 </security-constraint>
 
 <!-- Login page -->
 <login-config>
  <auth-method>FORM</auth-method>
  <form-login-config>
   <form-login-page>/pages/public/login.xhtml</form-login-page>
   <form-error-page>/pages/public/loginError.xhtml</form-error-page>
  </form-login-config>
 </login-config>
 
 <!-- System roles -->
 <security-role>
  <role-name>ADMIN</role-name>
 </security-role>
 <security-role>
  <role-name>USER</role-name>
 </security-role>
</web-app>

Вам не нужно беспокоиться, если появится какое-то предупреждение / ошибка; мы решим их позже. Обратите внимание, что я добавил весь код JAAS, который нам понадобится (если вы хотите получить подробный пост об этих конфигурациях JAAS, вы можете проверить его здесь: Проверка входа пользователя в систему JAAS и JSF ).

В соответствии с конфигурациями JAAS обычный пользователь (роль USER) будет видеть только файлы внутри пользовательской папки, то есть только список собак, записанных в нашей базе данных; ADMIN сможет выполнять все действия CRUD, потому что все страницы находятся в папке admins.

Наш «Face-config.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
<?xml version='1.0' encoding='UTF-8'?>
 
<faces-config
    version='2.0'>
 
 <navigation-rule>
  <navigation-case>
   <from-outcome>logout</from-outcome>
   <to-view-id>/pages/protected/user/listAllDogs.xhtml</to-view-id>
   <redirect/>
  </navigation-case>
 </navigation-rule>
 <navigation-rule>
  <navigation-case>
   <from-outcome>listAllDogs</from-outcome>
   <to-view-id>/pages/protected/user/listAllDogs.xhtml</to-view-id>
  </navigation-case>
 </navigation-rule>
 <navigation-rule>
  <navigation-case>
   <from-outcome>createDog</from-outcome>
   <to-view-id>/pages/protected/admin/createDog.xhtml</to-view-id>
   <redirect/>
  </navigation-case>
 </navigation-rule>
 <navigation-rule>
  <navigation-case>
   <from-outcome>updateDog</from-outcome>
   <to-view-id>/pages/protected/admin/updateDog.xhtml</to-view-id>
  </navigation-case>
 </navigation-rule>
 <navigation-rule>
  <navigation-case>
   <from-outcome>deleteDog</from-outcome>
   <to-view-id>/pages/protected/admin/deleteDog.xhtml</to-view-id>
  </navigation-case>
 </navigation-rule>
 
 <application>
  <resource-bundle>
   <base-name>messages</base-name>
   <var>msgs</var>
  </resource-bundle>
 </application>
 
</faces-config>

Обратите внимание, что для некоторых действий я использовал действие перенаправления. Этим действием мы обновим запрошенную ссылку в строке URL браузера, после обновления URL JAAS запретит доступ нелегальному пользователю.

У нас также есть файл, который будет содержать все сообщения нашей системы. Вы заметите, что все тексты, отображаемые на наших страницах, находятся в этом файле (создайте файл с именем «messages.properties» внутри папки src):

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#Dog
dog=Dog
dogName=Name
dogWeight=Weight
 
#Dog messages
dogCreateHeader=Create a new Dog
dogUpdateHeader=Update the Dog
dogDeleteHeader=Delete this Dog
dogNameRequired=The dog needs a name.
dogWeightRequired=The dog needs a weight.
 
#Actions
update=Update
create=Create
delete=Delete
cancel=Cancel
 
#Login
loginHello=Hello
loginErrorMessage=Could not login. Check you UserName/Password
loginUserName=Username
loginPassword=Password
logout=Log Out

View — создание и настройка JSF

Давайте теперь создадим ManagedBeans.

Во-первых, нам нужно добавить EJB в веб-проект. Щелкните правой кнопкой мыши проект JSF> Свойства:

Путь сборки Java> Проекты> Добавить> Проверить CrudEJB> ОК

Во-первых, давайте создадим DogMB:

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.mb;
 
import java.util.List;
 
import javax.ejb.EJB;
import javax.ejb.EJBException;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
 
import com.facade.DogFacade;
import com.model.Dog;
 
@ManagedBean
@RequestScoped
public class DogMB {
 
 @EJB
 private DogFacade dogFacade;
 
 private static final String CREATE_DOG = 'createDog';
 private static final String DELETE_DOG = 'deleteDog';
 private static final String UPDATE_DOG = 'updateDog';
 private static final String LIST_ALL_DOGS = 'listAllDogs';
 private static final String STAY_IN_THE_SAME_PAGE = null;
 
 private Dog dog;
 
 public Dog getDog() {
 
  if(dog == null){
   dog = new Dog();
  }
 
  return dog;
 }
 
 public void setDog(Dog dog) {
  this.dog = dog;
 }
 
 public List<Dog> getAllDogs() {
  return dogFacade.findAll();
 }
 
 public String updateDogStart(){
  return UPDATE_DOG;
 }
 
 public String updateDogEnd(){
  try {
   dogFacade.update(dog);
  } catch (EJBException e) {
   sendErrorMessageToUser('Error. Check if the weight is above 0 or call the adm');
   return STAY_IN_THE_SAME_PAGE;
  }
 
  sendInfoMessageToUser('Operation Complete: Update');
  return LIST_ALL_DOGS;
 }
 
 public String deleteDogStart(){
  return DELETE_DOG;
 }
 
 public String deleteDogEnd(){
  try {
   dogFacade.delete(dog);
  } catch (EJBException e) {
   sendErrorMessageToUser('Error. Call the ADM');
   return STAY_IN_THE_SAME_PAGE;
  }  
 
  sendInfoMessageToUser('Operation Complete: Delete');
 
  return LIST_ALL_DOGS;
 }
 
 public String createDogStart(){
  return CREATE_DOG;
 }
 
 public String createDogEnd(){
  try {
   dogFacade.save(dog);
  } catch (EJBException e) {
   sendErrorMessageToUser('Error. Check if the weight is above 0 or call the adm');
 
   return STAY_IN_THE_SAME_PAGE;
  
 
  sendInfoMessageToUser('Operation Complete: Create');
 
  return LIST_ALL_DOGS;
 }
 
 public String listAllDogs(){
  return LIST_ALL_DOGS;
 }
 
 private void sendInfoMessageToUser(String message){
  FacesContext context = getContext();
  context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, message, message));
 }
 
 private void sendErrorMessageToUser(String message){
  FacesContext context = getContext();
  context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, message, message));
 }
 
 private FacesContext getContext() {
  FacesContext context = FacesContext.getCurrentInstance();
  return context;
 }
}

О коде выше:

  • Всю навигацию вы найдете в face-config.xml. Вы должны использовать константы или пакет ресурсов с навигацией ваших страниц; этот подход лучше, чем просто оставлять строки в ваших методах.
  • Обратите внимание, что мы используем только @EJB для внедрения EJB внутри МБ. Это происходит потому, что мы используем все внутри одного EAR. JBoss 7 упрощает эту локализацию.
  • Если инъекция не работает с JBoss 6 (или если вы используете EJB-банку вне EAR), вы можете использовать инъекцию следующим образом: @EJB (mappedName = «DogFacadeImp / local»).
  • Обратите внимание, что сообщение отображается для пользователя нашей системы. У нас есть попытка / отлов к каждому действию, которое мы выполняем в Фасаде, если произойдет какая-либо ошибка, мы отправим сообщение об ошибке пользователю.
  • Правильными действиями будет проверка данных в ManagedBean и на фасаде. Эти проверки имеют низкую стоимость процессора.
  • Если вы используете JBoss 4.2, вам нужно будет выполнить поиск JNDI, как показано ниже (как сказано выше в этом посте, используйте аннотацию LocalBinding). Аннотируйте свой класс следующим образом:
    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
    @Stateless
    @LocalBinding(jndiBinding='MyBean')
    public class MyBeanImp implements MyBean{
     @Override
     public String hello() {
      return 'Value From EJB';
     }
    }
    // In your Servlet class you would lookup like the code bellow:
    public class Inject extends HttpServlet {
     
     private MyBean local;
     
     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      try {
       InitialContext iniCtx = new InitialContext();
       local = (MyBean) iniCtx.lookup('MyBean');
      } catch (NamingException e) {
       e.printStackTrace();
      }
     
      System.out.println(local.hello());
      request.getRequestDispatcher('/finish.jsp').forward(request, response);
     }
     
     /**
      * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
      */
     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
     
     }
    }

Теперь давайте посмотрим на UserMB:

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
package com.mb;
 
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
 
import com.facade.UserFacade;
import com.model.User;
 
@SessionScoped
@ManagedBean
public class UserMB {
 private User user;
 
 @EJB
 private UserFacade userFacade;
 
 public User getUser(){
  if(user == null){
   ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
   String userEmail = context.getUserPrincipal().getName();
 
   user = userFacade.findUserByEmail(userEmail);
  }
 
  return user;
 }
 
 public boolean isUserAdmin(){
  return getRequest().isUserInRole('ADMIN');
 }
 
 public String logOut(){
  getRequest().getSession().invalidate();
  return 'logout';
 }
 
 private HttpServletRequest getRequest() {
  return (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
 }
}

О коде выше:

  • Этот МБ используется только для хранения сеанса пользователя нашего приложения. Вы будете использовать этот MB для отображения имени пользователя или любых других действий, касающихся пользователя приложения.
  • Обратите внимание, что это Session MB; мы только один раз проверяем, является ли пользователь нулевым, и если возвращает true, мы пойдем в базу данных. С этим условием мы только один раз перейдем к сохранению производительности базы данных.
  • Если инъекция @EJB вызывает исключение, проверьте советы, приведенные в DogMB выше.

Просмотр — Страницы

Подуйте страницы, css и соответствующие пути:

Не возражайте против значков опроса или любого другого типа значков, который показан на рисунке выше. Это значки версий, которые указывают на мой код. Всегда сохраняйте свой код.

Я использую RequestScope в ManagedBean, поэтому вы увидите h: inputHidden на всех моих страницах. Я думаю, что для вас было бы лучше повторить это поле с MBS RequestScope, потому что у вас будет больше свободной памяти на вашем сервере, вместо того, чтобы использовать MB SessionScope.

/WebContent/resources/css/main.css

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
.table {
 border-collapse: collapse;
}
 
.tableColumnsHeader {
 text-align: center;
 background: none repeat scroll 0 0 #E5E5E5;
 border-bottom: 1px solid #BBBBBB;
 padding: 16px;
}
 
.tableFirstLine {
 text-align: center;
 background: none repeat scroll 0 0 #F9F9F9;
 border-top: 1px solid #BBBBBB;
}
 
.tableNextLine {
 text-align: center;
 background: none repeat scroll 0 0 #FFFFFFF;
 border-top: 1px solid #BBBBBB;
}
 
.panelGrid {
 border: 1px solid;
}
 
.panelFirstLine {
 text-align: center;
 border-top: 1px solid #BBBBBB;
}
 
.panelNextLine {
 text-align: center;
 border-top: 1px solid #BBBBBB;
}

/WebContent/pages/public/login.xhtml

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
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN'
<h:head>
 <h:outputStylesheet library='css' name='main.css' />
</h:head>
<h:body>
 <p>Login to access secure pages:</p>
 <form method='post' action='j_security_check'>
  <h:messages layout='table' errorStyle='background: #AFEEEE;'
   infoStyle='background: #AFEEEE;' globalOnly='true' />
  <h:panelGrid columns='2'>
   <h:outputLabel value='Username: ' />
   <input type='text' id='j_username' name='j_username' />
   <h:outputLabel value='Password: ' />
   <input type='password' id='j_password' name='j_password' />
   <h:outputText value='' />
   <h:panelGrid columns='1'>
    <input type='submit' name='submit' value='Login' />
   </h:panelGrid>
  </h:panelGrid>
  <br />
 </form>
</h:body>
</html>

Обратите внимание, как мы импортируем CSS, как если бы это была библиотека. Действие, которое вы видите в теге формы, указывает на неизвестное нам действие, но JAAS отвечает за его управление.
/WebContent/pages/public/loginError.xhtml

01
02
03
04
05
06
07
08
09
10
11
12
13
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN'
<h:head>
 <h:outputStylesheet library='css' name='main.css' />
</h:head>
<h:body>
 #{msgs.loginErrorMessage}
</h:body>
</html>

/WebContent/pages/protected/user/listAllDogs.xhtml

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
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN'
<h:head>
 <h:outputStylesheet library='css' name='main.css' />
</h:head>
<h:body>
 <h:form>
  <h3>#{msgs.loginHello}: #{userMB.user.name} || <h:commandLink action='#{userMB.logOut()}' value='#{msgs.logout}' /> </h3>
 
  <h:messages />
  <h:dataTable value='#{dogMB.allDogs}' var='dog' styleClass='table' headerClass='tableColumnsHeader' rowClasses='tableFirstLine,tableNextLine' >
   <h:column>
    <f:facet name='header'>
     #{msgs.dogName}
    </f:facet>
 
    #{dog.name}
   </h:column>
   <h:column>
    <f:facet name='header'>
     #{msgs.dogWeight}
    </f:facet>
 
    #{dog.weight}
   </h:column>
   <h:column>
    <h:panelGrid columns='2'>
     <!-- Always save the id as hidden when you use a request scope MB -->
     <h:inputHidden value='#{dog.id}' />
 
     <h:commandButton action='#{dogMB.updateDogStart()}' value='#{msgs.update}' rendered='#{userMB.userAdmin}' >
      <f:setPropertyActionListener target='#{dogMB.dog}' value='#{dog}' />
     </h:commandButton>
     <h:commandButton action='#{dogMB.deleteDogStart()}' value='#{msgs.delete}' rendered='#{userMB.userAdmin}' >
      <f:setPropertyActionListener target='#{dogMB.dog}' value='#{dog}' />
     </h:commandButton>
    </h:panelGrid>
   </h:column>
  </h:dataTable>
  <!-- This button is displayed to the user, just to you see the error msg  -->
  <h:commandButton action='createDog' value='#{msgs.create} #{msgs.dog}' />
 </h:form>
</h:body>
</html>

О коде выше:

  • Не забывайте оборачивать свой код тегом h: form. Существуют фреймворки (такие как Primefaces), которые не будут работать без h: form, h: head и h: body.
  • Мы используем UserMB для отображения имени пользователя и выхода из системы нашего пользователя.
  • Тег <h: messages /> будет отображать сообщения, отправленные DogMB.
  • Обратите внимание, что в строке 33 идентификатор скрыт. Это необходимое значение, если вы используете RequestScope вместо SessionScope. Я скорее использую RequestScope, чем SessionScope, в памяти вашего сервера будет меньше данных.
  • Обратите внимание, что кнопки имеют значение Rendered = ”# {userMB.userAdmin}”, чтобы указать, что только роль ADMIN будет иметь доступ к удалению / обновлению.
  • Я передаю выбранной собаке на свой MB через тег: « f: setPropertyActionListener ».
  • Кнопка «Создать» не имеет опции визуализации. Это просто показать вам, если обычный пользователь пытается получить доступ к странице.

/WebContent/pages/protected/admin/createDog.xhtml

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
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN'
<h:head>
 <h:outputStylesheet library='css' name='main.css' />
</h:head>
<h:body>
 <h:form>
  <h:messages/>
 
  <h3>${msgs.dogCreateHeader}</h3>
  <h:panelGrid columns='2' styleClass='panelGrid' rowClasses='panelFirstLine,panelNextLine' >
   <h:outputLabel for='dogName' value='#{msgs.dogName}' />
   <h:inputText id='dogName' value='#{dogMB.dog.name}' required='true' requiredMessage='#{msgs.dogNameRequired}' />
 
   <h:outputLabel for='dogWeight' value='#{msgs.dogWeight}' />
   <h:inputText id='dogWeight' value='#{dogMB.dog.weight}' required='true' requiredMessage='#{msgs.dogWeightRequired}' >
    <f:convertNumber />
   </h:inputText>
  </h:panelGrid>
  <h:panelGrid columns='2'>
   <h:commandButton action='#{dogMB.createDogEnd()}' value='#{msgs.create}' />
   <h:commandButton action='#{dogMB.listAllDogs()}' value='#{msgs.cancel}' immediate='true' />
  </h:panelGrid>
  <br/>
 </h:form>
</h:body>
</html>

О коде выше:

  • Поля name и weight являются обязательными и выведут сообщение об ошибке, если вы оставите его пустым.
  • Кнопка отмены требует опции немедленного = «истина»; с этой опцией JSF не будет проверять любое поле.

/WebContent/pages/protected/admin/deleteDog.xhtml

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN'
<h:head>
 <h:outputStylesheet library='css' name='main.css' />
</h:head>
<h:body>
 <h:form>
  <h:messages/>
 
  <h3>#{msgs.dogDeleteHeader}: #{dogMB.dog.name}?</h3>
  <h:inputHidden value='#{dogMB.dog.id}' />
  <h:panelGrid columns='2'>
   <h:commandButton action='#{dogMB.deleteDogEnd()}' value='#{msgs.delete}' />
   <h:commandButton action='#{dogMB.listAllDogs()}' value='#{msgs.cancel}' immediate='true' />
  </h:panelGrid>
  <br/>
 </h:form>
</h:body>
</html>

Обратите внимание, что в строке 15 идентификатор скрыт. Это необходимое значение, если вы используете RequestScope вместо SessionScope. Я скорее использую RequestScope, чем SessionScope, в памяти вашего сервера будет меньше данных.

/WebContent/pages/protected/admin/updateDog.xhtm l

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
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN'
<h:head>
 <h:outputStylesheet library='css' name='main.css' />
</h:head>
<h:body>
 <h:form>
  <h:messages/>
 
  <h3>#{msgs.dogUpdateHeader}: #{dogMB.dog.name}</h3>
  <h:inputHidden value='#{dogMB.dog.id}' />
  <h:panelGrid columns='2' styleClass='panelGrid' rowClasses='panelFirstLine,panelNextLine' >
   <h:outputLabel for='dogName' value='#{msgs.dogName}' />
   <h:inputText id='dogName' value='#{dogMB.dog.name}' required='true' requiredMessage='#{msgs.dogNameRequired}' />
 
   <h:outputLabel for='dogWeight' value='#{msgs.dogWeight}' />
   <h:inputText id='dogWeight' value='#{dogMB.dog.weight}' required='true' requiredMessage='#{msgs.dogWeightRequired}' >
    <f:convertNumber />
   </h:inputText>
  </h:panelGrid>
  <h:panelGrid columns='2'>
   <h:commandButton action='#{dogMB.updateDogEnd()}' value='#{msgs.update}' />
   <h:commandButton action='#{dogMB.listAllDogs()}' value='#{msgs.cancel}' immediate='true' />
  </h:panelGrid>
  <br/>
 </h:form>
</h:body>
</html>

О коде выше:

  • Обратите внимание, что в строке 15 идентификатор скрыт. Это необходимое значение, если вы используете RequestScope вместо SessionScope. Я скорее использую RequestScope, чем SessionScope, в памяти вашего сервера будет меньше данных.
  • Поля name и weight являются обязательными и выведут сообщение об ошибке, если вы оставите его пустым.
  • Кнопка отмены требует опции немедленного = «истина»; с этой опцией JSF не будет проверять любое поле.

Вид — конфигурация JBoss 7 JAAS

Теперь нам нужно всего лишь несколько шагов, чтобы закончить нашу программу (наконец-то!).

Нам нужно отредактировать конфигурации JBoss и добавить наши конфигурации JAAS.

Снова откройте файл « YOUR_JBOSS / standalone / configuration / standalone.xml » и найдите ключ: «<security-domains>». Добавьте приведенный ниже код (в этом посте я покажу, как выполнить настройку для JBoss 6 — проверка входа пользователя с помощью JAAS и JSF ):

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
<subsystem xmlns='urn:jboss:domain:security:1.0'>
 <security-domains>
  <!-- add me: begin -->
  <security-domain name='CrudJSFRealm' cache-type='default'>
   <authentication>
    <login-module code='org.jboss.security.auth.spi.DatabaseServerLoginModule' flag='required'>
     <module-option name='dsJndiName' value='CrudDS'/>
     <module-option name='principalsQuery' value='select password from users where email=?' />
     <module-option name='rolesQuery' value='select role, 'Roles' from users u where u.email=?' />
    </login-module>
   </authentication>
  </security-domain>
  <!-- add me: end -->
 
  <!-- Other data... -->
 </security-domains>
</subsystem>

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

Давайте создадим EAR для объединения наших проектов.

Файл> Создать> Другое> EnterpriseApplication Project

Нам просто нужно добавить в наш JBoss EAR.

Давайте запустим наше приложение. Запустите JBoss и получите доступ к нашему приложению по URL: http: // localhost: 8080 / CrudJSF / .

Я написал страницы с простым CSS, чтобы облегчить понимание.

Войдите в систему как ПОЛЬЗОВАТЕЛЬ, и вы не увидите кнопки обновления / удаления; вы увидите только кнопку «Создать», которую мы оставили там, чтобы увидеть исключение из незаконного доступа.

Посмотрите ниже на наших страницах:

Вы вошли как ADMIN:

Зарегистрирован как пользователь:

Это все на сегодня

Чтобы скачать исходный код этого поста, нажмите здесь .

Я надеюсь, что этот пост может помочь вам.

Если у вас есть какие-либо сомнения или комментарии, просто опубликуйте их ниже.

До скорой встречи. \ o_

Ссылки, которые мне помогли:

http://7thursdays.wordpress.com/2008/03/18/dependency-injection-in-jboss-42-hold-your-excitement/

http://jan.zawodny.pl/blog/2011/07/jboss-7-postgresql-9

http://blog.xebia.com/2011/07/19/developing-a-jpa-application-on-jboss-as-7/

http://community.jboss.org/wiki/DataSourceConfigurationInAS7

http://stackoverflow.com/questions/286686/how-to-create-conditions-based-on-user-role-using-jsf-myfaces/

http://www.mkyong.com/jsf2/jsf-2-datatable-example/

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