2012-04-26 57 views
6

我已经搜索并尝试了所有我能想到的方法来解决此问题,但是TestService类中的Dao始终为空。我看到Spring日志显示Dao被注入以及TestService类。我曾尝试在WTP下运行eclipse以及直接在Tomcat中运行。两者都导致相同的错误。任何人都可以帮助解码错误,导致Dao在TestService类中为null。Jersey + Spring 3 + Maven 3 + Tomcat 7 @Component类中的资源始终为空

版本:

Jersey 1.8 
Spring 3.0.5Release 
Tomcat apache-tomcat-7.0.27 
Maven 3.0.3 (r1075438; 2011-02-28 12:31:09-0500) 
Java 1.6.0_31 

Eclipse Java EE IDE for Web Developers. 
Version: Indigo Service Release 2 
Build id: 20120216-1857 

记录 - 显示注射发生(切断DEBUG和类名为了简洁)

Creating shared instance of singleton bean 'dataSource' 
Creating instance of bean 'dataSource' 
Eagerly caching bean 'dataSource' to allow for resolving potential circular references 
Finished creating instance of bean 'dataSource' 
Creating shared instance of singleton bean 'jdbcTemplate' 
Creating instance of bean 'jdbcTemplate' 
Eagerly caching bean 'jdbcTemplate' to allow for resolving potential circular references 
Returning cached instance of singleton bean 'dataSource' 
Invoking afterPropertiesSet() on bean with name 'jdbcTemplate' 
Finished creating instance of bean 'jdbcTemplate' 
Creating shared instance of singleton bean 'testClassDao' 
Creating instance of bean 'testClassDao' 
Found injected element on class [test.dao.TestClassDao]: AutowiredMethodElement for public void test.dao.TestClassDao.setDataSource(javax.sql.DataSource) 
Eagerly caching bean 'testClassDao' to allow for resolving potential circular references 
Processing injected method of bean 'testClassDao': AutowiredMethodElement for public void test.dao.TestClassDao.setDataSource(javax.sql.DataSource) 
Returning cached instance of singleton bean 'dataSource' 
Autowiring by type from bean name 'testClassDao' to bean named 'dataSource' 
Finished creating instance of bean 'testClassDao' 
Creating shared instance of singleton bean 'testService' 
Creating instance of bean 'testService' 
Found injected element on class [test.service.admin.TestService]: AutowiredFieldElement for test.dao.TestClassDao test.service.admin.TestService.dao 
Eagerly caching bean 'testService' to allow for resolving potential circular references 
Processing injected method of bean 'testService': AutowiredFieldElement for test.dao.TestClassDao test.service.admin.TestService.dao 
Returning cached instance of singleton bean 'testClassDao' 
Autowiring by type from bean name 'testService' to bean named 'testClassDao' 
Finished creating instance of bean 'testService' 

错误 - 空指针异常在TestService.java因为TestClassDao为空

Apr 25, 2012 9:07:04 PM org.apache.catalina.core.StandardWrapperValve invoke 
SEVERE: Servlet.service() for servlet [jersey] in context with path [/test-service]  threw exception 
java.lang.NullPointerException 
at test.service.admin.TestService.createCompanyProfile(TestService.java:35) 

TestClassDao.java

package test.dao; 
import javax.sql.DataSource; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; 
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; 
import org.springframework.stereotype.Repository; 

import test.domain.TestClass; 

@Repository 
public class TestClassDao { 

    private NamedParameterJdbcTemplate namedParamJdbcTemplate; 
    private DataSource dataSource; 


    @Autowired 
    public void setDataSource(DataSource dataSource) { 
     this.dataSource = dataSource; 
     this.namedParamJdbcTemplate = new NamedParameterJdbcTemplate(dataSource); 
    } 

    public void insertTestClass(TestClass testClass) 
    {  
     String query = "INSERT INTO TEST_CLASS_TABLE(NAME) VALUES (:NAME)"; 

     MapSqlParameterSource namedParams = new MapSqlParameterSource(); 

     mapParams(namedParams, testClass); 

     namedParamJdbcTemplate.update(query, namedParams); 
    } 




    private void mapParams(MapSqlParameterSource namedParams, TestClass testClass) 
    { 

      namedParams.addValue("NAME", testClass.getName()); 

    } 
} 

TestClass.java

package test.domain; 
import java.util.Date; 
import java.util.HashSet; 
import java.util.Set; 

public class TestClass implements java.io.Serializable { 
    private String name; 

    public TestClass(String name){ 
     this.name = name; 

    } 

    public String getName() { 
     return this.name; 
    } 
} 

TestService.java

package test.service.admin; 

