spring注解可以访问方法参数吗?

2024-01-12

考虑一个UrlValidator方法注释,在调用方法之前测试给定的 url 是否有效。

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UrlValdator{
    String value();
}

当路由是静态的并且提前已知时,这种方法工作得很好。例如:

@UrlValidator("http://some.known.url")
public void doSomething();

但这不太灵活。例如,如果路由隐含在doSomething()方法签名?我可以通过 Spring 表达式语言或其他方式访问它吗?例如,这不起作用,但正是我要拍摄的

@UrlValidator("#p1")
public void doSomething(String url)

or

@UrlValidator("#p1.url")
public void doSomething(Request request)

是否可以通过这种方式使注释动态化?

Related

这是我找到的最接近的 https://stackoverflow.com/questions/20350961/spring-expression-language-in-custom-annotation?rq=1,但线程已经过时,并且接受的答案非常麻烦/难以遵循。是否有一个最小的工作示例/更新的方法来做到这一点?


我不完全确定这是否是您的想法,但我可以建议使用 Spring AOP,因为它可以为您提供很大的灵活性。

既然您在评论之一中提到您已经在使用 Spring AOP,我将假设您已经添加了spring-boot-starter-aop作为依赖项,并且您已通过使用注释您的配置类之一来启用对处理标有 @Aspect 的组件的支持@EnableAspectJAutoProxy

