2012-03-07 84 views
1

我想將一個字符串數組從Web服務傳遞到Spring Web應用程序。春季用盡請求的輸入流

Web服務代碼是:

/** 
* 
*/ 
package lnt.remote.ws; 

import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
import java.io.IOException; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import java.net.HttpURLConnection; 
import java.net.MalformedURLException; 
import java.net.URL; 
import java.util.Properties; 

import javax.jws.WebMethod; 
import javax.jws.WebService; 

import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 

/** 
* @author 298790 
* 
*   This class is a JAX-WS end-point implementation and contains 
*   method(s) to fire batch jobs pertaining to reports 
*/ 
@WebService 
public class BatchJobWS { 

    private static String remoteAppURL; 
    private static Logger log = LoggerFactory.getLogger(Constants.WS_LOGGER); 

    static { 
     try { 

      Properties props = new Properties(); 
      props.load(BatchJobWS.class.getResourceAsStream("/url.properties")); 

      remoteAppURL = props.getProperty(Constants.REMOTE_APP_URL); 

      log.info("In BatchJobWS , remote app. url is {}", remoteAppURL); 

     } catch (FileNotFoundException e) { 
      // TODO Auto-generated catch block 
      // e.printStackTrace(); 
      log.error("FileNotFoundException in static block of BatchJobWS", e); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      // e.printStackTrace(); 
      log.error("IOException in static block of BatchJobWS", e); 
     } 

    } 

    @WebMethod 
    public String[] generateReportBatchJob(String... params) { 

     HttpURLConnection httpConn; 
     URL remotePayrollUrl = null; 
     ObjectOutputStream oos = null; 
     String[] returnValues = null; 

     log.info("In BatchJobWS.generateReportBatchJob(...),params = {}", 
       params); 

     if (params == null || params.length == 0) { 
      return null; 
     } 

     try { 
      remotePayrollUrl = new URL(remoteAppURL); 
     } catch (MalformedURLException e1) { 
      // TODO Auto-generated catch block 
      // e1.printStackTrace(); 
      log.error(
        "MalformedURLException in BatchJobWS.generateReportBatchJob(...)", 
        e1); 
     } 

     /* 
     * Give some thought to which exception(s) be handled and which must be 
     * thrown 
     */ 
     try { 
      httpConn = (HttpURLConnection) remotePayrollUrl.openConnection(); 
      httpConn.setDoOutput(true); 
      httpConn.setUseCaches(false); 

      oos = new ObjectOutputStream(httpConn.getOutputStream()); 

      log.info("Writing params to the outputstream"); 

      oos.writeObject(params); 

      oos.flush(); 
      oos.close(); 

      ObjectInputStream ois = new ObjectInputStream(
        httpConn.getInputStream()); 

      Object returnParams = ois.readObject(); 

      log.info("Reading params from the inputstream"); 

      if (returnParams.getClass().isArray()) { 
       returnValues = (String[]) returnParams; 
      } 

     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      // e.printStackTrace(); 
      log.error("IOException in BatchJobWS.generateReportBatchJob(...)", 
        e); 
     } catch (ClassNotFoundException e) { 
      // TODO Auto-generated catch block 
      // e.printStackTrace(); 
      log.error(
        "ClassNotFoundException in BatchJobWS.generateReportBatchJob(...)", 
        e); 
     } 

     log.info(
       "Returning from BatchJobWS.generateReportBatchJob(...),returnValues = {}", 
       returnValues); 

     return returnValues; 
    } 

} 

最初,在網絡應用方面,我寫了一個普通老式的servlet,如下圖所示:

package lnt.remote; 

import java.io.IOException; 

import javax.servlet.ServletException; 
import javax.servlet.http.HttpServlet; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 

import lnt.service.ReportService; 
import lnt.utilities.BatchJobService; 

import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.beans.factory.annotation.Qualifier; 
import org.springframework.stereotype.Controller; 
import org.springframework.stereotype.Service; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 

/** 
* Servlet implementation class RemoteCallInterceptor 
*/ 
    public class RemoteCallInterceptor extends HttpServlet { 
    private static final long serialVersionUID = 1L; 

    private static Logger log = LoggerFactory 
      .getLogger(RemoteCallInterceptor.class); 


    /** 
    * @see HttpServlet#HttpServlet() 
    */ 
    public RemoteCallInterceptor() { 
     // super(); 
     // TODO Auto-generated constructor stub 
    } 

    /** 
    * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse 
    *  response) 
    */ 
    protected void doGet(HttpServletRequest request, 
      HttpServletResponse response) throws ServletException, IOException { 
     // TODO Auto-generated method stub 
     log.info("In Target Payroll. RemoteCallInterceptor.doGet()"); 
    } 

    /** 
    * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse 
    *  response) 
    */ 
    protected void doPost(HttpServletRequest request, 
      HttpServletResponse response) throws ServletException, IOException { 
     // TODO Auto-generated method stub 
     log.info(
       "In Target Payroll. RemoteCallInterceptor.doPost(),reportService = {}", 
       reportService); 

     BatchJobService BatchJobService = new BatchJobService(); 
     BatchJobService.runBatchJob(request, response); 

    } 
} 

