前段时间开发了一个web小系统,主要是和.net客户端交互,由于不是很复杂,就没有采用webservice,而是使用了HttpCLient通过json方式交互,在交互的时候想在servlet中直接调用spring的bean,这样能节省不少时间。但是直接调用总是报错,网上查了一下才知道,servlet是无法直接调用spring中的bean的,如果直接调用,一般都会报空指针异常。
为什么会这样?其实我们使用spring的目的就是为了让spring为我们来提供一个已经被注入好的一个实例。而servlet是不同的,servlet是有生命周期的,而这个并不归属spring管理,而是由web容器管理的。那么当servlet刚刚创建的时候,spring可以为servlet注入,当你访问的时候,由于servlet是单实例多线程的,所以,servlet信息被重置,刚刚被注入的对象又为null了。
那么该怎么处理这个问题呢?其实只要我在获得servlet的时候,用从Spring获得,而不是由web容器获得就可以了。而解决这个方法的思路就是,我们使用一个代理的servlet,利用这个代理的servlet去调用我们的业务servlet(其中这个业务servlet是被配置为spring中的bean),这样就可以实现其他bean注入,然后使用代理servlet调用。
首先看代理Servlet代码
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
public class HttpServletProxy extends HttpServlet {
/**
* random serialVersionUID
*/
private static final long serialVersionUID = -7208519469035631940L;
private static Logger logger = LoggerFactory
.getLogger(HttpServletProxy.class);
private String targetServlet;
private HttpServlet proxy;
public void init() throws ServletException {
this.targetServlet = getInitParameter("targetServlet");
getServletBean();
proxy.init(getServletConfig());
System.out.println(targetServlet + " was inited by HttpServletProxy successfully......");
}
private void getServletBean() {
WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
this.proxy = (HttpServlet) wac.getBean(targetServlet);
}
@Override
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException, RuntimeException {
proxy.service(request, response);
}
}
接下来看我们使用的业务Servlet的代码:
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import com.qdhh.xfylxt.bean.Ygxxbean;
import com.qdhh.xfylxt.common.bean.Pager;
import com.qdhh.xfylxt.entity.XFTrainSetting;
import com.qdhh.xfylxt.entity.XFYgtrainScore;
import com.qdhh.xfylxt.entity.XFYgxx;
import com.qdhh.xfylxt.entity.XFZksxx;
import com.qdhh.xfylxt.service.XFTrainService;
import com.qdhh.xfylxt.service.XFYgxxService;
import com.qdhh.xfylxt.service.XFZksxxService;
@Component
public class RemoteServlet extends HttpServlet {
/**
* Constructor of the object.
*/
public RemoteServlet() {
super();
}
@Autowired
private XFTrainService xFTrainService;
@Autowired
private XFYgxxService xFYgxxService;
@Autowired
private XFZksxxService xFZksxxService;
/**
* Destruction of the servlet. <br>
*/
public void destroy() {
super.destroy(); // Just puts "destroy" string in log
}
/**
* The doGet method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to get.
*
* @param request
* the request send by the client to the server
* @param response
* the response send by the server to the client
* @throws ServletException
* if an error occurred
* @throws IOException
* if an error occurred
*/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String method = request.getParameter("method");
if(Utils.isEmpty(method)){
return;
}
System.out.println(request.getQueryString());
response.setContentType("text/html" + ";charset=UTF-8");
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
String zksbh = request.getParameter("zksbh");
XFZksxx zksxxSearch = new XFZksxx();
zksxxSearch.setZksbh(zksbh);
Pager page = xFZksxxService.queryPageByCxtj(zksxxSearch, 0, 20);
XFZksxx zksxx = (XFZksxx)page.getList().get(0);
PrintWriter out = response.getWriter();
String result = "";
if(zksxx == null) {
result = handlerSuccess("服务器端无此中控室,请检查后重新连接");
} else {
if("queryTrainSetting".equals(method)) { // 根据中控室下载考核内容设置
XFTrainSetting ts = xFTrainService.getTrainSetting(zksbh);
Map<String, Object> map = new HashMap<String, Object>();
if(ts != null) {
List zdylxt = ts.queryZdylxtList();
List zdyyss = ts.queryZdylssList();
String s1 = StringUtils.collectionToDelimitedString(zdylxt, "");
String s2 = StringUtils.collectionToDelimitedString(zdyyss, "");
System.out.println(s1);
System.out.println(s2);
map.put("zdylxt", s1);
map.put("zdyyss", s2);
} else {
map.put("zdylxt", "00000000");
map.put("zdyyss", "00000000000");
}
JSONObject jsonObject = JSONObject.fromObject(map);
result = jsonObject.toString();
} else if("downYgxx".equals(method)) { // 根据中控室下载员工信息
XFYgxx search = new XFYgxx();
search.setZksbh(zksbh);
List<XFYgxx> list = xFYgxxService.queryAll(search);
List<Ygxxbean> ygList = new ArrayList<Ygxxbean>();
if(!Utils.isEmpty(list)) {
for(XFYgxx yg: list) {
Ygxxbean bean = new Ygxxbean();
BeanUtils.copyProperties(yg, bean);
ygList.add(bean);
}
}
JSONArray json = JSONTools.toJSONArray(ygList);
result = json.toString();
} else if("downZksxx".equals(method)) { // 下载所有的中控室信息
List<XFZksxx> list = xFZksxxService.queryAll();
JSONArray json = JSONTools.toJSONArray(list);
result = json.toString();
} else if("downTrainxx".equals(method)) {
List<XFYgtrainScore> list = xFTrainService.queryAllTrainScore(null);
JSONArray json = JSONTools.toJSONArray(list);
result = json.toString();
} else if("uploadYgxx".equals(method)){ // 上传员工信息
String idcard = request.getParameter("idcard");
String name = request.getParameter("name");
String username = request.getParameter("username");
String password = request.getParameter("password");
String status = request.getParameter("status");
XFYgxx ygxx = new XFYgxx();
ygxx.setName(name);
ygxx.setPassword(password);
ygxx.setUsername(username);
ygxx.setIdcard(idcard);
ygxx.setStatus(status);
ygxx.setZksbh(zksbh);
ygxx.setRegtime(new Date());
ygxx.setZksid(zksxx.getTid());
ygxx.setZksname(zksxx.getName());
String msg = xFYgxxService.updateYgxxByClient(ygxx);
result = handlerSuccess(msg);
} else if("uploadTrain".equals(method)) { // 上传用户考核成绩
try {
String idcard = request.getParameter("idcard");
String name = request.getParameter("name");
String starttime = request.getParameter("starttime");
String duration = request.getParameter("duration");
String grades = request.getParameter("grade");
Double temp = Double.parseDouble(grades);
BigDecimal bg = new BigDecimal(temp);
double grade = bg.setScale(2, BigDecimal.ROUND_CEILING).doubleValue();
XFYgtrainScore trainScore= new XFYgtrainScore();
Date kssj = TimeUtil.toUtilDateFromStrDateByFormat(starttime,"yyyy-MM-dd hh:mm:ss");
trainScore.setIdcard(idcard);
trainScore.setStartTime(kssj);
trainScore.setName(name);
trainScore.setTimeSpan(duration);
trainScore.setGrade(grade);
trainScore.setZksid(zksxx.getTid());
trainScore.setZksbh(zksbh);
trainScore.setZksname(zksxx.getName());
xFTrainService.uploadTrainScore(trainScore);
result = handlerSuccess("操作成功");
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else if("downloadUserGrade".equals(method)) { // 下载指定用户成绩
String idcard = request.getParameter("idcard");
XFYgtrainScore scoreSearch = new XFYgtrainScore();
scoreSearch.setIdcard(idcard);
List<XFYgtrainScore> list = xFTrainService.queryAllTrainScore(scoreSearch);
JSONArray json = JSONTools.toJSONArray(list);
result = json.toString();
} else if("downloadAllGrade".equals(method)) { // 下载所有用户的成绩
XFYgtrainScore scoreSearch = new XFYgtrainScore();
scoreSearch.setZksbh(zksbh);
List<XFYgtrainScore> list = xFTrainService.queryAllTrainScore(scoreSearch);
JSONArray json = JSONTools.toJSONArray(list);
result = json.toString();
System.out.println(result);
} else if("uploadYgmm".equals(method)) { // 更改用户密码
String idcard = request.getParameter("idcard");
String password = request.getParameter("password");
String msg = xFYgxxService.changePassByClient(idcard, password);
result = handlerSuccess(msg);
} else if("uploadRysl".equals(method)) { //上传人员数量
String peracount = request.getParameter("peracount");
zksxx.setPeracount(Long.parseLong(peracount));
xFZksxxService.update(zksxx);
result = handlerSuccess("操作成功");
}
}
out.write(result);
out.flush();
}
public String handlerSuccess(String msg, Object result) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("success", true);
map.put("msg", msg);
map.put("result", result);
JSONObject jsonObject = JSONObject.fromObject(map);
return jsonObject.toString();
}
public String handlerSuccess(String msg) {
return handlerSuccess(msg,null);
}
public String handlerSuccess(Object result) {
return handlerSuccess(null,result);
}
/**
* The doPost method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to
* post.
*
*
* @param request
* the request send by the client to the server
* @param response
* the response send by the server to the client
* @throws ServletException
* if an error occurred
* @throws IOException
* if an error occurred
*/
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
/**
* Initialization of the servlet. <br>
*
* @throws ServletException
* if an error occurs
*/
public void init() throws ServletException {
// Put your code here
}
public XFTrainService getXFTrainService() {
return xFTrainService;
}
public void setXFTrainService(XFTrainService trainService) {
xFTrainService = trainService;
}
}
代码就到这了,接下来就需要配置了,
业务serlvet配置为spring的bean:
<bean id="remoteServlet" />
web.xml中业务servlet的配置如下:
<servlet> <description>This is the description of my J2EE component</description> <display-name>This is the display name of my J2EE component</display-name> <servlet-name>RemoteServlet</servlet-name> <servlet-class>com.qdhh.xfylxt.util.HttpServletProxy</servlet-class> <init-param> <param-name>targetServlet</param-name> <param-value>remoteServlet</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>RemoteServlet</servlet-name> <url-pattern>/remote</url-pattern> </servlet-mapping>