春季用尽请求的输入流
我想将一个字符串数组从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 - 既不是参数也不是属性?如果是的话,可以采取什么措施?
我怀疑它是因为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
可能是导致错误的原因。
对不起,我不得不修改原来的职位 - 在EOFException类是在类BatchJobService而不是BatchJobWS抛出,前者是在下面的代码片段抛出一个异常: “公共无效runBatchJob(HttpServletRequest的请求,HttpServletResponse的响应)抛出IOException异常{ \t \t // TODO自动生成方法存根 \t \t ObjectInputStream的OIS =新的ObjectInputStream(request.getInputStream());” 我试着让它成为一个纯粹的Spring控制器,但问题依然存在。 – 2012-03-07 15:30:24