前段时间开发了一个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>