1

私はグーグルアプリエンジン、スプリング、タイルの構成を使用しており、各コントローラーのアクションにより、ネストされた(タイル)jspのセットがレンダリングされます。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(model)」メソッドを呼び出す必要があるのとは異なるソリューションです。

4

1 に答える 1

4

Tilesは、ViewPreparerの概念を知っています。ViewPreparerは、定義がレンダリングされる前に実行され、タイルビューに共通の属性を設定するのに適した場所です。これらの属性は、前述のViewPreparerチュートリアルページの例に示されているように、リクエスト属性(以下に示す)またはタイル属性にすることができます。

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);
        }
    }
}

次に、preparerFactoryClassプロパティを設定してTilesConfigurerを構成し、次のようにViewPreparerBeanを取得します。

<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>

そして、ビュー宣言で作成者を定義します。ベースビューからすべてのビューを拡張して、作成者の宣言を1回だけ実行する必要があります。

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

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

または、Tilesビュー以外のビューがある場合は、独自のHandlerInterceptorを実装することもできます。

于 2012-10-07T20:08:37.683 に答える