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結果字符串必需要嚴格的格式等知識點。

相關文章
相關標籤/搜索