Spring MVC java.lang.IllegalStateException:无法加载应用程序上下文错误java spring-boot

jpfvwuh4  于 2022-11-15  发布在  Spring
关注(0)|答案(2)|浏览(165)

好的,我经历了很多答案,但我的问题仍然没有解决。我试图测试我的控制器-

@Controller
@Produces(MediaType.APPLICATION_JSON)
@RequestMapping(value = "/verify/email")
public class EmailController {

@Autowired
private ByEmail strategy;

@Autowired
private ApplicationConfig config;

@ResponseBody
@RequestMapping(method = RequestMethod.POST, produces = 
MediaType.APPLICATION_JSON)
public Request newRequest(@RequestBody VRequest request) throws 
IOException {
    log.info(request.toString());
    System.out.println(request.toString());
    request.setType(VType.EMAIL);
    Optional<Request> response = strategy.processRequest(request);
    return response.orElseThrow(BadRequestException::new);
}

我的测试是-

@RunWith(SpringRunner.class)
@AutoConfigureMockMvc
@WebAppConfiguration
@SpringBootTest
public class TestEmailController {

@Mock
private ByEmail strategy;

@InjectMocks
@Autowired
private EmailController controller;

@Autowired
private MockMvc mockMvc;

@Test
public void contexLoads() throws Exception {
    assertThat(controller).isNotNull();
}

当我尝试运行测试时,出现以下错误-

java.lang.IllegalStateException: Failed to load ApplicationContext

at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83)
at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:189)
at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:131)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:230)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:228)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:287)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:289)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:247)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
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:191)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'application': Unsatisfied dependency expressed through field 'configs'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'applicationConfig': Could not bind properties to ApplicationConfig (prefix=company.services.verification, ignoreInvalidFields=false, ignoreUnknownFields=true, ignoreNestedProperties=false); nested exception is org.springframework.validation.BindException: org.springframework.boot.bind.RelaxedDataBinder$RelaxedBeanPropertyBindingResult: 2 errors
Field error in object 'company.services.verification' on field 'redirectUrl': rejected value [null]; codes [NotNull.company.services.verification.redirectUrl,NotNull.redirectUrl,NotNull.java.lang.String,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [company.services.verification.redirectUrl,redirectUrl]; arguments []; default message [redirectUrl]]; default message [may not be null]
Field error in object 'company.services.verification' on field 'countries': rejected value [null]; codes [NotNull.company.services.verification.countries,NotNull.countries,NotNull.java.util.List,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [company.services.verification.countries,countries]; arguments []; default message [countries]]; default message [may not be null]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
    at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:120)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116)
    ... 24 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'applicationConfig': Could not bind properties to ApplicationConfig (prefix=company.services.verification, ignoreInvalidFields=false, ignoreUnknownFields=true, ignoreNestedProperties=false); nested exception is org.springframework.validation.BindException: org.springframework.boot.bind.RelaxedDataBinder$RelaxedBeanPropertyBindingResult: 2 errors
Field error in object 'company.services.verification' on field 'redirectUrl': rejected value [null]; codes [NotNull.company.services.verification.redirectUrl,NotNull.redirectUrl,NotNull.java.lang.String,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [company.services.verification.redirectUrl,redirectUrl]; arguments []; default message [redirectUrl]]; default message [may not be null]
Field error in object 'company.services.verification' on field 'countries': rejected value [null]; codes [NotNull.company.services.verification.countries,NotNull.countries,NotNull.java.util.List,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [company.services.verification.countries,countries]; arguments []; default message [countries]]; default message [may not be null]
    at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.postProcessBeforeInitialization(ConfigurationPropertiesBindingPostProcessor.java:334)
    at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.postProcessBeforeInitialization(ConfigurationPropertiesBindingPostProcessor.java:291)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:409)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1620)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
    ... 42 more
