package cn.dreampie.common.http; import cn.dreampie.common.Constant; import cn.dreampie.common.Response; import cn.dreampie.common.http.result.HttpStatus; import cn.dreampie.log.Logger; import javax.servlet.ServletException; import javax.servlet.ServletResponse; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.OutputStream; import java.lang.reflect.Field; /** * Date: 2/6/13 * Time: 9:40 PM */ public class HttpResponse extends AbstractResponse<HttpServletResponse> { public static final Logger logger = Logger.getLogger(HttpResponse.class); private final HttpServletResponse response; private final HttpServletRequest request; public HttpResponse(HttpServletResponse response, HttpServletRequest request) { super(HttpServletResponse.class, response); this.response = response; this.request = request; } protected void doSetStatus(HttpStatus httpStatus) { response.setStatus(httpStatus.getCode()); } protected OutputStream doGetOutputStream() throws IOException { return response.getOutputStream(); } public Response addCookie(Cookie cookie) { response.addCookie(cookie); return this; } public Response addCookie(String name, String value, int expiration) { return addCookie(name, value, expiration, true); } public Response addCookie(String name, String value, int expiration, boolean httpOnly) { Cookie existingCookie = HttpRequest.getCookie(request.getCookies(), name); if (existingCookie != null) { if (Constant.cookiePath.equals(existingCookie.getPath()) || existingCookie.getPath() == null // in some cases cookies set on path '/' are returned with a null path ) { // update existing cookie existingCookie.setPath(Constant.cookiePath); existingCookie.setValue(value); existingCookie.setMaxAge(expiration); if (Constant.cookieHttpOnly) { setHttpOnly(existingCookie); } existingCookie.setSecure(Constant.cookieSecure); if (Constant.cookieDomain != null) { existingCookie.setDomain(Constant.cookieDomain); } response.addCookie(existingCookie); } else { // we have an existing cookie on another path: clear it, and add a new cookie on root path existingCookie.setValue(""); existingCookie.setMaxAge(0); response.addCookie(existingCookie); Cookie c = new Cookie(name, value); c.setPath(Constant.cookiePath); c.setMaxAge(expiration); if (Constant.cookieHttpOnly) { setHttpOnly(existingCookie); } c.setSecure(Constant.cookieSecure); if (Constant.cookieDomain != null) { c.setDomain(Constant.cookieDomain); } response.addCookie(c); } } else { Cookie c = new Cookie(name, value); c.setPath(Constant.cookiePath); c.setMaxAge(expiration); if (Constant.cookieHttpOnly) { setHttpOnly(c); } c.setSecure(Constant.cookieSecure); if (Constant.cookieDomain != null) { c.setDomain(Constant.cookieDomain); } response.addCookie(c); } return this; } public Response clearCookie(String cookie) { Cookie existingCookie = HttpRequest.getCookie(request.getCookies(), cookie); if (existingCookie != null) { existingCookie.setPath(Constant.cookiePath); existingCookie.setValue(""); existingCookie.setMaxAge(0); response.addCookie(existingCookie); } return this; } public void doSetHeader(String headerName, String header) { response.setHeader(headerName, header); } public void doAddHeader(String headerName, String header) { response.addHeader(headerName, header); } public void forward(String url) throws ServletException, IOException { request.getRequestDispatcher(url).forward(request, response); } public void sendRedirect(String url) throws ServletException, IOException { response.sendRedirect(url); } @SuppressWarnings("unchecked") public <T> T unwrap(Class<T> clazz) { if (clazz == HttpServletResponse.class || clazz == ServletResponse.class) { return (T) response; } throw new IllegalArgumentException("Underlying implementation is HttpServletResponse, not " + clazz.getName()); } public void setHttpOnly(Cookie cookie) { try { Field field = Cookie.class.getDeclaredField("httpOnly"); field.setAccessible(true); field.set(cookie, true); } catch (NoSuchFieldException e) { logger.warn("Could not support 'httpOnly', upgrade servlet solve it."); } catch (IllegalAccessException e) { logger.error(e.getMessage(), e); } } public void reset() { response.reset(); } }