gpt4 book ai didi

java - 将 @ModelAttribute 解析为方法参数的切入点表达式

转载 作者:太空宇宙 更新时间:2023-11-04 10:32:23 34 4
gpt4 key购买 nike

我在 @controllerAdvice 中定义了一个 @ModelAttribute(key),并且我在多个 Controller 方法中使用相同的模型属性作为方法参数,因为 (key) 将在所有 Controller 中可用。

我正在像这样在 Controller 类中添加属性(键)。

@RequestMapping(value = "/", method = RequestMethod.GET)
public String list(final Model model,@ModelAttribute("key") final boolean key) {
...
...
}

我想拦截所有以 @ModelAttribute("key") 作为方法参数的 Controller 方法。

我的方面文件如下所示。

@Component
@Aspect
@EnableAspectJAutoProxy
public class myAspectclass {

@Pointcut("execution(public * *(.., @org.springframework.web.bind.annotation.ModelAttribute(boolean key)))")
public void methodWithAnnotatedParameter() {}

@Around("methodWithAnnotatedParameter()")
public String blahMethod(ProceedingJoinPoint PJP){

blah blah

....
}

但是我的服务器启动失败说

[tomcat:launch] Caused by: java.lang.IllegalArgumentException: Pointcut is not well-formed: expecting 'name pattern' at character position 97

[tomcat:launch] execution(public * *(.., @org.springframework.web.bind.annotation.ModelAttribute(boolean key), ..))

我无法理解这种情况下的错误...我在语法上做错了什么吗?

注意:我的ModelAttribute(key)在参数列表中没有任何特定位置

引用this答案:

最佳答案

这是独立的 AspectJ 示例(不是 Spring 应用程序,但方面语法应该相同)。

驱动程序应用程序:

正如你所看到的,有几种带和不带@ModelAttribute参数注释的方法,其中一种甚至有两个带注释的参数(无论有意义与否,但这只是一个例子)。

package de.scrum_master.app;

import java.util.Collection;
import java.util.Map;

import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;

public class Application {
public String list(Model model, @ModelAttribute("key") boolean key) {
return "x";
}

public String foo(Model model, @ModelAttribute("key") boolean key, @ModelAttribute(name = "key") String text) {
return "x";
}

public String bar(@ModelAttribute(name = "key") int number) {
return "x";
}

public String zot(Model model, @ModelAttribute("XXX") boolean key) {
return "x";
}

public String baz(Model model, boolean key, String text) {
return "x";
}

public String bla(@ModelAttribute("XXX") int number) {
return "x";
}

public static void main(String[] args) {
Model model = new Model() {
@Override public Model mergeAttributes(Map<String, ?> arg0) { return null; }
@Override public boolean containsAttribute(String arg0) { return false; }
@Override public Map<String, Object> asMap() { return null; }
@Override public Model addAttribute(String arg0, Object arg1) { return null; }
@Override public Model addAttribute(Object arg0) { return null; }
@Override public Model addAllAttributes(Map<String, ?> arg0) { return null; }
@Override public Model addAllAttributes(Collection<?> arg0) { return null; }
};
Application application = new Application();
application.list(model, true);
application.foo(model, true, "hey");
application.bar(11);
application.zot(model, true);
application.baz(model, true, "hey");
application.bla(11);
}
}

方面:

该方面与至少具有一个带 @ModelAttribute 注释的参数的所有方法执行相匹配。如果您只想查找这些方法,无论注释参数值如何,切入点就足够了。但正如您所说,您只想匹配具有 value = "key" 的注释,我们需要使用反射来查看注释本身并过滤掉不需要的注释。

根据 @ModelAttribute JavaDoc 的另一个并发症,参数 namevalue 是彼此的别名,也就是说,我们还需要检查这两个参数的值,以便使其完全正确。

package de.scrum_master.aspect;

import java.lang.annotation.Annotation;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ModelAttribute;

@Aspect
@Component
public class ModelAttributeInterceptor {
@Pointcut("execution(public * *(.., @org.springframework.web.bind.annotation.ModelAttribute (*), ..))")
public void methodWithAnnotatedParameter() {}

@Around("methodWithAnnotatedParameter()")
public String blahMethod(ProceedingJoinPoint thisJoinPoint) throws Throwable {
MethodSignature methodSignature = (MethodSignature) thisJoinPoint.getSignature();
Annotation[][] annotationMatrix = methodSignature.getMethod().getParameterAnnotations();
boolean foundModelAttribute = false;
for (Annotation[] annotations : annotationMatrix) {
for (Annotation annotation : annotations) {
if (!(annotation instanceof ModelAttribute))
continue;
ModelAttribute modelAttribute = (ModelAttribute) annotation;
if ("key".equals(modelAttribute.value()) || "key".equals(modelAttribute.name())) {
if (!foundModelAttribute) {
System.out.println(thisJoinPoint);
foundModelAttribute = true;
}
System.out.println(" " + modelAttribute);
}
}
}
return (String) thisJoinPoint.proceed();
}
}

控制台日志:

execution(String de.scrum_master.app.Application.list(Model, boolean))
@org.springframework.web.bind.annotation.ModelAttribute(name=, value=key, binding=true)
execution(String de.scrum_master.app.Application.foo(Model, boolean, String))
@org.springframework.web.bind.annotation.ModelAttribute(name=, value=key, binding=true)
@org.springframework.web.bind.annotation.ModelAttribute(name=key, value=, binding=true)
execution(String de.scrum_master.app.Application.bar(int))
@org.springframework.web.bind.annotation.ModelAttribute(name=key, value=, binding=true)

关于java - 将 @ModelAttribute 解析为方法参数的切入点表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49863491/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com