Spring AOP:如何从方面从URI模板读取路径变量值? [英] Spring AOP: How to read path variable value from URI template in aspect?

查看:118
本文介绍了Spring AOP:如何从方面从URI模板读取路径变量值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建Spring方面,该方面将通过自定义注释注释的方法参数设置为URI模板中的id标识的特定类的实例.路径变量名称是注释的参数.与Spring @PathVariable非常相似.

I want to create Spring aspect which would set method parameter, annotated by custom annotation, to an instance of a particular class identified by an id from URI template. Path variable name is parameter of the annotation. Very similar to what Spring @PathVariable does.

所以控制器方法如下:

@RestController
@RequestMapping("/testController")
public class TestController {

    @RequestMapping(value = "/order/{orderId}/delete", method = RequestMethod.GET)
    public ResponseEntity<?> doSomething(
            @GetOrder("orderId") Order order) {

        // do something with order
    }

}

代替经典:

@RestController
@RequestMapping("/testController")
public class TestController {

    @RequestMapping(value = "/order/{orderId}/delete", method = RequestMethod.GET)
    public ResponseEntity<?> doSomething(
            @PathVariable("orderId") Long orderId) {

        Order order = orderRepository.findById(orderId);
        // do something with order
    }
}

注释源:

// Annotation
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface GetOrder{

    String value() default "";
}

方面来源:

// Aspect controlled by the annotation
@Aspect
@Component
public class GetOrderAspect {

    @Around( // Assume the setOrder method is called around controller method )
    public Object setOrder(ProceedingJoinPoint jp) throws Throwable{

        MethodSignature signature = (MethodSignature) jp.getSignature();
        @SuppressWarnings("rawtypes")
        Class[] types = signature.getParameterTypes();
        Method method = signature.getMethod();
        Annotation[][] annotations = method.getParameterAnnotations();
        Object[] values = jp.getArgs();

        for (int parameter = 0; parameter < types.length; parameter++) {
            Annotation[] parameterAnnotations = annotations[parameter];
            if (parameterAnnotations == null) continue;

            for (Annotation annotation: parameterAnnotations) {
                // Annotation is instance of @GetOrder
                if (annotation instanceof GetOrder) {
                    String pathVariable = (GetOrder)annotation.value();                        

                    // How to read actual path variable value from URI template?
                    // In this example case {orderId} from /testController/order/{orderId}/delete

                    HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder
                            .currentRequestAttributes()).getRequest();
                    ????? // Now what?

                }
           } // for each annotation
        } // for each parameter
        return jp.proceed();
    }
}

更新2017年4月4日:

Answer given by Mike Wojtyna answers the question -> thus it is accepted.

Answer given by OrangeDog solves the problem form different perspective with existing Spring tools without risking implementation issue with new aspect. If I knew it before, this question would not be asked.

谢谢!

推荐答案

如果您已经可以访问HttpServletRequest,则可以使用HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE spring模板来选择请求中所有属性的映射.您可以这样使用它:

If you already have access to HttpServletRequest, you can use HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE spring template to select map of all attributes in the request. You can use it like that:

request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE)

结果是一个Map实例(不幸的是,您需要强制转换为它),因此您可以对其进行迭代并获取所需的所有参数.

The result is a Map instance (unfortunately you need to cast to it), so you can iterate over it and get all the parameters you need.

这篇关于Spring AOP:如何从方面从URI模板读取路径变量值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