java - 访问由 Spring 的类转换器创建的对象上的 getter 时出现 ArrayIndexOutOfBoundsException

标签 java spring-boot java-8 converters

我正在将一个对象转换为另一个对象,但是当我尝试在创建的对象上使用 getter 时,我收到了 ArrayIndexOutOfBoundsException。

数据是字段中的一个简单字符串,并且位于一个非常直接的对象上。

我在 Spring Boot 2.1.1 和 2.1.7 上都遇到了同样的问题。

注意:要重现该问题,我必须使用 mvn testmvn install 运行,或使用 Eclipse 的代码覆盖工具。使用 Eclipse 的 Run 或 Debug utils 成功且没有错误。

异常:

[ERROR] storeWithEncryption(com.forms.service.SpringConversionServiceTest)  Time elapsed: 0.003 s  <<< ERROR!
java.lang.ArrayIndexOutOfBoundsException: 1
        at com.forms.service.SpringConversionServiceTest$To.<init>(SpringConversionServiceTest.java:45)
        at com.forms.service.SpringConversionServiceTest.storeWithEncryption(SpringConversionServiceTest.java:26)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
        at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
        at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)
        at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
        at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
        at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
        at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
        at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
        at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
        at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
        at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:365)
        at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:273)
        at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:238)
        at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:159)
        at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:384)
        at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:345)
        at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:126)
        at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:418)

测试类

package com.forms.service;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.convert.ConversionService;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;

import com.forms.Application;

@RunWith(SpringRunner.class)
@ActiveProfiles("test")
@SpringBootTest(classes = { Application.class })
public class SpringConversionServiceTest {

    @Autowired
    private ConversionService conversionService;

    @Test
    public void storeWithEncryption() throws Exception {
        From from = new From();
        from.bob = "nope";
        from.bob2 = "yep";
        new To(conversionService.convert(from, To.class));
    }

    public static final class From {

        String bob;
        String bob2;
    }

    public static final class To {


        public To() {
            // TODO Auto-generated constructor stub
        }

        public To(To convert) {
            this.bob = convert.bob;
            this.bob2 = convert.bob2;
        }

        String bob;
        String bob2;
    }
}

从到转换器

package com.forms.service;

import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;
import com.forms.service.SpringConversionServiceTest.From;
import com.forms.service.SpringConversionServiceTest.To;
import com.forms.service.converter.AbstractReflectionConverter;

@Component
public class FromToConverter extends AbstractReflectionConverter implements Converter<From, To> {

    public To convert(From from) {
        To to = new To();
        try {
            // 1 to 1 conversions
            conversionByReflection(from, to);
        } catch (IllegalAccessException e) {
            throw new IllegalArgumentException("The source external Header cannot be converted into an internal Header", e);
        }
        return to;
    }

}

应用程序.java

package com.forms;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ImportResource;

@SpringBootApplication
@ImportResource({ "classpath:spring/camel-context.xml" })
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Pom:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.7.RELEASE</version>
</parent>

最佳答案

为了解决这个问题,我必须从使用 spring 的反射 ConversionService 方法更改为仅手动插入转换器中的值。

我不会将此标记为解决方案,因为如果您需要使用反射,它并不能真正解决问题,但我将其放在这里作为解决方法。

关于java - 访问由 Spring 的类转换器创建的对象上的 getter 时出现 ArrayIndexOutOfBoundsException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57419472/

相关文章:

java - RxJava 出错后如何继续流式传输项目?

java - 正则表达式 - SQL 语句

java - Spring Boot 无法正确渲染 View

java - 如何在 Spring Boot 应用程序中缓存复杂对象,例如 Map<String, List<Car>>

java-8 - 引用特定对象的实例方法会破坏 Java 中的类型安全吗?

java - 如果不将行转换为字符串,代码可以正常工作吗?

java - 如果谓词中给出了所有条件,则获取所有匹配的非空元素

java - 使用 Google People API (Java) 检索有关联系人的信息

java - 如何在 Java 中仅初始化一次局部变量

java - Spring Data JPA依赖错误