0

したがって、単純な REST Web アプリケーションがあり、コントローラーが DAO を直接呼び出す場合、JDBC 呼び出しは正常に機能しますが、コントローラーが代わりに DAO を呼び出す別のクラスを呼び出すと、NullPointerException (NPE) で失敗します。

これが私のコントローラーです:

@Component
@Scope("request")
@Path("/emsrequest")
public class EMSRequest {

    // I'm using this for testing
    @GET
    @Path("/xml/{accountNumber}")
    @Produces({MediaType.TEXT_PLAIN})
    public String requestByAccountNumber_XML(
            @PathParam("accountNumber") String accountNumber) {

        ReqSubTest los = new ReqSubTest();

        return "account (LOS) number is : " + los.testSql(Integer.parseInt(accountNumber)) + "!";
    }
}

中間 (サービス) クラスは次のとおりです。

package com.company.demo.mercury.processmanager.components;

import com.company.demo.pmrws.dao.EMSRequestDaoImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class ReqSubTest {

    @Autowired
    EMSRequestDaoImpl dao = new EMSRequestDaoImpl();

    public int testSql(int quantity){
        return dao.getNextTableIds("sys_process_tbl", quantity);

    }
}

DAO の実装は次のとおりです。

package com.company.demo.pmrws.dao;

import org.apache.log4j.Logger;
import org.springframework.jdbc.core.support.JdbcDaoSupport;

public class EMSRequestDaoImpl extends JdbcDaoSupport {

    private static final Logger logger = Logger.getLogger(EMSRequestDaoImpl.class);

    public int getNextTableIds(String tableName, int quantity) {

        if (logger.isDebugEnabled()) {
            logger.trace("Entering getNextTableIds");
        }

        if (getJdbcTemplate() == null) {
            System.out.println("UH OH!");
        }

        String selectSql = "select next_id "
                + "from sys_key_tbl "
                + "where table_name = ? ";
        String updateSql = "update sys_key_tbl "
                + "set next_id = ? "
                + "where table_name = ? and next_id = ? ";
        int lastId = -1;
        int updateCount = 0;
        while (updateCount == 0) {
            lastId = getJdbcTemplate().queryForInt(selectSql,
                    new Object[]{tableName});
            updateCount = getJdbcTemplate().update(updateSql,
                    new Object[]{lastId + quantity, tableName, lastId});
        }

        if (logger.isDebugEnabled()) {
            logger.trace("Leaving getNextTableIds");
        }
        return lastId + 1;
    }
}

アプリケーション コンテキスト XML:

<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-2.5.xsd
   http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
    <context:component-scan base-package="com.company.demo.pmrws"/>

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
          destroy-method="close">
        <property name="driverClassName" value="com.sybase.jdbc3.jdbc.SybDataSource" />
        <property name="url"
                  value="jdbc:sybase:Tds:blah:10240/BLAH_DB1" />
        <property name="username" value="blah" />
        <property name="password" value="blah" />
    </bean>

    <bean id="dataSourceMain" class="org.apache.commons.dbcp.BasicDataSource"
          destroy-method="close">
        <property name="driverClassName" value="com.sybase.jdbc3.jdbc.SybDataSource" />
        <property name="url"
                  value="jdbc:sybase:Tds:blah:10240/BLAH_DB2" />
        <property name="username" value="blah" />
        <property name="password" value="blah" />
    </bean>
    </bean>

    <!--    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource" />
    </bean>-->

    <bean id="emsResponseDao" class="com.company.demo.pmrws.dao.EMSResponseDaoImpl">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <bean id="emsStatusDao" class="com.company.demo.pmrws.dao.EMSStatusDaoImpl">
        <property name="dataSource" ref="dataSourceMain" />
    </bean>

<!--    <bean id="collateralSybaseEmsDao" class="com.company.demo.dao.CollateralSybaseEmsDaoImpl">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <bean id="collateralSybaseDao" class="com.company.demo.dao.CollateralSybaseDaoImpl">
        <property name="dataSource" ref="dataSource" />
    </bean>-->

    <bean id="emsRequestDao" class="com.company.demo.pmrws.dao.EMSRequestDaoImpl">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <context:component-scan base-package="com.company.demo.mercury.processmanager.components" />

</beans>

私は何が欠けていますか?ところで、これはSpring 2.5です。

4

2 に答える 2

3

これは、ReqSubTest los = new ReqSubTest();SpringBeanではなく新しい通常のJavaObjectインスタンスを作成するため、losインスタンスに何も注入されないためです。

それを修正する3つの方法。

  • Spring経由でReqSubTest los = new ReqSubTest();注入する代わりに、これにはSpringBeanも必要ですlosEMSRequest

例:

@Component public class EMSRequest {

    @Autowire ReqSubTest los;

    public String requestByAccountNumber_XML(@PathParam("accountNumber") String accountNumber) {
        return "account (LOS) number is : " + los.testSql(Integer.parseInt(accountNumber)) + "!";
    } 
}
  • ReqSubTest los = new ReqSubTest();使用する代わりにReqSubTest los = springApplicationContext.getBean(ReqSubTest.class)
  • 実際のAspectJを使用する@Configurable場合は、インスタンスが作成されている場合でも、他のBeanを追加してからSpringインジェクトでき​​ますnew(を介して有効にする必要があります<context:spring-configured />)-アノテーションを追加してからEMSRequest、最初の項目で提案されているような通常のインジェクションを使用するか、にReqSubTest
于 2013-01-09T07:00:58.653 に答える
0

私は問題を理解したと思います。問題はサービスクラスにありますReqSubTest

そこでDAOクラスを自動配線しましたが、そこで初期化しないでください。したがって、DAO宣言の初期化部分を削除するだけで、準備は完了です。これで、サービスクラスでの宣言は次のようになります。

@Autowired
private EMSRequestDaoImpl dao;

また、コントローラーでは、Serviceクラスを自動配線する必要があります。また、関数自体に新しいオブジェクトを作成しないでください。

@Autowired
private ReqSubTest service;

これがお役に立てば幸いです。乾杯。

于 2013-01-09T07:00:10.040 に答える