例如,定义注释如下:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface EnsureUrlValid {
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface UrlToVerify {
}

我可以在示例弹簧组件中使用它们,如下所示:

@Component
public class SampleComponent {

    private static final Logger logger = LogManager.getLogger(SampleComponent.class);

    @EnsureUrlValid
    public void fetchData(String url) {
        logger.info("Fetching data from " + url);
    }

    @EnsureUrlValid
    public long fetchData(Long id, @UrlToVerify String url) {
        logger.info("Fetching data for user#" + id + " from " + url);
        // just to show that a method annotated like this can return values too
        return 10L;
    }

    @EnsureUrlValid
    public void fetchDataFailedAttempt() {
        logger.info("This should not be logged");
    }
}

这是一个示例“处理器”EnsureUrlValid注解。它查找带注释的方法,尝试提取传入的 url,并根据 url 是否有效,继续调用该方法或引发异常。它很简单,但它表明您可以完全控制所注释的方法。

@Aspect
@Component
public class UrlValidator {

    @Around(value = "@annotation(EnsureUrlValid)")
    public Object checkUrl(ProceedingJoinPoint joinPoint) throws Throwable {
        final Optional<String> urlOpt = extractUrl(joinPoint);
        if (urlOpt.isPresent()) {
            final String url = urlOpt.get();
            if (isUrlValid(url)) {
                return joinPoint.proceed();
            }
        }
        throw new RuntimeException("The passed-in url either could not be resolved or is not valid");
    }

    private Optional<String> extractUrl(JoinPoint joinPoint) {
        Object[] methodArgs = joinPoint.getArgs();

        Object rawUrl = null;
        if (methodArgs.length == 1) {
            rawUrl = methodArgs[0];
        }
        else if (methodArgs.length > 1) {
            // check which parameter has been marked for validation
            Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
            Parameter[] parameters = method.getParameters();
            boolean foundMarked = false;
            int i = 0;
            while (i < parameters.length && !foundMarked) {
                final Parameter param = parameters[i];
                if (param.getAnnotation(UrlToVerify.class) != null) {
                    rawUrl = methodArgs[i];
                    foundMarked = true;
                }
                i++;
            }
        }

        if (rawUrl instanceof String) { // if rawUrl is null, instanceof returns false
            return Optional.of((String) rawUrl);
        }
        // there could be some kind of logic for handling other types

        return Optional.empty();
    }

    private boolean isUrlValid(String url) {
        // the actual validation logic
        return true;
    }
}

我希望它有所帮助。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

spring注解可以访问方法参数吗? 的相关文章

  • (Java) App Engine 中的静态文件无法访问

    The 示例文档 http code google com appengine docs java gettingstarted staticfiles html表示您只需将文件放在 war 或子目录 中 并且应该可以从主机访问它们 只要它
  • 使用 XMLStarlet(图像注释)将值连接到现有 xml 属性

    我正在使用 xml 来注释图像 我正在使用 xmlstarlet 和 unix bash 命令 但当我尝试将值附加到现有 xml 属性值时遇到一些问题 例如 我有
  • 删除优先级队列的尾部元素

    如何删除优先级队列的尾部元素 我正在尝试使用优先级队列实现波束搜索 一旦优先级队列已满 我想删除最后一个元素 优先级最低的元素 Thanks 没有简单的方法 将元素从原始元素复制到新元素 最后一个除外 PriorityQueue remov
  • 稀有对象的 python 类型注释,例如 psycopg2 对象

    我了解内置类型 但是我如何指定稀有对象 例如数据库连接对象 def get connection and cursor gt tuple psycopg2 extensions cursor psycopg2 extensions conn
  • 您建议使用哪种压缩(GZIP 是最流行的)servlet 过滤器?

    我正在寻找一个用于大容量网络应用程序的 GZIP servlet 过滤器 我不想使用容器特定的选项 要求 能够压缩响应负载 XML Faster 已在大批量应用的生产中得到验证 应适当设置适当内容编码 跨容器移植 可选择解压缩请求 谢谢 我
  • Android蓝牙java.io.IOException:bt套接字已关闭,读取返回:-1

    我正在尝试编写一个代码 仅连接到运行 Android 5 0 KitKat 的设备上的 目前 唯一配对的设备 无论我尝试了多少方法 我仍然会收到此错误 这是我尝试过的最后一个代码 它似乎完成了我看到人们报告为成功的所有事情 有人能指出我做错
  • 在 MongoDB 和 Apache Solr 之间同步数据的简单方法

    我最近开始使用 MongoDB 和 Apache Solr 我使用 MongoDB 作为数据存储 并且希望 Apache Solr 为我的数据创建索引 以实现应用程序中的搜索功能 经过一些研究 我发现 基本上有两种方法可以在 MongoDB
  • Java:从集合中获取第一项

    如果我有一个集合 例如Collection
  • 如何使用正则表达式验证 1-99 范围?

    我需要验证一些用户输入 以确保输入的数字在 1 99 范围内 含 这些必须是整数 Integer 值 允许前面加 0 但可选 有效值 1 01 10 99 09 无效值 0 007 100 10 5 010 到目前为止 我已经制定了以下正则
  • 虽然我的类已加载,但 Class.forName 抛出 ClassNotFoundException

    代码如下 它的作用是加载我放在主目录中的 jar 文件中的所有类 import java io File import java util jar JarFile import java util jar JarEntry import j
  • Eclipse - 安装新的 JRE (Java SE 8 1.8.0)

    我正在尝试安装 Java 8 到目前为止我所做的 安装最新版本的 Eclipse 下载并安装 Java SE 运行时环境 8http www oracle com technetwork java javase downloads jre8
  • 如何从日期中删除毫秒、秒、分钟和小时[重复]

    这个问题在这里已经有答案了 我遇到了一个问题 我想比较两个日期 然而 我只想比较年 月 日 这就是我能想到的 private Date trim Date date Calendar calendar Calendar getInstanc
  • 我们如何测试包私有类?

    我正在看书Effective Java in Item 13 Minimize the accessibility of classes and members 它提到 为了方便测试 您可能想让类 接口或成员更易于访问 这在某种程度上是好的
  • 如何通过 Android 按钮单击运行单独的应用程序

    我尝试在 Android 应用程序中添加两个按钮 以从单独的两个应用程序订单系统和库存系统中选择一个应用程序 如图所示 我已将这两个应用程序实现为两个单独的 Android 项目 当我尝试运行此应用程序时 它会出现直到正确选择窗口 但是当按
  • 使用Java绘制维恩图

    我正在尝试根据给定的布尔方程绘制维恩图 例如 a AND b AND c我想在 Android 手机上执行此操作 因此我需要找到一种使用 Java 来执行此操作的方法 我找到了一个完美的小部件 它可以完成我在这方面寻找的一切布尔代数计算器
  • 如何从 Ant 启动聚合 jetty-server JAR?

    背景 免责声明 I have veryJava 经验很少 我们之前在 Ant 构建期间使用了 Jetty 6 的包装版本来处理按需静态内容 JS CSS 图像 HTML 因此我们可以使用 PhantomJS 针对 HTTP 托管环境运行单元
  • 如何让 Emma 或 Cobertura 与 Maven 一起报告其他模块中源代码的覆盖率?

    我有一个带有 Java 代码的多模块 Maven 设置 我的单元测试在其中一个模块中测试多个模块中的代码 当然 这些模块具有相互依赖性 并且在测试执行之前根据需要编译所有相关模块中的代码 那么 如何获得整个代码库覆盖率的报告 注意 我不是问
  • Hadoop NoSuchMethodError apache.commons.cli

    我在用着hadoop 2 7 2我用 IntelliJ 做了一个 MapReduce 工作 在我的工作中 我正在使用apache commons cli 1 3 1我把库放在罐子里 当我在 Hadoop 集群上使用 MapReduceJob
  • JMS 中的 MessageListener 和 Consumer 有什么区别?

    我是新来的JMS 据我了解Consumers能够从队列 主题中挑选消息 那么为什么你需要一个MessageListener因为Consumers会知道他们什么时候收到消息吗 这样的实际用途是什么MessageListener 编辑 来自Me
  • 使用 JFreeChart 为两个系列设置不同的 y 轴

    我正在使用 JFreeChart 使用折线图绘制两个数据系列 XYSeries 复杂的因素是 其中一个数据系列的 y 值通常远高于第二个数据系列的 y 值 假设第一个系列的 y 值约为数百万数量级 而第二个数据系列的 y 值约为数百万数量级

随机推荐

  • 在 Docker 中启动并填充 Postgres 容器

    我有一个包含 Postgres 数据库的 Docker 容器 这是用官方的Postgres 图像 https registry hub docker com postgres 其中有一个 CMD 条目在主线程上启动服务器 我想通过运行来填充
  • xcode 8 错误被服务委托拒绝 (SBMainWorkspace)

    尝试在模拟器上运行构建 我收到此错误 打开 com companyname appname 的请求失败 请求被服务委托 SBMainWorkspace 拒绝 原因 安全 权利 启动需要 com apple frontboard debuga
  • 如何传递通用方法的 lambda 表达式参数以检查 MVC EF 4.0 中的重复项

    我的应用程序中有超过 10 个设置屏幕 在每个数据中 我都必须检查重复数据 例如 这是一个示例代码 private void CheckDuplication AIRLINE airline var AIRLINE context AIRL
  • React Native 不会填满 iPad 上的窗口

    我正在运行的任何 React Native 项目 包括 Facebook 的示例 在 iPad 上看起来都很奇怪 它没有填满屏幕 一切看起来 太大 内容左右各有2个黑条 任何帮助都会很棒 谢谢 解决方案 在 xcode 项目中 转到常规选项
  • 使用javascript获取具有多个下拉菜单的选项的选定值

    我有多个功能 其中有多个选项 在选择某个选项时需要更新这些选项 我还需要通过属性元素传递第三条数据 getElementById 适用于单个下拉菜单 但是当页面上有多个菜单时如何使其工作 我努力了var e document getElem
  • jQuery stop(true, true) 跳转到队列中所有动画的末尾

    我一直在使用 jQuerystop true true 方法清除正在运行的动画 以便下一个立即开始 我注意到第一个参数 clearQueue 清除整个动画队列 但第二个参数 jumpToEnd 仅跳转到当前正在运行的动画的末尾 而不是从队列
  • 如何静音AVPlayer中播放的视频?

    我正在 AVPlayer 中播放视频 现在我需要在播放时单独静音音频 请建议如何在 Objective C 中进行操作 谢谢 苏雷什 从iOS7开始你可以设置AVPlayerisMuted财产给true 在 Objective C 中 该属
  • 在 Entity Framework 4.1 Code First 中排除列可更新

    有谁知道我们是否可以在 Entity Framework 4 1 Code First 中排除列的更新 例如 我有 CreatedOn 字段 我不想在进行编辑 更新时包含该字段 这是否可能 即有选择地从 EF Code First 4 1
  • Java Swing:GUI 未更新某些属性

    编辑 下面是一个最简单 最简单且可检查的问题 RESUME 我正在做一个拉丁方应用程序 它设置一个大小为 s 的正方形 并且您需要使用一些限制来为其着色 例如同一行或同一列中的颜色不同 但我的麻烦不是问题本身 而是Swing 我正在尝试使用
  • 求矩阵中不同行和列的元素总和的最大值

    我有一个 nxm 矩阵 我需要找到不同行和列中其值之和的最大值 例如考虑以下矩阵 m1 m2 m3 n1 1 2 3 n2 4 5 6 n3 7 8 9 n4 10 11 12 最大值为 12 8 4 24 请注意 查找最大值并消除属于该列
  • 检查断言是否启用

    您可以启用 禁用assert on the ClassLoader http docs oracle com cd E19683 01 806 7930 assert 5 index html 但如何确定它们是否已启用 我想采用一些代码路径
  • 避免Python中的对象别名?

    我正在尝试编写一个函数来检查列表是否已排序 返回True or False 如何避免多个变量指向同一事物 def is sorted t a t a sort 当我这样做时 它会对两者进行排序a and t 我怎样才能避免这种情况 这是 O
  • 使用电子构建器的构建后脚本

    在使用电子构建器打包安装程序之前 是否可以在构建后运行某种脚本 我需要生成一个应该分发的额外文件 但我需要二进制文件 exe 来生成它 None
  • 从外部模块添加 argparse 参数

    我正在尝试编写一个可以由第三方扩展的Python程序 该程序将从命令行运行 并提供任何参数 为了允许第三方创建自己的模块 我创建了以下 简化的 基类 class MyBaseClass object def init self self d
  • 哪个正则表达式适用于数字和字符串?

    我正在尝试创建简单的 IDE 并根据以下内容为我的 JTextPane 着色 字符串 注释 和 关键字 公共 int 数字 整数 如 69 浮点数 如 1 5 我为源代码着色的方式是覆盖 StyledDocument 中的 insertSt
  • Spark查询执行时间

    我安装了本地 hadoop 单节点和 hive 并且在 hdfs 中存储了一些 hive 表 然后我使用 MySQL Metastore 配置 Hive 现在我安装了 Spark 并且对 Hive 表进行了一些查询 如下所示 在 scala
  • PHP 7.2 wamp 服务器上的 Magento

    我正在使用 WAMP 服务器 php 版本 7 2 在本地系统上配置现有的 magento 项目 在安装 magento 时出现错误 必须加载 PHP 扩展 mcrypt 问题是 php 7 2 不再支持 mycrypt 有人可以建议我如何
  • RabbitMQ 等待多个队列完成

    好的 这里是正在发生的事情的概述 M lt Message with unique id of 1234 Start Queue lt Exchange lt bind to multiple queues Q1 Q2 Q3 lt star
  • 使用 JSTL 的 c:foreach 将列表值从 servlet 打印到 JSP

    这是我想要发送列表中存在的值的 servlet public class SearchServlet extends HttpServlet private static final long serialVersionUID 1L pub
  • spring注解可以访问方法参数吗?

    考虑一个UrlValidator方法注释 在调用方法之前测试给定的 url 是否有效 Target ElementType METHOD Retention RetentionPolicy RUNTIME public interface