Caused by: org.springframework.validation.BindException: org.springframework.boot.bind.RelaxedDataBinder$RelaxedBeanPropertyBindingResult: 2 errors
Field error in object 'company.services.verification' on field 'redirectUrl': rejected value [null]; codes [NotNull.company.services.verification.redirectUrl,NotNull.redirectUrl,NotNull.java.lang.String,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [company.services.verification.redirectUrl,redirectUrl]; arguments []; default message [redirectUrl]]; default message [may not be null]
Field error in object 'company.services.verification' on field 'countries': rejected value [null]; codes [NotNull.company.services.verification.countries,NotNull.countries,NotNull.java.util.List,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [company.services.verification.countries,countries]; arguments []; default message [countries]]; default message [may not be null]
    at org.springframework.boot.bind.PropertiesConfigurationFactory.checkForBindingErrors(PropertiesConfigurationFactory.java:359)
    at org.springframework.boot.bind.PropertiesConfigurationFactory.doBindPropertiesToTarget(PropertiesConfigurationFactory.java:276)
    at org.springframework.boot.bind.PropertiesConfigurationFactory.bindPropertiesToTarget(PropertiesConfigurationFactory.java:240)
    at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.postProcessBeforeInitialization(ConfigurationPropertiesBindingPostProcessor.java:329)
    ... 55 more

这是我的应用程序测试类-

@RunWith(SpringRunner.class)
    @SpringBootTest
    public class ApplicationTests {

    @Test
    public void contextLoads() {
    }

}

下面是我的ApplicationConfig类-

@Data
@Configuration
@EnableAutoConfiguration
@ConfigurationProperties(prefix = "company.services.verification")
public class ApplicationConfig {

@NotNull
String smstype;

@NotNull
String fromEmail;

@NotNull
String subjectEmail;

@NotNull
String subjectManual;

@NotNull
List<Integer> countries;

@NotNull
String redirectUrl;
}

我的application.yaml文件定义了上述属性-

company:
    services:
      verification:
        smstype: Claims
        fromEmail: noreply@company.com
        subjectEmail: Email Verification
        subjectManual: Claim Initiated
        redirectUrl: http://www.google.com
        countries:
         - 1
         - 2
         - 3
         - 4

我经历了很多答案,但错误仍然是一样的。我正在使用Spring启动1.5.6。任何帮助吗?

3vpjnl9f

3vpjnl9f1#

首先,请将以下依赖项添加到您的项目中,并按照Spring Doc中“使用注解处理器生成您自己的元数据”的说明进行操作
http://docs.spring.io/spring-boot/docs/1.5.6.RELEASE/reference/html/configuration-metadata.html#configuration-metadata-annotation-processor
下面是用于生成自定义Spring元数据配置属性的maven依赖项

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

您的applicationconfig类还应该具有getter和setter

@Configuration
@EnableAutoConfiguration
@ConfigurationProperties(prefix = "company.services.verification")
public class ApplicationConfig {

    @NotNull
    String smstype;

    @NotNull
    String fromEmail;

    @NotNull
    String subjectEmail;

    @NotNull
    String subjectManual;

    @NotNull
    List<Integer> countries;

    @NotNull
    String redirectUrl;

    public String getSmstype() {
        return smstype;
    }

    public void setSmstype(String smstype) {
        this.smstype = smstype;
    }

    public String getFromEmail() {
        return fromEmail;
    }

    public void setFromEmail(String fromEmail) {
        this.fromEmail = fromEmail;
    }

    public String getSubjectEmail() {
        return subjectEmail;
    }

    public void setSubjectEmail(String subjectEmail) {
        this.subjectEmail = subjectEmail;
    }

    public String getSubjectManual() {
        return subjectManual;
    }

    public void setSubjectManual(String subjectManual) {
        this.subjectManual = subjectManual;
    }

    public List<Integer> getCountries() {
        return countries;
    }

    public void setCountries(List<Integer> countries) {
        this.countries = countries;
    }

    public String getRedirectUrl() {
        return redirectUrl;
    }

    public void setRedirectUrl(String redirectUrl) {
        this.redirectUrl = redirectUrl;
    }
}

电子邮件控制器类

@Controller
@Produces(MediaType.APPLICATION_JSON)
@RequestMapping(value = "/verify/email")
public class EmailController {

    @Autowired
    private ApplicationConfig config;

