2009-06-25 30 views
25

Tôi có một số lỗi lạ: khi tôi mở trang lần đầu tiên trong một số trình duyệt, tất cả tham chiếu có tham số jsessionid (như <a href="/articles?name=art&jsessionid=5as45df4as5df"..>).jsessionid xảy ra trong tất cả các url được tạo bởi jstl <c:url..> tag

Khi tôi nhấn F5 hoặc làm mới trang bằng mọi cách khác, mọi thứ đều biến mất và mọi thứ hoạt động tốt cho đến khi tôi đóng trình duyệt (và tất cả các tab cũng sẽ bị đóng). Khi tôi mở nó một lần nữa, tôi thấy tham số jsessionid lạ này.

Tôi sử dụng thẻ jstl <c:url..> để tạo tất cả URL.

Tôi đã đọc một số thời gian trước đây rằng jsessionid là một thay thế cho cookie nếu cookie bị tắt, nhưng cookie được bật và tôi thực sự không sử dụng cookie.

Trả lời

34

Đây không phải là lỗi, theo thiết kế. Khi một phiên mới được tạo, máy chủ không chắc chắn liệu máy khách có hỗ trợ cookie hay không, và vì vậy nó tạo ra một cookie cũng như jsessionid trên URL. Khi khách hàng quay trở lại lần thứ hai, và trình bày cookie, máy chủ biết jsessionid là không cần thiết và giảm nó cho phần còn lại của phiên. Nếu khách hàng quay lại không có cookie, thì máy chủ cần tiếp tục sử dụng viết lại jsessionid.

Bạn không thể sử dụng cookie một cách rõ ràng, nhưng bạn hoàn toàn có phiên và vùng chứa cần theo dõi phiên đó.

+0

đẹp, nhưng tất cả css của tôi trông giống như "liên kết rel =" .. "href ="/mysite/css/styles.css? Jsessionid = as2dfs4df ". Tôi có thể tắt hành vi mặc định này hoặc nó sẽ là một thực hành xấu và Tôi nên sửa chữa css của tôi tải? – Roman

+2

Điều đó sẽ phụ thuộc vào container bạn đang chạy trong – skaffman

0

Thật không may là cách duy nhất tôi tìm thấy xung quanh việc này là thêm bộ lọc vào ứng dụng của bạn sẽ loại bỏ tham số jsessionid. Nó đặc biệt khó chịu nếu bạn đang tạo ra một trang web công cộng và muốn các công cụ tìm kiếm thứ để lập chỉ mục các trang của bạn.

Tôi không tin rằng tomcat (nếu đó là những gì bạn đang sử dụng) có thể được cấu hình để không thêm địa chỉ này vào url của bạn. Tôi không thể nói cho các máy chủ khác mặc dù.

Tuy nhiên, lưu ý rằng nếu bạn tạo bộ lọc và sau đó bạn yêu cầu quản lý phiên và người dùng đã tắt cookie, bạn sẽ gặp sự cố.

+0

Thật thú vị là ví dụ của ông có jsessionid như một tham số trong URL.Tôi chưa từng thấy trước đây. một postfix đến URL (ví dụ: my/path; jsessionid = ... & x = y), mà tôi nghĩ là những gì speclet spec yêu cầu – skaffman

+0

Thực ra tôi đã mắc lỗi, nó không phải là một tham số nhưng tôi quên định dạng chính xác tại thời điểm đó – Roman

+0

Tomcat 7 có thể được sử dụng cho điều này Tomcat 6.0.30 sẽ có tính năng này – Wes

0

Một workaround là không sử dụng <c:url>, nhưng để sử dụng ${request.contextPath}/path

+1

Chỉ cần làm rõ điều này - nó phải là '$ {pageContext.request.contextPath}' – delfuego

4

Dưới đây là một cách giải quyết khó chịu trong hương vị của một Filter để bạn sẽ không bao giờ thấy jsessionid trong URL bất cứ khi nào khách hàng hỗ trợ cookie.

@Override 
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 
    HttpServletRequest req = (HttpServletRequest) request; 
    HttpServletResponse res = (HttpServletResponse) response; 
    HttpSession session = req.getSession(); 

    if (session.isNew()) { 
     // New session? OK, redirect to encoded URL with jsessionid in it (and implicitly also set cookie). 
     res.sendRedirect(res.encodeRedirectURL(req.getRequestURI())); 
     return; 
    } else if (session.getAttribute("verified") == null) { 
     // Session has not been verified yet? OK, mark it verified so that we don't need to repeat this. 
     session.setAttribute("verified", true); 
     if (req.isRequestedSessionIdFromCookie()) { 
      // Supports cookies? OK, redirect to unencoded URL to get rid of jsessionid in URL. 
      res.sendRedirect(req.getRequestURI().split(";")[0]); 
      return; 
     } 
    } 

    chain.doFilter(request, response); 
} 

