4

Spring MVCアプリケーションに動的に変更可能なメニュー(注釈付きのメソッドまたはコントローラーが追加されるたびに更新)を実装したいと思います。

私が欲しいのは、Beanとそのメソッド@RequestMenuMappingに行く新しいアノテーション()を導入することです@Controller(ちょうど@RequestMapping作品のように)。

これが私が欲しいものです、Userクラス、次のようなメニューを作成します

Users
    Index | List | Signup | Login

次のコードで:

@Controller
@RequestMapping("user")
@RequestMenuMapping("Users")
public class User {

    @RequestMapping("")
    @RequestMenuMapping("Index")
    public String index(/* no model here - just show almost static page (yet with JSP checks for authority)*/) {
        return "user/index.tile";
    }

    @RequestMapping("list")
    @RequestMenuMapping("List")
    public String list(Model model) {

        model.addAttribute("userList",/* get userlist from DAO/Service */);

        return "user/list.tile";
    }

    @RequestMapping("signup")
    @RequestMenuMapping("Signup")
    public String signup(Model model) {

        model.addAttribute("user",/* create new UserModel instance to be populated by user via html form */);

        return "user/signup.tile";
    }

    @RequestMapping("login")
    @RequestMenuMapping("Login")
    public String login(Model model) {

        model.addAttribute("userCreds",/* create new UserCreds instance to be populated via html form with login and pssword*/);

        return "user/login.tile";
    }
}

@RequestMenuMappingSpring AOPは、アノテーションを使用してメソッドをポイントカットし、 @AfterReturningWebサイトメニューを表すものをモデルに追加するのに役立つと思います。

しかし、これには2つの疑問があります。

  1. (のように)アドバイスされたメソッドにインスタンスがない場合、アドバイスメソッドでModelインスタンスを取得するにはどうすればよいですか?@AfterReturning.index()
  2. 完全なメニューインデックスを作成するために、すべてのメソッド(JavaリフレクションのようにMethod)とクラス(JavaリフレクションのようにClass)に注釈を付けるにはどうすればよいですか?@RequestMenuMapping
4

3 に答える 3

2

@RequestMenuMappingより良い解決策は、Bean ポスト プロセッサですべてのコントローラ クラスをスキャンし、HandlerInterceptorすべてのモデル マップにメニュー項目を追加することだと思います。

于 2012-12-22T15:21:52.567 に答える
1

Q1: ModelAndViewオブジェクト作成時org.springframework.web.servlet.DispatcherServlet.doDispatch()

// Actually invoke the handler.
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

// Do we need view name translation?
if (mv != null && !mv.hasView()) {
    mv.setViewName(getDefaultViewName(request));
}

したがって、handleメソッドを返した後、メソッドをインターセプトするか、メソッドをオーバーライドできます。

Q2:私が知る限り、アノテーション メソッドを取得する方法は 2 つあります。

1.AOP を使用する: 次のようにポイントカットを宣言できます。

@Pointcut("@annotation(you.package.RequestMenuMapping)")
public void requestMenuMappingPountcut() {
}

2.反射を使用します。

Class clazz = Class.forName(classStr);
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
    if (method.isAnnotationPresent(RequestMapping.class)
            && method.isAnnotationPresent(RequestMenuMapping.class)) {
        // do something
    }
}
于 2012-12-22T13:30:04.410 に答える
1

インターセプターのデモ:

@Aspect
@Component
public class InterceptorDemo {

  @Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
  public void requestMapping() {
  }
  @Pointcut("@annotation(you.package.RequestMenuMapping)")
  public void requestMenuMapping() {
  }


  @AfterReturning("requestMapping() && equestMenuMapping()")
  public void checkServer(JoinPoint joinPoint,Object returnObj) throws Throwable {
      Object[] args = joinPoint.getArgs();
      Model m = (Model)args[0];
      // use joinPoint get class or methd...
  }
}

自分自身で Contoller をインターセプトしたい場合は、別のポイントカットを作成すると、ProceedingJoinPointオブジェクトが必要なものを取得できます。

于 2012-12-22T14:04:55.810 に答える