gpt4 book ai didi

Jersey JAX-RS REST "getter"方法总是被调用

转载 作者:行者123 更新时间:2023-12-04 19:27:52 25 4
gpt4 key购买 nike

我在 Glasshfish 5 中运行一个 Web 应用程序,它使用 Jersey JAX-RS 提供一个 REST 端点。它还使用 bean 验证。
我遇到的问题是,任何以“get”开头的方法总是在返回带有 @Valid 注释的东西时被调用。

例子:

@Path("/hello")
public class HelloResource {

@GET
public @Valid HelloMessage getSomething() {
HelloMessage helloMessage = new HelloMessage();
helloMessage.setMessage("Hello World!");
return helloMessage;
}

@POST
public @Valid HelloMessage updateMessage(@Valid HelloMessage message) {
return message;
}
}

如果我对/hello 执行 POST,您将看到在调用 updateMessage 之前调用了 getSomething 方法。
如果删除 getSomething 方法返回类型上的 @Valid 注释,则不会调用 getSomething。

这是符合规范的吗?在 REST 类中,您是否应该基本上永远不要命名以“get”开头的方法?

过去我在github上报告过这个问题,但从未收到回复。

https://github.com/eclipse-ee4j/jersey/issues/3743

其他类:
@ApplicationPath("/")
public class HelloApplication extends Application {

@Override
public Set<Class<?>> getClasses() {
return Collections.singleton(HelloResource.class);
}
}

public class HelloMessage {

@Size(max = 100)
private String message;

public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}
}

可在以下位置找到的最小项目
https://github.com/robertatgh/stackoverflow-50658396/tree/develop

最佳答案

因此,由于命名约定,这被证明是一个有趣的问题。通过 Jersey 源代码调试你会看到它通过

org.glassfish.jersey.server.validation.internal.DefaultConfiguredValidator.onValidate(ValidationInterceptorContext) 行:166

public void onValidate(final ValidationInterceptorContext ctx) {

final Object resource = ctx.getResource();
final Invocable resourceMethod = ctx.getInvocable();
final Object[] args = ctx.getArgs();

final Set<ConstraintViolation<Object>> constraintViolations = new HashSet<>();
final BeanDescriptor beanDescriptor = getConstraintsForClass(resource.getClass());

// Resource validation.
if (beanDescriptor.isBeanConstrained()) {
constraintViolations.addAll(validate(resource));
}

if (resourceMethod != null
&& configuration.getBootstrapConfiguration().isExecutableValidationEnabled()) {
final Method handlingMethod = resourceMethod.getHandlingMethod();

有趣的部分是
// Resource validation.
if (beanDescriptor.isBeanConstrained()) {
constraintViolations.addAll(validate(resource));
}

相同的定义是
@Override
public final boolean isBeanConstrained() {
return hasConstraints() || !constrainedProperties.isEmpty();
}

现在,如果您查看 constrainedProperties 的值它显示如下

getSomething is a property

所以它认为 getSomething表示属性(property) something然后在属性本身上插入验证。

所以现在如果我们重命名方法如下
  @GET
public @Valid HelloMessage doGetSomething() {
System.out.println("* * * *---==** getSomething() called **==---* * * *");
HelloMessage helloMessage = new HelloMessage();
helloMessage.setMessage("H");
return helloMessage;
}

@POST
public @Valid HelloMessage updateMessage(@Valid HelloMessage message) {
message.setMessage("H");
System.out.println("* * * *---==** updateMessage() called **==---* * * *");

return message;
}

并从命令行再次运行它

getSomething is not Called

当然,如果我用有效数据更正返回值

getSomething not called

关于Jersey JAX-RS REST "getter"方法总是被调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50658396/

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