3

每次调用一组控制器(页面控制器)而不是其他控制器(表单控制器,ajax,...)时,如何在 Spring MVC Web 应用程序中使用动态数据(如用户名)填充可重用部分(如标题)?

标题:

<#import "../spring.ftl" as spring />
<!DOCTYPE html>
<html>
<head>
<title>DW-Client</title>
</head>
<body>
<h2>Welcome ${menu.userName}</h2>

指数:

<#include "common/header.ftl">
<!-- stuff -->
<#include "common/footer.ftl" />

这是对这个 SO 帖子的一种跟进。然而,这家伙似乎不再活跃,我想听听一些关于我们用动态菜单之类的数据在 spring mvc web 应用程序中填充部分的方法的新意见......

另一个人建议使用AbstractController由所有页面控制器扩展并通过带@ModelAttribute注释的方法填充变量的方法,这似乎是一个不错的主意。但我最初的想法是:

为什么不使用带有切入点的 AOP 来填充ModelAndView.modelOne 只会用 say 注释控制器或方法@MenuData。现在,每当调用控件时,它都会被向 ModelAndView 添加所需信息的 Aspect 截获:

@RequestMapping(value = "/")
@MenuData
public ModelAndView homePath() {
    ModelAndView mav = new ModelAndView();
    mav.setViewName("index");        
    return mav;
}


@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface MenuData {
}

@Aspect
@Component
public class MenuDataAspect {

    @Inject
    private MenuDataProvider menuDataProvider;


    @Pointcut("within(@MenuData *) && execution(public * * (..))")
    public void menuDataRequested() {            
    }

    @Around("menuDataRequested()")
    public Object provideMenuData(ProceedingJoinPoint pjp) throws Throwable {
        Object output = pjp.proceed();
        ModelAndView mav = (ModelAndView) output;
        mav.getModel().put("menu", menuDataProvider.getMenuData());            
        return mav;
    }

}

现在我应该可以${menu.userName}在我的标题部分中说或任何内容......这样我可以准确控制哪个控制器应该有menuData。

通过告诉切入点拦截所有以 Page 开头的控制器,可以使这个概念更加灵活(不确定语法,但我知道它会起作用,例如@Pointcut("within(*.Page*)")pageController 包中的所有控制器或其他东西。

当然,也可以为不依赖于会话而是依赖于页面的不同菜单场景定义多个注释。


所以我想知道,这种方法看起来是个好主意还是有什么陷阱?你会做什么不同/更好?您使用哪种方法?

谢谢!

4

1 回答 1

4

AOP 对于在一些控制器类中初始化数据似乎有点矫枉过正。

我质疑(a)不是应用程序范围的行为,(b)仅限于少数用户页面级控制器,以及(c)可以使用传统继承来实现的复杂性。

虽然它在技术上可以工作,但使用继承的令人信服的理由是什么?

如果我在这方面提供oversite,您将不得不更加努力地在权衡中卖给我。

于 2012-06-12T11:15:17.333 回答