OSGi框架嵌入servlet开发Web应用问题(1)——servlet实例惟一

1、环境简介前端

  项目之前使用的是RCP框架,现想支持web请求,为了减小后台逻辑处理工做量,重用以前的RCP程序代码,经过添加一个新的插件用于处理web请求。具体实现可见http://blog.csdn.net/rongyongfeikai2/article/details/39577237。java

2、问题现象web

  在前台的一个页面中有两种ajax请求device和plan。页面显示的表格内容是经过plan请求填充,操做须要用到的数据经过定时的device请求来获取。这两个请求的后台处理类为同一个HttpServlet类。在重复刷新的过程当中,出现plan请求失败的现象,出现请求失败时device请求也会出现异常,但成功返回。ajax

  关键代码以下:json

AbstractServlet类跨域

 1 import javax.servlet.http.HttpServlet;
 2 import javax.servlet.http.HttpServletRequest;
 3 import javax.servlet.http.HttpServletResponse;
 4 
 5 public abstract class AbstractServlet extends HttpServlet {
 6     
 7     /** 请求*/
 8     protected HttpServletRequest request;
 9     
10     /** 响应*/
11     protected HttpServletResponse response;
12     
13     /** 操做名称*/
14     protected String action;
15     
16     /** 请求结果*/
17     protected boolean result;
18     
19     @Override
20     protected void doGet(HttpServletRequest request, HttpServletResponse response){
21         this.request = request;
22         this.response = response;
23         
24         getActionParam();
25         
26         excetue();
27         
28         returnResult();
29         
30     }
31     
32     /**
33      * 获取前端的action字段
34      */
35     protected void getActionParam() {
36         action = request.getParameter("action");    
37     }
38     
39     
40     abstract  public void excetue();
41     
42     abstract protected void returnResult();
43 }
View Code

TestServlet类浏览器

 1 import java.io.IOException;
 2 
 3 import org.codehaus.jackson.JsonNode;
 4 
 5 import com.macrosan.core.nonui.util.JsonMapper;
 6 
 7 public class TestServlet extends AbstractServlet {
 8     
 9     private JsonNode resultNode;
10     
11     @Override
12     public void excetue() {
13         if ("plan".equals(action)) {
14             queryAllPlans();
15         } else if ("device".equals(action)) {
16             queryAllDevices();
17         }     
18     }
19 
20     private void queryAllDevices() {
21         /// .......
22         resultNode = JsonMapper.toNormalTree("device response json string");
23 
24     }
25 
26     private void queryAllPlans() {
27         /// .......
28         resultNode = JsonMapper.toNormalTree("plan response json string");
29     }
30     
31     /**
32      * 
33      */
34     protected void returnResult() {
35         
36         try {
37             String resultStr = resultNode.toString();
38             
39             String callBack = request.getParameter("callback");
40             
41             // 普通访问
42             String responseStr = "";
43             if (callBack == null) {
44                 responseStr = resultStr;                
45             } else {
46                 responseStr = callBack + "(" + resultStr + ")";                
47             }
48             
49             response.getWriter().print(responseStr);
50         } catch (IOException e) {
51             e.printStackTrace();
52         }
53     }
54 }
View Code

3、问题定位多线程

  复现问题后,经过浏览器调试工具,找出后台返回的结果,以下:app

  jQuery110102986526135296296_1444812367854([{plan}])jQuery110102986526135296296_1444812367854([{device1},{device2}])框架

  正常状况下应该只返回一个jQuery110102986526135296296_1444812367854字符串,很显然是一个请求结果中包含了两个请求的结果,因为是jsonp跨域请求,因此第二个ajax请求失败。那第一个请求出现error的缘由是什么呢?

  从结果上看,应该是plan请求先来处理完成后在returnResult方法中将结果先写入,且device请求也来了,接着讲device的结果也写入致使的该字符串。

  习惯了使用Struts2等框架,每次action请求都是一个单独的实例来处理请求,跟上一次请求无关。但servlet插件则不一样,每次处理请求的实例是同一个对象,因此上一次请求将该实例中的属性修改了会影响到下一次请求。该问题的出现缘由是plan请求先来,request和response都是plan请求的,当完成数据收集后,device请求来了,将request和response修改成device的信息,致使plan请求流程中的returnResult方法中的response是device请求的,故致使device请求的结果有两个字符串,而plan请求因为没有返回数据致使请求失败。

4、问题解决

  解决方法很是简单,在doGet方法前添加同步关键字,以下:

 1     @Override
 2     synchronized protected void doGet(HttpServletRequest request, HttpServletResponse response){
 3         this.request = request;
 4         this.response = response;
 5         
 6         getActionParam();
 7         
 8         excetue();
 9         
10         returnResult();
11         
12     }
View Code

5、问题总结  该问题包含多线程处理同一对象,致使信息达不到预期的效果;请求没有任何返回会做为error处理;jsonp结果字符串必需要严格的格式等知识点。

相关文章
相关标签/搜索