2017-05-16 15 views
-3

問題:我有一個HttpServlet的(從本地主機提供服務:8080),看起來像這樣:的Java HttpServlet的頭沒有得到正確設置時的servlet調用快速連續(兼)多次

@WebServlet(name = "ConcurrencyServlet", urlPatterns = { "/concurrency" }) 
    public class ConcurrencyServlet extends HttpServlet { 
    @Override 
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
    resp.setHeader("Access-Control-Allow-Origin", "*"); 
    resp.setHeader("Content-Type", "application/json"); 
    PrintWriter writer = resp.getWriter(); 

    String x = req.getParameter("x"); 
    writer.println("{\"module\":\"" + this.toString() + "\",\"value\":\"" + x + "\"}"); 
    writer.flush(); // This makes no difference, though 
    } 
} 

和一個javascript(從本地主機提供服務:9000)調用它在快速連續10次,創造併發:

(function() { 
    for (var i = 0; i < 10; i++) { 
    $.getJSON('//localhost:8080/concurrency', { x: i }, function (data) { 
     $('#out').append(data.module + ' : ' + data.value + '<br>'); 
    }); 
    } 
})(); 

的問題是,我需要一個Content-Type=application/json - 和Access-Control-Allow-Origin=* -Header設置nd呼叫的內容不會混淆至關重要。儘管如此,servlet似乎並沒有很好地處理頭文件的設置和對PrintWriter(response.getWriter())的訪問。

問題:有沒有辦法配置HttpServlets來正確處理這些同時調用?

此致曼努埃爾


解決方案:錯誤爲在所述過濾器中的一個。它將響應存儲在一個實例變量中(這不是線程安全的)。將變量移動到doFilter方法後,錯誤消失了。

+3

*該servlet似乎無法處理...很好* - 您觀察到了什麼? – wero

+2

您在'ConcurrencyServlet'中沒有使用任何可變狀態,因此沒有辦法可能發生任何併發問題。試試最後做一個'writer.flush();'。 – shazin

+0

@wero我在客戶端得到X-Origin-Errors,並且調用的響應是混合的(有些是空的,它們的內容被轉移到另一個響應內容中。) – zoku

回答

0

我發現這個錯誤要感謝wero的提示,看看過濾器。

有一個過濾器:

@WebFilter(
       filterName = "AccessControlFilter", 
       description = "Change access mathods, add headers to requests.", 
       urlPatterns = { "/*" }, 
       servletNames = "*" 
       ) 
public class AccessControlFilter implements Filter { 
    private HttpServletResponse response; 

    @Override 
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { 
     response = (HttpServletResponse) servletResponse; 

     MyResponseWrapper wrapper = new MyResponseWrapper(response); 

     wrapper.setHeader("Access-Control-Allow-Origin", "*"); 
     wrapper.setHeader("Access-Control-Allow-Methods", "*"); 

     filterChain.doFilter(servletRequest, response); 
    } 

    @Override 
    public void init(FilterConfig filterConfig) throws ServletException {} 

    @Override 
    public void destroy() {} 
} 

將其改爲:

@WebFilter(
       filterName = "AccessControlFilter", 
       description = "Change access mathods, add headers to requests.", 
       urlPatterns = { "/*" }, 
       servletNames = "*" 
       ) 
public class AccessControlFilter implements Filter { 

    @Override 
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { 
     HttpServletResponse response = (HttpServletResponse) servletResponse; 

     MyResponseWrapper wrapper = new MyResponseWrapper(response); 

     wrapper.setHeader("Access-Control-Allow-Origin", "*"); 
     wrapper.setHeader("Access-Control-Allow-Methods", "*"); 

     filterChain.doFilter(servletRequest, response); 
    } 

    @Override 
    public void init(FilterConfig filterConfig) throws ServletException {} 

    @Override 
    public void destroy() {} 
} 

現在,它的工作原理。

相關問題