[spring-projects/spring-boot]用于需要请求参数的 Web @ReadOperation 的自定义执行器 @Selector

2024-04-23 283 views
8

版本 Spring Boot 2.0.2 问题:自定义端点@ReadOperation和环境:启用@Parameter Gradle 构建-parameters

@Endpoint(id = "custom")
public class CustomEndpoint {
    @ReadOperation
    public CustomResponse getCustom() {
      ...
    }

    @ReadOperation
    public CustomResponse getCustomByName(@Selector String name) {
...
   }

调用http://localhost:62381/actuators端点返回:

   "custom": {
      "href": "http://localhost:62381/actuator/custom",
      "templated": false
    },
    "custom-arg0": {
      "href": "http://localhost:62381/actuator/custom/{arg0}",
      "templated": true
    },

但调用http://localhost:62381/actuator/custom/test返回 There was an unexpected error (type=Bad Request, status=400). Missing parameters: name

这是由于org.springframework.boot.actuate.endpoint.invoke.reflect.ReflectiveOperationInvoker validateRequiredParameters(InvocationContext context)验证失败引起的

调用http://localhost:62381/actuator/custom?name=test返回第一个的输出,@ReadOperation而不是第二个的输出

有一个解决方法http://localhost:62381/actuator/custom/ignored?name=test

回答

3

arg0告诉我这没有效果,但我无法从您提供的信息中看出原因custom-arg0。您能提供一个重现该问题的小型 Gradle 项目吗?{arg0}-parameters

7

我会尝试,该项目是结构化的,因为我们为我们的项目提供了一个 Spring Boot 启动器(r​​esilience4j

但是看看错误,即使--parameters没有有效(但是,如果不是因为 ,为什么我们会得到Missing parameters: name并工作?),读取操作使用请求参数而不是路径参数,就像文档似乎暗示的那样?name=test--parameters

0

你好,我在 Spring Boot 2.0.1 (maven + eclipse + tomcat + war 部署) 中面临同样的问题。

@Component
@Endpoint(id="my-custom")
public class MyCustomEndpoint {
  @ReadOperation
  public Map<String, List<Parameter>> showParameters() {
    // some code
  }
  @ReadOperation
  public List<Parameter> showParametersByCategory(@Selector String category) {
    // some code
  }
}

Parameter是一个自定义的 POJO

启动时:

[...]o.s.b.a.e.web.servlet.WebMvcEndpointHandlerMapping|Mapped "{[/actuator/my-custom],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)
[...]|o.s.b.a.e.web.servlet.WebMvcEndpointHandlerMapping|Mapped "{[/actuator/my-custom/{arg0}],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)

我的“选择器”方法参数名为category@rLitto arg0

  • 我收到错误消息org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$BadOperationRequestException: Missing parameters: category- 这是好名字
  • 如果我想使用选择器,我必须使用 URI 调用端点/actuator/my-custom/foo?category=xxx

我已经检查了端点的源代码,例如LoggersEndpointEnvironmentEndpoint来与我的端点进行比较,以了解我做错了什么......但徒劳

7

@LeBezout 重要的不仅仅是源代码,还有它的编译方式。也许您可以提供一个重现问题的小样本?

5

谢谢安迪,我不认为这可能是编译问题。

我用“start.spring.io”生成的简单示例重现了这一点(2个类:Spring Boot APP和我的自定义端点)

  • 带有 STS 插件的 Eclipse
  • 运行方式 > Spring Boot 应用程序

您可以在这里看到主要文件。

7

看起来您正在依赖 Eclipse 来编译代码。在这种情况下,您需要配置 Eclipse 的编译器来存储有关方法参数的信息(相当于使用 javac with 进行编译,-parameters因为我认为它默认不会从 Maven 编译器的配置方式中获取该信息。右键单击您的项目-> 属性 -> Java 编译器,然后在“类文件生成”部分中,选中“存储有关方法参数的信息(可通过反射使用)”。

6

我真丢脸。谢谢安迪,抱歉我的无知,问题已解决......但它在文档中。

回到最初的问题,这似乎是 Gradle 或 @rLitto 特定的问题,并对造成的污染表示歉意。

9

如果您希望我们查看此问题,请提供所需的信息。如果在接下来的 7 天内未提供信息,此问题将被关闭。

2

@wilkinsona我也看到了这个问题,你的建议在从 Eclipse 构建时确实有效。尽管它仍然不适用于 Maven 构建。我需要在 pom.xml 中添加什么具体内容吗?以下是其配置方式:

<build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
7

@HarishaAkasapu我不知道为什么,但是(在我使用maven 3.5.2的项目上),这个有效:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <compilerArgs>
            <arg>-parameters</arg>
        </compilerArgs>
    </configuration>
</plugin>

而这个(就像在 Spring Boot pom 中):

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <compilerArgs>
            <parameters>true</parameters>
        </compilerArgs>
    </configuration>
</plugin>

没有!

5

@HarishaAkasapu 请查看文档。 java代码应该编译-parameters(因此应该配置编译器插件,而不是spring boot插件)。

@LeBezout 感谢您尝试提供帮助。第二个示例不起作用,因为parameters它是 Maven 插件的标准属性,而不是您应该在compilerArgs.如果您使用父级,它会自动为您完成。否则,这是正确的配置方法:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <parameters>true</parameters>
    </configuration>
</plugin>
8

抱歉@snicoll,我在输入第二个块时感到困惑........................(文本区域编码的危险;))

奇怪的是,在我的项目中,默认配置<parameters>true</parameters>不起作用。

1

您需要使用3.6.2或稍后(请参阅文档)。

9

你好,我回来了,抱歉耽误了。今天我会给你一个项目。它有点复杂,需要简化。

1

首先我可以告诉大家,我检测到失败的项目是resilience4j,这是一个多模块项目。我可以提供一个项目分支来帮助我们识别问题吗?

7

抱歉,但这并不是我们调试 Gradle 构建的真正工作(在调试模式下运行 Gradle 并确认它-parameters已传递给编译器应该很容易)。如果是这种情况并且您遇到了该问题,我们可以更深入地了解,但如果有一个更简单的示例,我们将不胜感激。

1

我发现了这个问题,抱歉,这是 IntelliJ 的一个问题,在编译运行测试的项目时没有添加 - 参数。

这是一个简化的项目,验证该问题在 gradle build 中工作正常,但在使用 intellij 运行相同测试时失败。

我正在关闭该问题,很抱歉让您浪费时间

6

感谢@rLitto 的反馈,很高兴你明白了。