http 프로토콜 - 캐시 제어: etag If-None-Match/Last-Modified If-Modified-Since

2881 단어 http 프로토콜
ETag와 Last-Modified의 사용법의 차이점은 ETag는 반드시 개발자가 사용해야 하고 Last-Modified 서버는 자동으로 판단해야 한다는 것이다.즉, 서버 자체가 파일의'Last-Modified'를 얻을 수 있고'If-Modify-Since'와 비교하여 어떤 응답을 보낼지 결정한다.ETag는 개발자 스스로'If-None-Match'와 비교 판단해야 한다.
게다가 ETag의 한 가지 용도는 파일이 편집되었지만 실제 내용이 변하지 않는다면 이 때 ETag의 값이 변하지 않도록 지정할 수 있다. 그러면 브라우저에서 보내온 "If-None-Match"값과 같고 응답이 304, 즉 변하지 않는 것을 지정할 수 있다.ETag 기능을 추가하지 않으면 브라우저에서 200 응답을 보냅니다.
구체적인 프레젠테이션 코드는 저녁에 다시 쓰고, 처음으로 기술을 이렇게 늦게까지 연구해서 졸렸다.

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException,
	 ServletException {
	 	HttpServletRequest servletRequest = (HttpServletRequest) req;
	 	HttpServletResponse servletResponse = (HttpServletResponse) res;

	  	ByteArrayOutputStream baos = new ByteArrayOutputStream();
	 	ETagResponseWrapper wrappedResponse = new ETagResponseWrapper(servletResponse, baos);
	 	chain.doFilter(servletRequest, wrappedResponse);

	  	byte[] bytes = baos.toByteArray();

	  	String token = '"' + EtagComputeUtils.getMd5Digest(bytes) + '"';
	 	servletResponse.setHeader("ETag", token); 
//	 	servletResponse.setHeader("Cache-Control", "max-age=5"); // 
	 	servletResponse.setHeader("Cache-Control", "no-cache"); // 

	  	String previousToken = servletRequest.getHeader("If-None-Match");
	 	if (previousToken != null && previousToken.equals(token)) { 
	 		logger.debug("ETag match: returning 304 Not Modified");
	 		servletResponse.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
	 		
	 	} else  { 		
	 		Calendar cal = Calendar.getInstance();
	 		cal.set(Calendar.MILLISECOND, 0);
	 		Date lastModified = cal.getTime();
	 		servletResponse.setDateHeader("Last-Modified", lastModified.getTime());

	  		logger.debug("Writing body content");
	 		servletResponse.setContentLength(bytes.length);
	 		ServletOutputStream sos = servletResponse.getOutputStream();
	 		sos.write(bytes);
	 		sos.flush();
	 		sos.close();
	 	}
	 } 

이것을 주의하십시오. 이것도 있고 없고의 차이는 매우 큽니다.

ByteArrayOutputStream baos = new ByteArrayOutputStream();
ETagResponseWrapper wrappedResponse = new ETagResponseWrapper(servletResponse, baos);
chain.doFilter(servletRequest, wrappedResponse);

wrappedResponse가 아닌 원시적인 servletResponse를 사용하지 않으면 Ctrl+f5의 경우 ETag이든 response 설정이든 모두 사라집니다. 즉, 응답 정보는 본 프로그램에서 제어하지 않고 상기 코드로 이 문제를 해결할 수 있습니다.
ETagResponseWrapper, ETagResponseStream 클래스 코드는 첨부 파일을 참조하십시오.
참고 자료:
infoq,etag

좋은 웹페이지 즐겨찾기