我寫了一類新的BatchJobService它調用了一些現有的Spring bean,而這些Spring bean又使用@Autowire注入了多個Spring bean。因此,BatchJobService(它不是Spring管理的組件)中的代碼失敗,導致NullPointerException(因爲bean沒有被注入)。 因此,爲了 '注入' BatchJobService(由此,在注入所需BatchJobService豆)中RemoteCallInterceptor,我提出後者一個Spring控制器(使用@Controller)和改性如圖所示的doPost(...):

package lnt.remote; 

import java.io.IOException; 

import javax.servlet.ServletException; 
import javax.servlet.http.HttpServlet; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 

import lnt.service.ReportService; 
import lnt.utilities.BatchJobService; 

import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.beans.factory.annotation.Qualifier; 
import org.springframework.stereotype.Controller; 
import org.springframework.stereotype.Service; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 

/** 
* Servlet implementation class RemoteCallInterceptor 
*/ 
@Controller 
public class RemoteCallInterceptor extends HttpServlet { 
    private static final long serialVersionUID = 1L; 

    private static Logger log = LoggerFactory 
      .getLogger(RemoteCallInterceptor.class); 

    @Autowired 
    @Qualifier("ReportService") 
    ReportService reportService; 

    /** 
    * @see HttpServlet#HttpServlet() 
    */ 
    public RemoteCallInterceptor() { 
     // super(); 
     // TODO Auto-generated constructor stub 
    } 

    /** 
    * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse 
    *  response) 
    */ 
    protected void doGet(HttpServletRequest request, 
      HttpServletResponse response) throws ServletException, IOException { 
     // TODO Auto-generated method stub 
     log.info("In Target Payroll. RemoteCallInterceptor.doGet()"); 
    } 

    /** 
    * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse 
    *  response) 
    */ 
    @RequestMapping(value = "/RemoteCallInterceptor.do", method = RequestMethod.POST) 
    protected void doPost(HttpServletRequest request, 
      HttpServletResponse response) throws ServletException, IOException { 
     // TODO Auto-generated method stub 
     log.info(
       "In Target Payroll. RemoteCallInterceptor.doPost(),reportService = {}", 
       reportService); 

     BatchJobService BatchJobService = new BatchJobService(); 
     BatchJobService.runBatchJob(request, response); 

    } 
} 

但現在的問題是BatchJobService中的代碼從輸入流中讀取對象(由Web服務編寫的字符串數組)將得到EOFException。

我想@RequestMapping的事情導致輸入流被消耗 - 是我的假設正確?如果不是,我應該如何在Web應用程序中檢索String [] params - 既不是參數也不是屬性?如果是的話,可以採取什麼措施?

回答

1

我懷疑它是因爲Spring MVC應用程序中斷而發生故障,並且您的WS客戶端正在發送錯誤響應。您的BatchJobWS未檢查HTTP響應代碼,只是假設一切正常。它出現異常並不奇怪。

你需要做兩件事。首先,向BatchJobWS添加明確的響應狀態檢查,例如,

HttpURLConnection httpConn; 
... 
oos.writeObject(params); 
oos.flush(); 
oos.close(); 

if (httpConn.getResponseCode() != 200) { 
    // error - throw an exception, or whatever 
} 

其次,有一個在註釋的HttpServlet@Controller沒有點 - 使用一個或另一個,而不是兩個。刪除extends HttpServlet並使doPostpublicprotected可能是導致錯誤的原因。

+0

對不起,我不得不修改原來的職位 - 在EOFException類是在類BatchJobService而不是BatchJobWS拋出,前者是在下面的代碼片段拋出一個異常: 「公共無效runBatchJob(HttpServletRequest的請求,HttpServletResponse的響應)拋出IOException異常{ \t \t // TODO自動生成方法存根 \t \t ObjectInputStream的OIS =新的ObjectInputStream(request.getInputStream());」 我試着讓它成爲一個純粹的Spring控制器,但問題依然存在。 – 2012-03-07 15:30:24