import javax.ws.rs.GET; 
import javax.ws.rs.Path; 
import javax.ws.rs.core.Context; 
import javax.ws.rs.core.Request; 
import javax.ws.rs.core.UriInfo; 

import org.apache.log4j.Logger; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Component; 

import test.dao.TestClassDao; 
import test.domain.TestClass; 

@Path("/resttest") 
@Component 
public class TestService { 
    @Context 
    UriInfo uriInfo; 
    @Context 
    Request request; 
    @Autowired 
    TestClassDao dao; 

    static Logger log = Logger.getLogger(TestService.class); 

    @GET 
    @Path("/test") 
    public String createCompanyProfile() { 

     TestClass test = new TestClass("MyTestName"); 

     dao.insertTestClass(test); 

     return "test done"; 
    } 
} 

的applicationContext.xml

<?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" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.0.xsd"> 

    <context:annotation-config /> 

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> 
     <property name="driverClassName" value="com.mysql.jdbc.Driver" /> 
     <property name="url" value="jdbc:mysql://localhost:1234/testClassDatabase" /> 
     <property name="username" value="user" /> 
     <property name="password" value="password" /> 
    </bean> 

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> 
     <property name="dataSource"> 
      <ref bean="dataSource" /> 
     </property> 
    </bean> 
    <context:component-scan base-package="test"/> 
</beans> 

的web.xml

