Java BeanUtils setProperty引发IllegalArgumentException

Java BeanUtils setProperty引发IllegalArgumentException,java,reflection,apache-commons-beanutils,Java,Reflection,Apache Commons Beanutils,环境详细信息 我有三个项目: 项目A:Java REST服务应用程序 项目B:Java客户端应用程序 项目C:POJO的简单列表 前两个项目将第三个项目作为依赖项 数据流 项目B向项目A发出HTTP请求,项目A使用项目C的模型对象将其转换为JSON进行响应 Project B使用解码JSON响应,并尝试使用获取原始POJO对象 代码示例 示例POJO类(项目C的一部分): 投影一个示例端点: @Path("/sample") @GET @Produces(MediaType.APPLICAT

环境详细信息

我有三个项目:

  • 项目A:Java REST服务应用程序
  • 项目B:Java客户端应用程序
  • 项目C:POJO的简单列表
前两个项目将第三个项目作为依赖项

数据流

项目B向项目A发出HTTP请求,项目A使用项目C的模型对象将其转换为JSON进行响应

Project B使用解码JSON响应,并尝试使用获取原始POJO对象

代码示例

示例POJO类(项目C的一部分):

投影一个示例端点:

@Path("/sample")
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getExampleResponse() {

    try {

        ServiceResponse<ExamplePOJO> response = new ServiceResponse<ExamplePOJO>();

        ExamplePOJO eo = new ExamplePOJO();
        eo.setId("1");

        AnotherPOJO ap = new AnotherPOJO();
        eo.setAnotherPojo(ap);

        response.setResponse(eo);

        return ((ResponseBuilder) Response.ok().entity(response)).type("application/json").build();

    } catch(Exception E) {
        //error
    }
}
问题

当decodeResponse尝试解码递归调用中的另一个TherPojo对象时,抛出此验证:

java.lang.IllegalArgumentException:无法在bean类“class com.example.package.ExamplePOJO”-参数类型不匹配-具有类型为“com.example.package.AnotherPOJO”的对象,但需要签名“com.example.package.AnotherPOJO”

从异常中可以明显看出,这些对象是同一类的实例

有什么想法吗


哪种方法可以更好地解码未知类别的对象?这:

String className = "com.example.packace." + field.getName().toUpperCase().charAt(0) + field.getName().substring(1, field.getName().length());

 //className = com.example.package.AnotherPOJO                      
 //recursive call
 objectFromResponse = decodeResponse(json.getJSONObject(field.getName()), Class.forName(className), responseObjectModel);

存在一个明显的问题,即必须将字段命名为其类。

这似乎是类加载问题。 查看
类的源代码。对于名称(字符串)
,它使用调用方的类加载器。这可能与加载目标
响应模型的类加载器不同,因此,请尝试以下操作:

//recursive call
objectFromResponse = decodeResponse(
    json.getJSONObject(field.getName()),
    Class.forName(className, true, responseModel.getClassLoader()),
    responseObjectModel);

这应该确保模型子层次结构类由相同的类加载器加载。

您在
字段中有关于该类的信息。调用
field.getType()
获取当前字段/属性的类

         //here I found another object inside the "response" object.  Use information from field to get class.
         else {

             objectFromResponse = decodeResponse(json.getJSONObject(field.getName()), field.getType(), responseObjectModel);

注意:我建议Jackson将JSON转换为java对象。

您是否检查了类路径中可能存在的重复类?当然可以,我使用gradle来管理依赖关系我想到的另一个想法来自这样一个事实,即您正在使用泛型,并将它们与反射访问混合在一起,这在运行时评估期间可能会带来一些问题。是的,但我认为它应该起作用。。错误本身很奇怪,它说“有类型为”com.example.package.AnotherPOJO“的对象,但预期签名为”com.example.package.AnotherPOJO”“:这没有意义,这是阶级上的差异。请检查粗体字中的错误输入。com.example。bean类的class com.example上的package.ExamplePOJO.setAnotherPOJO。pacjage.ExamplePOJO'String className=“com.example.packace。”
{
    "response": { //response is an instance of ExamplePOJO
        "id":"1",
        "anotherPOJO":{
             [...]
        }
    },
    [ ...other fields...]
 }
String className = "com.example.packace." + field.getName().toUpperCase().charAt(0) + field.getName().substring(1, field.getName().length());

 //className = com.example.package.AnotherPOJO                      
 //recursive call
 objectFromResponse = decodeResponse(json.getJSONObject(field.getName()), Class.forName(className), responseObjectModel);
//recursive call
objectFromResponse = decodeResponse(
    json.getJSONObject(field.getName()),
    Class.forName(className, true, responseModel.getClassLoader()),
    responseObjectModel);
         //here I found another object inside the "response" object.  Use information from field to get class.
         else {

             objectFromResponse = decodeResponse(json.getJSONObject(field.getName()), field.getType(), responseObjectModel);