尝试将 Spring 与 Jersey 一起使用时出现 NoSuchBeanDefinitionException

NoSuchBeanDefinitionException when trying to use Spring with Jersey

我不确定问题是否是因为我对 Spring 和 Jersey 使用了相同的 class。 但是每当我尝试创建一个 bean 时,我都会得到这个异常:

Feb 18, 2015 2:13:12 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [Testing] in context with path [/testing] threw exception [com.sun.jersey.api.container.ContainerException: Unable to create resource class com.sample.test.TestWebService] with root cause
    org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'dataSource' is defined
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:529)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1094)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:276)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:192)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1075)
    at com.sample.test.TestWebService.setServletContext(TestWebService.java:54)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at com.sun.jersey.server.spi.component.ResourceComponentInjector.inject(ResourceComponentInjector.java:231)
    at com.sun.jersey.server.spi.component.ResourceComponentConstructor.construct(ResourceComponentConstructor.java:180)
    at com.sun.jersey.server.impl.resource.PerRequestFactory$PerRequest._getInstance(PerRequestFactory.java:182)
    at com.sun.jersey.server.impl.resource.PerRequestFactory$AbstractPerRequest.getInstance(PerRequestFactory.java:144)
    at com.sun.jersey.server.impl.application.WebApplicationContext.getResource(WebApplicationContext.java:238)
    at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:83)
    at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
    at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84)
    at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1469)
    at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1400)
    at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1349)
    at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1339)
    at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416)
    at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537)
    at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:708)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1074)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:314)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Unknown Source)

这是我的 web.xml 的样子:

<?xml version="1.0" encoding="UTF-8"?>
<web-app
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID"
    version="2.5" >

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:spring-test.xml</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>


    <servlet>
        <servlet-name>Testing</servlet-name>
        <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>com.sample.test</param-name>
            <param-value>Testing</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>Testing</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>

</web-app>

这是 spring-test.xml 的样子(满载 :P):

<?xml  version="1.0" encoding="UTF-8"?>
<beans
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jee="http://www.springframework.org/schema/jee"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xmlns:lang="http://www.springframework.org/schema/lang"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.6.xsd
                        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.6.xsd
                        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.6.xsd
                        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.6.xsd
                        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jdbc-3.0.6.xsd
                        http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.0.6.xsd
                        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.6.xsd
                        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.6.xsd">

    <context:component-scan base-package="com.sample.test"/>

    <jee:jndi-lookup id="dataSource" jndi-name="java:/comp/evn/jdbc/localdb2"/>

    <bean id="npJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
        <constructor-arg ref="dataSource"/>
    </bean>
</beans>

这是我的 TestWebservice.java,它使用球衣的@Path:

package com.sample.test;

import javax.servlet.ServletContext;
import javax.sql.DataSource;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

@Path("test")
@Component
public class TestWebService {
    private ServletContext sc;

    @Autowired
    private DataSource dataSource;

    @Autowired
    private NamedParameterJdbcTemplate npJdbcTemplate;

    @Context
    public void setServletContext(ServletContext context) {
        this.sc = context;

        WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(sc);

        /*
         * none of these work, tried both
         */

        //NamedParameterJdbcTemplate npJdbcTemplate = (NamedParameterJdbcTemplate) ctx.getBean("npJdbcTemplate");
        DataSource dataSource = (DataSource) ctx.getBean("dataSource");
    }

    @GET
    @Path("employee/{id}")
    @Produces(MediaType.TEXT_PLAIN)
    public String getEmployee(@PathParam("id") String id) {
        return id;
    }
}

我认为你的 beans 文件是问题所在,当我使用它时我得到 "length: 8"

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

    <context:annotation-config />
    <context:component-scan base-package="com.sample.test"/>

    <!--
    <jee:jndi-lookup id="dataSource" jndi-name="java:/comp/evn/jdbc/localdb2"/>

    <bean id="npJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
        <constructor-arg ref="dataSource"/>
    </bean>
    -->

<!--    <bean id="testB" class="com.sample.test.TestB"></bean> -->

<!--    <bean id="testJdbc" class="com.sample.test.TestJdbc"> -->
    <!--
        <property name="npJdbcTemplate" ref="npJdbcTemplate" />
        <property name="dataSource" ref="dataSource" />
    -->
<!--        <property name="testB" ref="testB" /> 
    </bean> -->
</beans>

Jersey 示例 zip 分发可以下载并 运行 在本地,但您也可以在线查看。我认为您需要进行 2 项主要配置更改:

  1. web.xml 需要 "Application"。在这里查看 init-param https://github.com/jersey/jersey/blob/2.16/examples/helloworld-spring-webapp/src/main/webapp/WEB-INF/web.xml

    1. 您的 "Application" 实施应类似于以下内容: https://github.com/jersey/jersey/blob/2.16/examples/helloworld-spring-webapp/src/main/java/org/glassfish/jersey/examples/helloworld/spring/MyApplication.java