2012-03-07 4 views
1

웹 서비스의 문자열 배열을 Spring 웹 응용 프로그램에 전달하려고합니다.요청의 입력 스트림이 소모 됨

웹 서비스 코드는 다음과 같습니다 처음

/** 
* 
*/ 
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; 
    } 

} 

, 웹 애플리케이션 측면에서, 나는 평범한 된 서블릿을 작성했다 아래와 같이

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 빈을 호출하고, 차례대로 @Autowire를 사용하여 여러 개의 Spring 빈을 삽입한다. 따라서 Spring 관리 컴포넌트가 아닌 BatchJobService의 코드는 NullPointerException (빈이 삽입되지 않음)로 실패했다. 그러므로, '분사'BatchJobService으로 (이에 BatchJobService에 필요한 빈을 주입) RemoteCallInterceptor에서 I 후자 스프링 컨트롤러 (@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의 코드는 EOFException을 가져옵니다.

@RequestMapping으로 인해 입력 스트림이 소비되었다고 가정합니다. 이 내 가정이 맞습니다.? 그렇지 않다면, 웹 애플리케이션에서 String [] 매개 변수 (매개 변수 또는 속성이 아닌)를 어떻게 검색해야합니까? 그렇다면 해결 방법은 무엇입니까?

답변

1

스프링 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을 제거하고 doPostpublic으로 설정하십시오. protected이 오류의 원인 일 수 있습니다.

+0

죄송합니다 내 원래의 게시물을 편집했다 - EOFException는이 클래스 BatchJobService하지 BatchJobWS에 슬로우되는, 전자는 다음 코드에서 예외를 던지고있다 : '공공 무효 runBatchJob (HttpServletRequest의 요청, HttpServletResponse를 응답) IOException가 {던졌습니다 \t \t // TODO 방법 \t \t 스터브 자동 생성하는 ObjectInputStream OIS = 새의 ObjectInputStream (request.getInputStream()); ' 순수 스프링 컨트롤러로 만들려고했지만 문제가 지속됩니다. –

관련 문제