2012-11-28 32 views
6

Tôi cố gắng để thay đổi phản ứng http trong một bộ lọc và đang nhận được ngoại lệ sau đâyJetty Lọc để thay đổi phản hồi - java.lang.IllegalStateException: WRITER

java.lang.IllegalStateException: WRITER tại org .eclipse.jetty.server.Response.getOutputStream (Response.java:657) ở javax.servlet.ServletResponseWrapper.getOutputStream (ServletResponseWrapper.java:142) ở org.eclipse.jetty.servlets.ProxyServlet.service (ProxyServlet .java: 414) tại org.eclipse.jetty.servlet.ServletHolder.handle (ServletHolder.jav a: 643) tại org.eclipse.jetty.servlet.ServletHandler $ CachedChain.doFilter (ServletHandler.java:1331) tại com.cisco.vsx.node.proxy.http.RegexFilter.doFilter (RegexFilter.java: 36)

Tôi đang sử dụng proxy SelectChannelSelector và ProxyServlet.Transparent.

Dưới đây là đoạn mã từ lớp thử nghiệm

ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); 
context.setContextPath("/"); 

ProxyServlet.Transparent p1 = new ProxyServlet.Transparent("/proxy", 
    "www.cisco.com", 80); 
ServletHolder servletHolder = new ServletHolder(p1); 
context.addServlet(servletHolder, "/proxy/*"); 
context.addFilter(new FilterHolder(RegexFilter.class), "/*", null); 

server.setHandler(context); 

server.start(); 
server.join(); 

Đây là mã từ lớp lọc

PrintWriter out = response.getWriter(); 
CharResponseWrapper wrapper = new CharResponseWrapper((HttpServletResponse) response); 

chain.doFilter(request, wrapper); 

String html = wrapper.toString(); 
if (regex != null && response.getContentType() != null 
     && response.getContentType().startsWith("text/html")) { 
    Matcher matcher = regex.matcher(html); 
    Map<Integer, Integer> matches = new LinkedHashMap<Integer, Integer>(); 
    while (matcher.find()) { 
     int start = matcher.start(1); 
     System.out.println("START" + start); 
     int end = matcher.end(1); 
     System.out.println("END" + end); 
     matches.put(start, end - start); 
    } 
    StringBuffer sb = new StringBuffer(); 
    int start = 0; 
    for (int startIndex : matches.keySet()) { 
     String str = html.substring(start, startIndex) + "/proxy/"; 
     sb.append(str); 
     start = startIndex + matches.get(startIndex); 
    } 
    html = sb.toString(); 
} 

response.setContentLength(html.getBytes().length); 
out.write(html); 

Không chắc chắn nơi thứ đang xảy ra sai.

Trả lời

11

Phản hồi Jetty của bạn có thể là hai (kỹ thuật ba) chế độ riêng biệt. Một là chế độ ghi, chế độ khác là chế độ phát trực tiếp (và chế độ thứ ba về cơ bản là chế độ chưa quyết định).

Nếu bạn gọi getWriter() khi trả lời 'chưa quyết định', bạn sẽ đặt nó ở chế độ ghi, không thể đảo ngược. Nếu điều gì đó sau này cố gắng sử dụng phản hồi này trong chế độ phát trực tuyến (bằng cách gọi getOutputStream()) Ngoại lệ bạn thấy sẽ bị ném.

Để khắc phục điều này, không sử dụng phản hồi này ở chế độ ghi và 'thực hiện điều' của bạn trên OutputStream thay thế. Nếu bạn đã truy cập vào văn tại một điểm sau đó (sau khi doChain), bạn sẽ có được ngoại lệ nghịch đảo

java.lang.IllegalStateException: STREAM

để thay thế.

Các vấn đề liên quan