Lập bản đồ trên /* hoặc bất kỳ mẫu URL nào yêu cầu quản lý phiên.

+0

hi BalusC, cảm ơn vì Tôi không d o phát triển web hiện tại, nhưng tôi sẽ thử giải pháp của bạn trên một trong những dự án cũ của tôi có vấn đề này. Bạn có thể giải thích một chút (hoặc cho một liên kết phóng viên) khái niệm về URL được mã hóa/không được mã hóa không? Tại sao nó lại quan trọng? Điều khác ở đây mà tôi thiếu kiến ​​thức để hiểu nó là thuộc tính "đã được xác minh" cho phiên. Ai và khi nào thường đặt? – Roman

+0

Skaffman đã trả lời nhu cầu về jsessionid trong URL. Sự xác thực 'đã xác minh' chỉ ở đó để ngăn bộ lọc chạy trong vòng lặp vô hạn khi hỗ trợ cookie đã được xác minh. Bạn được tự do đổi tên nó thành một thứ khác. – BalusC

13

On Tomcat 7 hoặc bất kỳ đặc điểm kỹ thuật servlet v3 máy chủ phù hợp, bạn có thể vô hiệu hóa jsessionid trong URL bằng cách thêm sau vào web.xml của ứng dụng của bạn

<session-config> 
    <tracking-mode>COOKIE</tracking-mode> 
</session-config> 
+0

Điều này làm việc cho tôi trong tomcat 7. – Mukus

+5

'c: url' vẫn có thể khiến' jsessionid' được nối, ngay cả với cài đặt này. tomcat7/servlet3 – beerbajay

+0

Làm việc cho tôi, tôi đang sử dụng cầu nối nhúng. – Junjie

23

Như đã giải thích trong skaffman's answer, của nó không phải là một lỗi. Hành vi mong đợi của nó.

Trong câu hỏi của bạn, jsessionid được nối thêm dưới dạng tham số, không phải như vậy.
Sử dụng
<c:url value="/"/>
sẽ tạo ra nội dung như sau: /some/;jsessionid=E85FAC04E331FFCA55549B10B7C7A4FA.
Vì vậy, sử dụng
<link href="<c:url value="/"/>stylesheets/style.css" rel="stylesheet" type="text/css"/>
sẽ tạo
/some/;jsessionid=E85FAC04E331FFCA55549B10B7C7A4FAstylesheets/style.css
, vì vậy máy chủ của bạn không thể tìm thấy tài nguyên có sẵn.

Cách giải quyết tốt nhất mà tôi tìm thấy là sử dụng ${pageContext.request.contextPath} thay vì <c:url value="/"/>. Vì vậy, trong ví dụ trước, bạn sẽ có
<link href="${pageContext.request.contextPath}/stylesheets/style.css" rel="stylesheet" type="text/css"/>
sẽ tạo ra
/some/stylesheets/style.css.

Giải pháp này là vùng chứa độc lập (trong khi thùng chứa tuân thủ đặc tả servlet v3 - như Tomcat - giải pháp không). Lọc url phản hồi có cảm giác giống như hack, khiến bạn cần thay đổi hành vi mặc định. Nhưng tất cả phụ thuộc vào những gì bạn cần và muốn đạt được.

2

Nếu bạn có trang trình bao bọc chung mà tất cả các trang sử dụng (đối với tôi nó là common.inc) bạn có thể thêm session="false" vào <%@ page để xóa sessionid.

Ví dụ common.inc

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" session="false" trimDirectiveWhitespaces="true" %> 
<%@ taglib prefix="ab" tagdir="/WEB-INF/tags" %> 

<c:set var="contextPath" scope="request" value="${ pageContext.request.contextPath }" /> 
<c:set var="assetPath" scope="request" value="/assets" /> 
<c:set var="debugEnabled" scope="request" value="${ applicationDebugProperties.debugEnabled }" /> 

Ngoài ra .. thiết lập giá trị của c:url cho một biến và sử dụng c:out escapeXml="false" để sản xuất các biến và điều này sẽ loại bỏ các sessionid.

Ví dụ:

<c:url value=${url} var="image"/> 
<c:out var=${image} escapeXml="false"/> 

Ngoài ra, bạn có thể thêm video này vào cấu hình Apache để cắt ngắn sessionid.

ReWriteRule ^/(\w+);jsessionid=\w+$ /$1 [L,R=301] 
ReWriteRule ^/(\w+\.go);jsessionid=\w+$ /$1 [L,R=301] 
Các vấn đề liên quan