Шаблон Session Facade

Шаблон Session Facade является частным случаем более общего шаблона Facade. Перед изучением Session Facade, полезно познакомиться с темрином сессионного компонента (session bean ).

Реализовывать что-то полезное не будем. Просто сделаем специальный бин - фасад, который должен инкапсулировать сложные взаимодействия (у нас они не будут сложными) от контейнера сервлетов. Реализовывать будем на базе Spring MVC, пример для которого уже описывали.

При этом нет уверенности, что код сделан правильным в плане бинов, он работает, но описан не как remote bean.

Идея простая: в контроллере создаем stateless bean, являющийся фасадом и через фасад загружаем данные. Загруженные данные возвращаем в представление (view).

Вначале создадим bean как Создать - Enterprise JvaBeans - Сеансовый компонент и оставить его как "Без сохранения состояния" и не создавать интерфейс. Разместим в пакет servlet.stateless под именем StatelessSessionBean

В итоге, появится файл StatelessSessionBean.java в котором сразу допишем нашу "бизнес-логику": package servlet.stateless;

import javax.ejb.Stateless;

/** * * @author ars */ @Stateless public class StatelessSessionBean { // Add business logic below. (Right-click in editor and choose   // "Insert Code > Add Business Method")

private Object data;

public Object getData { return data; }

public void setData(Object data) { this.data = data; }   public String sayHello(String name) { return "Hello, " + name + "!\n"; }   // Заглушка авторизации пользователя public Boolean isAuthorizedUser(String user) { return true; }   // Заглушка функции, загружающией в this.data какие либо данные public void loadData { // здесь подключение к БД и еще что-то this.setData("World"); // Положим, это бизнес данные } }

Теперь реализуем контроллер, в котором используем только-что созданные бин. Обратите внимание, что название бина выбрано немного неудачно, так как появились методы типа lookupStatelessSessionBeanBean

package jperm.controller;

import java.util.logging.Level; import java.util.logging.Logger; import javax.ejb.EJB; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.Controller; import servlet.stateless.StatelessSessionBean;

/** * * @author ars */ public class SessionFacadeController implements Controller { StatelessSessionBean statelessSessionBean = lookupStatelessSessionBeanBean; //SessionFacade sessionFacade = lookupSessionFacadeBean; @EJB private StatelessSessionBean sessionFacade;

@Override public ModelAndView handleRequest(HttpServletRequest hsr, HttpServletResponse hsr1) throws Exception { ModelAndView mav = new ModelAndView("info");

sessionFacade = lookupStatelessSessionBeanBean;  // Находим фасад (в виде bean) через JNDI if (sessionFacade.isAuthorizedUser("Ivan")) {      // Считаем, что пользователь у нас Ivan и проверяем авторизован ли он sessionFacade.loadData;                      // Загружаем бизнес-данные mav.addObject("data",sessionFacade.getData); // Добавляем загруженные данные в View }        return mav; }

private StatelessSessionBean lookupStatelessSessionBeanBean { try { Context c = new InitialContext; return (StatelessSessionBean) c.lookup("java:global/SessionFacadeExample/StatelessSessionBean!servlet.stateless.StatelessSessionBean"); } catch (NamingException ne) { Logger.getLogger(getClass.getName).log(Level.SEVERE, "exception caught", ne); throw new RuntimeException(ne); }   } }

Обратите внимание на метод StatelessSessionBean, он генерирует автоматически и netBeans сам его сгенерирует если попробовать написать создание бина. При такой автоматической генерации netBeans добавит в web.xml данные типа  StatelessSessionBean Session StatelessSessionBean  Эти данные надо закомментировать (почему-то :

Теперь пришла пора отображения. В нашем примере мы использовали отображение "info". Содержимое файла WEB-INF/jsp/info.jsp

<%@page contentType="text/html" pageEncoding="UTF-8"%> <!DOCTYPE html>  JSP Page Hello World! Your Data is: данные... ${data}

В заключении осталось привести web.xml

   contextConfigLocation /WEB-INF/applicationContext.xml </context-param> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>2</load-on-startup> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>*.htm</url-pattern> </servlet-mapping> <session-config> <session-timeout> 30       </session-timeout> </session-config> <welcome-file-list> <welcome-file>redirect.jsp</welcome-file> </welcome-file-list> </web-app>

И dispatcher-servlet.jsp, в который руками мы добавили описание нашего контроллера

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd      http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/>

<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <prop key="index.htm">indexController <prop key="info.htm">sessionFacadeController

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" />

<bean name="indexController" class="org.springframework.web.servlet.mvc.ParameterizableViewController" p:viewName="index" />

<bean name="sessionFacadeController" class="jperm.controller.SessionFacadeController" />