    @ResponseBody
    @RequestMapping(method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON)
    public String newRequest(@RequestBody String email) throws
            IOException {

        return email;
    }
}

因为我没有任何关于你的控制器中的byEmail类的想法,我删除了它。

应用程序.yaml

company:
  services:
    verification:
      from-email: noreply@company.com
      redirect-url: http://www.google.com
      subject-email: Email Verification
      smstype: Claims
      subject-manual: Claim Initiated
      countries:
        - 1
        - 2
        - 3
        - 4

这里是最重要的部分,你应该添加applicationcontext到你的测试类,并在任何测试之前进行必要的模拟操作。
EmailControllerTests.java

@RunWith(SpringRunner.class)
@AutoConfigureMockMvc
@WebAppConfiguration
@SpringBootTest
public class EmailControllerTests {
    @Autowired
    private MockMvc mockMvc;

    @Autowired
    private WebApplicationContext applicationContext;

    @Mock
    private ApplicationConfig applicationConfig;

    @Before
    public void init() throws Exception {
        MockitoAnnotations.initMocks(this);

        // @formatter:off
        this.mockMvc = webAppContextSetup(this.applicationContext)
                .alwaysDo(print())
                .build();
        // @formatter:on

        EmailController emailController = this.applicationContext.getBean(EmailController.class);

        // REPLACE YOUR SERVICES WITH the MOCKED ONES HERE
        //ReflectionTestUtils.setField(emailController, "byEmail", this.byEmail);
        ReflectionTestUtils.setField(emailController, "config", this.applicationConfig);
    }

    @Test
    public void unauthenticatedUsersCannotAddProperty() throws Exception {
        // @formatter:off
        MvcResult result = this.mockMvc.perform(post("/verify/email").contentType(MediaType.APPLICATION_JSON).content("{ahmet@ahmet.com}"))
                .andDo(print())
            .andExpect(status().isOk())
            .andReturn();
        // @formatter:on

        Assert.assertNotNull(result);
    }
}

这就是结果,一切都在正常运转...

希望这对你有帮助...

erhoui1w

erhoui1w2#

尝试使用此应用程序。yaml,验证后的所有属性只有一个选项卡。

company:
    services:
      verification:
        smstype: Claims
        fromEmail: noreply@company.com
        subjectEmail: Email Verification
        subjectManual: Claim Initiated
        redirectUrl: http://www.google.com
        countries:
          - 1
          - 2
          - 3
          - 4

选项2:使用application.propterties代替.yaml,在resources文件夹中创建application.propterties文件,内容应如下所示:

company.services.verification.smstype: Claims
company.services.verification.fromEmail: noreply@company.com
company.services.verification.subjectEmail: Email Verification
company.services.verification.subjectManual: Claim Initiated
company.services.verification.redirectUrl: http://www.google.com
company.services.verification.countries[0]: 1
company.services.verification.countries[1]: 2
company.services.verification.countries[2]: 3
company.services.verification.countries[3]: 4

配置类示例

@Configuration
@ConfigurationProperties(prefix = "company.services.verification")
public class MyConfig {

    private String smstype;

    private String fromEmail;

    private String subjectEmail;

    private String subjectManual;

    private List<Integer> countries;

    private String redirectUrl;

    public String getSmstype() {
        return smstype;
    }

    public void setSmstype(String smstype) {
        this.smstype = smstype;
    }

    public String getFromEmail() {
        return fromEmail;
    }

    public void setFromEmail(String fromEmail) {
        this.fromEmail = fromEmail;
    }

    public String getSubjectEmail() {
        return subjectEmail;
    }

    public void setSubjectEmail(String subjectEmail) {
        this.subjectEmail = subjectEmail;
    }

    public String getSubjectManual() {
        return subjectManual;
    }

    public void setSubjectManual(String subjectManual) {
        this.subjectManual = subjectManual;
    }

    public List<Integer> getCountries() {
        return countries;
    }

    public void setCountries(List<Integer> countries) {
        this.countries = countries;
    }

    public String getRedirectUrl() {
        return redirectUrl;
    }

    public void setRedirectUrl(String redirectUrl) {
        this.redirectUrl = redirectUrl;
    }
}

相关问题