0

有了这个示例 JAX-RS web-service,第二个参数的getByAttribute类型是Object.class.

@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Path("/POJOService")
public interface POJOService extends BasicService {

    @GET
    @Path("/getByAttribute")
    SampleObject getByAttribute(@QueryParam("attribute") String attribute, @QueryParam("value") Object value);

}

这将导致错误:

有效负载:参数类 java.lang.Object 没有带有单个 String 参数、静态 valueOf(String) 或 fromString(String) 方法的构造函数

我正在考虑添加一个提供者,javax.ws.rs.ext.ParamConverterProvider该提供者将传递 JSON 字符串中的类型。但也许有这个问题的最佳实践解决方案?

将现有企业服务器/客户端应用程序的通信层迁移到JAX-RS 2.1
为 MicroProfile使用Apache CXFEclipse Rest Client

编辑:客户端将调用不同类型的服务:

service.getByAttribute("name", "example"); // string, used for this test which throws the exception
service.getByAttribute("id", 99); // integer
service.getByAttribute("author", user); // object instace of User.class
4

1 回答 1

0

我发现需要配置 ObjectMapper 来添加输入信息:

ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping(DefaultTyping.NON_FINAL);

还有其他打字配置

JAVA_LANG_OBJECT
这个值意味着只有声明类型为 Object 的属性(包括没有显式类型的泛型类型)才会使用默认类型。

NON_CONCRETE_AND_ARRAYS
值表示默认类型将用于 OBJECT_AND_NON_CONCRETE 涵盖的所有类型以及它们的所有数组类型。

NON_FINAL
值,表示默认类型将用于所有非最终类型,除了少数“自然”类型(String、Boolean、Integer、Double)可以从 JSON 中正确推断出来;以及所有非最终类型的数组。

OBJECT_AND_NON_CONCRETE
值表示默认类型将用于声明类型为 Object 或抽象类型(抽象类或接口)的属性。

我还必须注册一个ParamConverterProvider考虑ObjectMapper所有传递参数的设置:

@Provider
public class ObjectMapperParamConverterProvider implements ParamConverterProvider {

    @Override
    public <T> ParamConverter<T> getConverter(final Class<T> rawType, final Type genericType, final Annotation[] annotations) {
        ObjectMapper mapper = ...;
        return new ParamConverter<T>() {
            @Override
            public T fromString(final String value) {
                try {
                    T result = mapper.readValue(value, rawType);
                    return result;
                } catch (IOException e) {
                    throw new ProcessingException(e);
                }
            }

            @Override
            public String toString(final T value) {
                try {
                    String result = mapper.writeValueAsString(value);
                    return result;
                } catch (JsonProcessingException e) {
                    throw new ProcessingException(e);
                }
            }
        };
    }
}
于 2019-08-12T12:49:27.457 回答