<!DOCTYPE web-app PUBLIC 
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" 
"http://java.sun.com/dtd/web-app_2_3.dtd" > 
<web-app> 
    <context-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>classpath:applicationContext.xml</param-value> 
    </context-param> 
    <listener> 
     <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class> 
    </listener> 
    <listener> 
     <listener-class> 
      org.springframework.web.context.ContextLoaderListener 
     </listener-class> 
    </listener> 

    <servlet> 
     <servlet-name>jersey</servlet-name> 
     <servlet-class> 
      com.sun.jersey.spi.container.servlet.ServletContainer 
     </servlet-class> 
     <load-on-startup>1</load-on-startup> 
    </servlet> 
    <servlet-mapping> 
     <servlet-name>jersey</servlet-name> 
     <url-pattern>/*</url-pattern> 
    </servlet-mapping> 
</web-app> 

更新:增加了本作的网络应用程序,但它并没有改变任何东西

<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> 

pom.xml的 - 我认为这是其中的问题可能在于,依赖什么

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>test-service</groupId> 
    <artifactId>test-service</artifactId> 
    <packaging>war</packaging> 
    <version>0.0.1-SNAPSHOT</version> 
    <name>Test Service</name> 
    <url>http://maven.apache.org</url> 
    <dependencies> 
     <!-- Jersey --> 
     <dependency> 
      <groupId>commons-dbcp</groupId> 
      <artifactId>commons-dbcp</artifactId> 
      <version>1.4</version> 
     </dependency> 
     <dependency> 
      <groupId>mysql</groupId> 
      <artifactId>mysql-connector-java</artifactId> 
      <version>5.1.19</version> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-jdbc</artifactId> 
      <version>${org.springframework.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>com.sun.jersey</groupId> 
      <artifactId>jersey-server</artifactId> 
      <version>${jersey.version}</version> 
     </dependency> 

     <!-- Spring 3 dependencies --> 
     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-core</artifactId> 
      <version>${org.springframework.version}</version> 
     </dependency> 

     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-context</artifactId> 
      <version>${org.springframework.version}</version> 
     </dependency> 

     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-web</artifactId> 
      <version>${org.springframework.version}</version> 
     </dependency> 

     <!-- Jersey + Spring --> 
     <dependency> 
      <groupId>com.sun.jersey.contribs</groupId> 
      <artifactId>jersey-spring</artifactId> 
      <version>${jersey.version}</version> 
      <exclusions> 
       <exclusion> 
        <groupId>org.springframework</groupId> 
        <artifactId>spring</artifactId> 
       </exclusion> 
       <exclusion> 
        <groupId>org.springframework</groupId> 
        <artifactId>spring-core</artifactId> 
       </exclusion> 
       <exclusion> 
        <groupId>org.springframework</groupId> 
        <artifactId>spring-web</artifactId> 
       </exclusion> 
       <exclusion> 
        <groupId>org.springframework</groupId> 
        <artifactId>spring-beans</artifactId> 
       </exclusion> 
       <exclusion> 
        <groupId>org.springframework</groupId> 
        <artifactId>spring-context</artifactId> 
       </exclusion> 
      </exclusions> 
     </dependency> 
     <dependency> 
      <groupId>junit</groupId> 
      <artifactId>junit</artifactId> 
      <version>4.8.2</version> 
      <scope>test</scope> 
     </dependency> 
     <dependency> 
      <groupId>log4j</groupId> 
      <artifactId>log4j</artifactId> 
      <version>1.2.16</version> 
     </dependency> 
    </dependencies> 
    <build> 
     <finalName>test-service</finalName> 
     <plugins> 
      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-compiler-plugin</artifactId> 
       <configuration> 
        <source>1.6</source> 
        <target>1.6</target> 
       </configuration> 
      </plugin> 
     </plugins> 
    </build> 
    <properties> 
     <org.springframework.version>3.0.5.RELEASE</org.springframework.version> 
     <jersey.version>1.8</jersey.version> 
    </properties> 
</project> 

更新固定:我的朋友看了看,注意到我没有为com.sun.jersey.config.property.packages设置参数,一旦我们添加了,一切都自动工作。

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

    <context-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>classpath:server-context.xml</param-value> 
    </context-param> 
    <listener> 
     <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class> 
    </listener> 
    <listener> 
     <listener-class> 
      org.springframework.web.context.ContextLoaderListener 
     </listener-class> 
    </listener> 

    <servlet> 
     <servlet-name>jersey-serlvet</servlet-name> 
     <servlet-class> 
      com.sun.jersey.spi.spring.container.servlet.SpringServlet 
     </servlet-class> 
     <init-param> 
      <param-name> 
           com.sun.jersey.config.property.packages 
         </param-name> 
      <param-value>service</param-value> 
     </init-param> 
     <load-on-startup>1</load-on-startup> 
    </servlet> 

    <servlet-mapping> 
     <servlet-name>jersey-serlvet</servlet-name> 
     <url-pattern>/*</url-pattern> 
    </servlet-mapping> 
</web-app> 

回答

7

春天注入TestService的一个DAO的实例,但该实例不是请求要去一个。您正在使用Jersey的ServletContainer来托管您的Jersey应用程序,它不以任何方式与Spring集成。它将根据需要自行创建实例,这显然不会由Spring注入(无论如何不进行字节码编织)。我建议使用SpringServlet,它是一个ServletContainer,它知道如何从Spring上下文获取资源类。这将清除你的问题。

+0

感谢您的评论,但它是一个简单的糟糕的web.xml,请参阅更新的答案,了解我的朋友能够修复它。 – Dennis 2012-04-26 04:38:19

+0

恐怕你的更新是错误的。它没有开始工作,因为init-param。这是因为你切换到SpringServlet,就像我在我的回答中所说的那样。你的init-param是多余的。它只被ServletContainer使用。 SpringServlet从Spring获取它的所有对象。此外,你的参数值是错误的。它应该是“test.service”或“test.service.admin”以查找您的资源类。您可以轻松地测试我所说的所有内容,方法是更换回ServletContainer并观察它再次中断。 – 2012-04-26 05:11:24

+0

我的不好我甚至没有看到昨晚,即使你说我仍然没有。我想这就是你在工作20小时后会发生什么。谢谢,很好的电话! – Dennis 2012-04-26 14:15:34

0

同瑞恩指出的 - 你的ServletContainer的servlet不知道Spring容器,所以你@Resource/@Autowired永远不会被依赖注入。

改为使用SpringServlet,或者将它添加到web.xml中,或者将它添加到Spring WebInitializer中,而不是两者都使用。看下面的例子。

这里的代码示例web.xml

<servlet> 
    <servlet-name>jersey-spring</servlet-name> 
    <servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class> 
</servlet> 
<servlet-mapping> 
    <servlet-name>jersey-spring</servlet-name> 
    <url-pattern>/resources/*</url-pattern> 
    <load-on-startup>1</load-on-startup> 
    <init-param> 
     <param-name>com.sun.jersey.config.property.packages</param-name> 
     <param-value>phonebook.rest</param-value> 
    </init-param> 
</servlet-mapping> 

这里是为您定制WebInitializer代码示例:

public class PhonebookApplicationWebInitializer implements WebApplicationInitializer { 

    @Override 
    public void onStartup(ServletContext container) throws ServletException { 

     AnnotationConfigWebApplicationContext factory = new AnnotationConfigWebApplicationContext(); 
     // factory.scan("phonebook.configuration"); 
     factory.register(PhonebookConfiguration.class); 

     ServletRegistration.Dynamic dispatcher = container.addServlet("jersey-spring", new SpringServlet()); 
     dispatcher.setLoadOnStartup(1); 
     dispatcher.addMapping("/resources/*"); 
     dispatcher.setInitParameter("com.sun.jersey.config.property.packages", "phonebook.rest"); 

     container.addListener(new ContextLoaderListener(factory)); 

    } 

} 

你可以看到春+新泽西集成这里有些一个很好的例子: http://www.mkyong.com/webservices/jax-rs/jersey-spring-integration-example/