在 Spring MVC 控制器中注入 Jaxb2Marshaller

Posted

技术标签:

【中文标题】在 Spring MVC 控制器中注入 Jaxb2Marshaller【英文标题】:Injecting Jaxb2Marshaller in Spring MVC controller 【发布时间】:2014-11-06 14:35:55 【问题描述】:

我正在尝试在我的控制器类中将静态 xml 转换为 POJO(解组)。我正在使用 Jaxb2Marshaller,并在 root context

中以以下方式配置
<oxm:jaxb2-marshaller id="marshaller">
    <oxm:class-to-be-bound name="org.springframework.ws.samples.airline.schema.Airport"/>        
</oxm:jaxb2-marshaller>

我正在尝试使用自动装配注入编组器。但它会抛出 No Bean Found Exception

@AutoWired
private Unmarshaller marshaller;

如何在控制器中注入编组器。任何其他方法或指出我的代码中的错误会有帮助吗?

【问题讨论】:

你在dispatcher-servlet.xml中配置marshaller了吗? Spring 中没有 UnMarshaller 类... Spring 中有 Unmarshaller 类。所以我怀疑你只是使用了错误的类型。 @DanglingPiyush 是的,我已经在 dispatch-servlet.xml 中配置了 bean。现在我将它移到应用程序上下文现在它可以工作了。谢谢 @M.Deinum 抱歉打错了 @karthik 我只想建议这个..你已经这样做了..cheers 【参考方案1】:

我最近遇到了类似的问题,我认为我提出的解决方案与公认的答案不同,我认为值得提出以供参考。

请确认我对您的情况的理解是正确的:

在调度程序上下文中,您有:

    创建了 jaxb2 编组器 创建了控制器。 在其中一个控制器中,您尝试注入编组器(通过注释)

但是注入失败。当将 JAXB2 Marshaller 的创建移动到根上下文时,它可以工作。

如果我对您的情况的描述是正确的,请继续阅读:


您所做的实际上是正确的:JAXB2 Marshaller 和 Controller bean 是在同一上下文(调度程序上下文)中创建的,并且 Controller bean 应该能够与 marshaller bean 一起注入。

问题可能出在根上下文中,您创建了 另一个 控制器 bean。并且根上下文中的额外控制器 bean 不能用编组器注入(因为编组器 bean 存在于无法访问的子上下文中)。因此,当您将编组器 bean 移动到根上下文时,一切似乎都正常(因为根上下文中的控制器和调度程序上下文都可以看到编组器 bean)

常见的问题是在您的根上下文 xml 中,您声明了 component-scan。默认情况下,component-scan 将包括在其扫描期间用@Controller 注释的类。这会在您的根上下文中带来另一个控制器 bean。

如果是这种情况,解决方案很简单:只需在根上下文组件扫描中排除 Controller(并且在调度程序上下文组件扫描中仅包含 Controller)

根上下文 xml:

<context:component-scan base-package="com.foo">
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

调度程序上下文 xml:

<context:component-scan base-package="com.foo" use-default-filters="false">
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

【讨论】:

很好地解释了阿德里安...我们也可以使用这个作为替代方案。 我个人认为这不是“替代方案”,因为我认为接受的答案实际上是错误的【参考方案2】:

Spring上下文配置

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:util="http://www.springframework.org/schema/util" xmlns:context="http://www.springframework.org/schema/context"
        xmlns:automation="http://www.springframework.org/schema/automation"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xmlns:oxm="http://www.springframework.org/schema/oxm"
        xmlns:task="http://www.springframework.org/schema/task"
        xsi:schemaLocation="http://www.springframework.org/schema/beans 
                            http://www.springframework.org/schema/beans/spring-beans.xsd
                            http://www.springframework.org/schema/util 
                            http://www.springframework.org/schema/util/spring-util.xsd
                            http://www.springframework.org/schema/context 
                            http://www.springframework.org/schema/context/spring-context.xsd
                            http://www.springframework.org/schema/automation
                            http://www.springframework.org/schema/automation/automation.xsd
                            http://www.springframework.org/schema/task 
                            http://www.springframework.org/schema/task/spring-task.xsd
                            http://www.springframework.org/schema/oxm
                            http://www.springframework.org/schema/oxm/spring-oxm.xsd">

        <context:annotation-config/>

        <oxm:jaxb2-marshaller id="jaxb2Marshaller">
            <oxm:class-to-be-bound name="your.package.Prova" />
        </oxm:jaxb2-marshaller>

    </beans>

@AutoWired
private org.springframework.oxm.Unmarshaller jaxb2Marshaller;

【讨论】:

感谢您的回答它有效但是为什么如果我在 dispatcher-servlet.xml 中配置它不起作用(我的意思是在 servlet 的上下文中)? 我认为你应该看到这个link 我不清楚的一件事:dispatcher-servlet.xml 将创建一个单独的 spring 应用程序上下文(我相信它是主上下文的子上下文),并且在这个调度程序上下文中,创建了 jaxb2marshaller 和控制器。它们都在相同的上下文中,但为什么不能注入 jaxb2marshaller? applicationContext.xml 定义了“根 webapp 上下文”的 bean,即与 webapp 关联的上下文。 dispatcher-servlet.xml(或任何其他名称)为一个 servlet 的应用程序上下文定义了 bean。 这就是我的理解。而且我相信您的建议实际上是错误的:我们不应该将与调度程序相关的配置(jaxb2 marshaller)放在根上下文中。它应该放在调度程序上下文中。 No Bean Found Exception 的原因是由另一个问题引起的(我已经添加了另一个答案)

以上是关于在 Spring MVC 控制器中注入 Jaxb2Marshaller的主要内容,如果未能解决你的问题,请参考以下文章

Spring 3 MVC Controller 集成测试 - 将 Principal 注入方法

在测试控制器方法时,Spring MVC 4.2.6 版似乎没有将模拟服务注入控制器

Spring MVC原理及配置详解

Spring MVC原理及配置详解

Spring MVC原理及配置详解

常用web开发框架:Spring MVC的简单介绍与使用