Пружинно-изнурительные входы потока заявки - PullRequest
1 голос
/ 07 марта 2012

Я пытаюсь передать массив String из веб-службы в веб-приложение 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, который вызывает несколько существующих bean-компонентов Spring, в которые, в свою очередь, вводится несколько bean-компонентов Spring с использованием @Autowire. Следовательно, код в BatchJobService (который не является компонентом, управляемым Spring) завершался с ошибкой NullPointerException (поскольку бины не вводились). Следовательно, чтобы «внедрить» BatchJobService (тем самым, внедрив бины, необходимые для BatchJobService) в RemoteCallInterceptor, я сделал последний Spring Controller (используя @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 Ответ

1 голос
/ 07 марта 2012

Я подозреваю, что это сломано, потому что сломано приложение 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 и сделайте doPost public.protected может быть причиной ошибки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...