2012-10-07 3 views
1

Я использую конфигурацию движка google, весну и плитки, где каждое действие контроллера приводит к отображению некоторого набора вложенных (плит) jsp. Некоторые из элементов СПЯ должны быть рассчитаны/набором для (почти) каждого контроллера, к примеру вход/выход ссылка где-то на странице:Как настроить весовые коэффициенты для всех контроллеров/действий

<% 
com.google.appengine.api.users.UserService userService = 
    com.google.appengine.api.users.UserServiceFactory.getUserService(); 
com.google.appengine.api.users.User user = userService.getCurrentUser(); 
if (user != null) {%> 
    <li class="active"><a href="#feeds">Feeds</a></li> 
    <li class="active"><a href="<%=userService.createLogoutURL("")%>">Logout</a></li> 
<%} else {%> 
    <li class="active"><a href="<%=userService.createLoginURL("")%>">Login</a></li> 
<%}%> 

Конечно, это возможно, и я мог бы также сделать статические классы, которые могут упростить такой код. Тем не менее, это не то, что мне нравится в моем jsp, более того, возможно (возможно) невозможно в шаблонах таких движков, как thymeleaf, выполнить код вроде этого. Поэтому, как мне делать что-то вроде этого:

@RequestMapping("/foo") 
public class FooController { 
    @RequestMapping(value="/{bar}", method = RequestMethod.GET) 
    public String getMovie(@PathVariable String bar, ModelMap model) { 
     model.addAttribute("bar", bar); 
     model.addAttribute("message", "message"); 
     UserService userService = UserServiceFactory.getUserService(); 
        User user = userService.getCurrentUser(); 
     model.addAttribute("isLoggedIn", user==null); 

     return "somepage"; 

    } 
} 

Так кратко: Как предотвратить, что isLoggedIn-код дублируется везде, предпочтительно раствор, отличный от необходимости вызывать некоторые «(модель) initUserModel» метод.

ответ

4

Плитка знает концепцию ViewPreparer. ViewPreparer выполняется до того, как определение будет отображено, и это хорошее место для установки атрибутов, которые являются общими для ваших просмотров Tiles. Эти атрибуты могут быть атрибутами запроса (как показано ниже) или атрибутами плиток, как показано в примере по указанному ViewPreparer tutorial page.

ViewPreparer реализуется как «нормальный» весенний сервис:

@Component 
public class YourViewPreparer implements ViewPreparer { 
    @Autowired 
    private UserService userService; 

    @Override 
    public void execute(TilesRequestContext tilesContext, AttributeContext attributeContext) { 
     // Some magic here to get the HttpRequest... 
     Object[] requestObjects = tilesContext.getRequestObjects(); 
     if (requestObjects.length == 2) { 
      HttpServletRequest request = (HttpServletRequest) requestObjects[0]; 
      User user = userService.getCurrentUser(); 
      request.setAttribute("isLoggedIn", user != null); 
     } 
    } 
} 

Затем настроить свой TilesConfigurer, установив свойство preparerFactoryClass подобрать любые бобы ViewPreparer как это:

<bean class="org.springframework.web.servlet.view.tiles2.TilesConfigurer" id="tilesConfigurer"> 
    <property name="definitions"> 
     ... 
    </property> 
    <property name="preparerFactoryClass" value="org.springframework.web.servlet.view.tiles2.SimpleSpringPreparerFactory" /> 
</bean> 

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

<definition name="main" preparer="com.example.YourViewPreparer"> 
    ... 
</definition> 

<definition name="myView" extends="main"> 
    ... 
</definition> 

В качестве альтернативы можно также реализовать свой собственный HandlerInterceptor, если у вас есть другие мнения, чем вид плитки.

+0

Почему вы проверяете «(requestObjects.length == 2)»? – Herbert

+0

Хороший вопрос. Возможно, существует несколько менее непонятный способ определить, какой тип массива вызывает вызов getRequestObjects() ... Существуют две реализации TilesRequestContext: ServletTilesRequestContext и JspTilesRequestContext (где первое - это то, за которым мы после). При просмотре реализаций ServletTilesRequestContext возвращает Object [] с двумя элементами, где JspTilesRequestContext возвращает Object [] только одним элементом. Возможно, было бы более ясным проверить 0-й элемент возвращаемого массива, например 'if (requestObjects [0] instanceof HttpServletRequest) {}' – James

+0

Спасибо за ваш ответ. При использовании 'org.springframework.web.servlet.view.tiles2.SimpleSpringPreparerFactory' вам не нужно (и не должно) аннотировать' YourViewPreparer' с помощью '@ Component'. Для этого приводит к экземпляру 'YourViewPreparer' в контексте приложения, который никогда не используется, поскольку' SimpleSpringPreparerFactory' создает свои собственные по требованию. Кроме того, используйте 'org.springframework.web.servlet.view.tiles2.SpringBeanPreparerFactory', который ищет экземпляр компонента-получателя из контекста приложения по имени. – sbk

Смежные вопросы