package li.mvc; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Properties; import java.util.Set; import javax.servlet.ServletContext; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import li.dao.Page; import li.model.Action; import li.util.Convert; import li.util.Files; import li.util.Log; import li.util.Reflect; import li.util.Verify; import freemarker.template.Configuration; import freemarker.template.Template; /** * 访问HTTP请求上下文的工具类,使用ThreadLocal * * @author li (limingwei@mail.com) * @version 0.1.1 (2012-07-20) * @see li.mvc.AbstractAction */ public class Context { static final String VIEW_TYPE = Files.config().getProperty("view.type", "forward"); static final String VIEW_PREFIX = Files.config().getProperty("view.prefix", ""); static final String VIEW_SUFFIX = Files.config().getProperty("view.suffix", ""); private static final ThreadLocal<HttpServletRequest> REQUEST = new ThreadLocal<HttpServletRequest>(); private static final ThreadLocal<HttpServletResponse> RESPONSE = new ThreadLocal<HttpServletResponse>(); private static final ThreadLocal<Action> ACTION = new ThreadLocal<Action>(); private static final Log log = Log.init(); /** * 初始化方法,会将request,response,action分别存入ThreadLocal */ public static void init(ServletRequest request, ServletResponse response, Action action) { REQUEST.set((HttpServletRequest) request); RESPONSE.set((HttpServletResponse) response); ACTION.set(action); } /** * 从request,sesstion,servletContext中取出Attributes转为Map */ public static Map<String, Object> getAttributes() { Map<String, Object> map = new HashMap<String, Object>(); map.put("application", getServletContext()); map.put("servletContext", getServletContext()); map.put("request", getRequest()); map.put("response", getResponse()); map.put("session", getSession()); Enumeration<?> servletContextEnumeration = getServletContext().getAttributeNames(); while (servletContextEnumeration.hasMoreElements()) {// 1. 存入servletContext的值 String name = (String) servletContextEnumeration.nextElement(); map.put(name, getServletContext().getAttribute(name)); } Enumeration<?> sessionEnumeration = getSession().getAttributeNames(); while (sessionEnumeration.hasMoreElements()) {// 2. 存入session的值 String name = (String) sessionEnumeration.nextElement(); map.put(name, getSession().getAttribute(name)); } Enumeration<?> requestEnumeration = getRequest().getAttributeNames(); while (requestEnumeration.hasMoreElements()) {// 3. 存入request的值 String name = (String) requestEnumeration.nextElement(); map.put(name, getRequest().getAttribute(name)); } return map; } /** * 返回Action引用 */ public static Action getAction() { return ACTION.get(); } /** * 返回request引用 */ public static HttpServletRequest getRequest() { return REQUEST.get(); } /** * 返回response引用 */ public static HttpServletResponse getResponse() { return RESPONSE.get(); } /** * 返回ServletContext */ public static ServletContext getServletContext() { return getSession().getServletContext();// for servlet 2.5 - } /** * 返回Session引用 */ public static HttpSession getSession() { return getRequest().getSession(); } /** * 返回基本类型的数组参数 */ public static <T> T[] getArray(Class<T> type, String key) { return Convert.toType(type, (Object[]) getRequest().getParameterValues(key)); } /** * 根据QueryString中的页码参数构建一个Page,或者一个默认的Page */ public static Page getPage(String pageNumberKey) { Page page = (Page) getSession().getAttribute("page"); if (null == page) { page = new Page(); } String pnStr = getRequest().getParameter(pageNumberKey); page.setPageNumber(Verify.isEmpty(pnStr) ? 1 : Integer.valueOf(pnStr)); return page; } /** * 从 request 的 parameters中得到数据组装成一个type类型的对象 * * @param type 对象类型 * @param prefix 查询 Parameters 时候的 key 的前缀 */ public static <T> T get(Class<T> type, String prefix) { T t = Reflect.born(type); Set<Entry<String, String[]>> parameterSet = getRequest().getParameterMap().entrySet(); for (Entry<String, String[]> entry : parameterSet) {// 迭代ParameterMap if (Verify.isEmpty(prefix) || Verify.startWith(entry.getKey(), prefix)) {// 前缀为空或者参数Key以前缀开头 String fieldName = entry.getKey().substring(prefix.length());// 属性名 Reflect.set(t, fieldName, entry.getValue()[0]); } } return t; } /** * 将QueryString中对应key的参数设置到request里面 */ public static void keepParams(String... keys) { for (String key : keys) { getRequest().setAttribute(key, getRequest().getParameter(key)); } } /** * 返回项目文件系统跟路径 */ public static String getRootPath() { return getServletContext().getRealPath("/"); } /** * 返回项目HTTP根路径 */ public static String getRootUrl() { return getRequest().getScheme() + "://" + getRequest().getServerName() + ":" + getRequest().getServerPort() + getRequest().getContextPath() + "/"; } /** * 主视图方法,以冒号分割前缀表示视图类型 * * @see #forward(String) * @see #freemarker(String) * @see #redirect(String) * @see #write(Object) */ public static String view(String path) { String viewType = path.contains(":") ? path.split(":")[0] : VIEW_TYPE;// 视图类型 String viewPath = path.startsWith(viewType + ":") ? path.split(viewType + ":")[1] : path;// path冒号后的部分或者path if ("forward".equals(viewType) || "fw".equals(viewType)) {// forward视图 forward(VIEW_PREFIX + viewPath + VIEW_SUFFIX); } else if ("freemarker".equals(viewType) || "fm".equals(viewType)) {// freemarker视图 freemarker(VIEW_PREFIX + viewPath + VIEW_SUFFIX); } else if ("redirect".equals(viewType) || "rd".equals(viewType)) {// redirect跳转 redirect(viewPath); } else if ("write".equals(viewType) || "wt".equals(viewType)) {// 向页面write数据 write(viewPath); } else { throw new RuntimeException("view error, not supported viewtype: " + path); } return "~!@#DONE"; } /** * 执行客户端跳转 */ public static String redirect(String path) { log.debug("redirect to ?", path); try { getResponse().sendRedirect(path); } catch (Exception e) { throw new RuntimeException(e + " ", e); } return "~!@#DONE"; } /** * 返回forward视图 */ public static String forward(String path) { log.debug("forward to ?", path); try { getRequest().getRequestDispatcher(path).forward(getRequest(), getResponse()); } catch (Exception e) { throw new RuntimeException(e + " ", e); } return "~!@#DONE"; } /** * 返回freemarker视图 */ public static String freemarker(String path) { try { Configuration configuration = (Configuration) Log.get("~!@#FREEMARKER_CONFIGURATION"); // 从缓存中查找freemarkerConfiguration if (null == configuration) { // 缓存中没有 log.info("freemarker initializing .."); configuration = new Configuration();// 初始化freemarkerConfiguration configuration.setServletContextForTemplateLoading(getServletContext(), "/");// 设置模板加载跟路径 configuration.setSettings(new Properties() { private static final long serialVersionUID = 1L; { put("default_encoding", "UTF-8");// 默认参数 putAll(Files.load("freemarker.properties"));// freemarker.properties中的参数设置 } });// 加载自定义配置 Log.put("~!@#FREEMARKER_CONFIGURATION", configuration); // 缓存freemarkerConfiguration } Template template = configuration.getTemplate(path);// 加载模板 template.process(getAttributes(), getResponse().getWriter()); log.debug("freemarker to: ?", path); } catch (Throwable e) { throw new RuntimeException(e + " ", e); } return "~!@#DONE"; } /** * 把 content写到页面上 */ public static void write(Object content) { if (!Verify.isEmpty(content)) { String contentStr = content.toString(); final String JSON_REGEX = "^[\\[]*[{]+.*[}]+[]]*$", XML_REGEX = "^<.*>$"; if (Verify.regex(contentStr, XML_REGEX)) {// 如果内容是XML getResponse().setContentType("text/xml;charset=UTF-8"); } else if (Verify.regex(contentStr, JSON_REGEX)) {// 如果内容是JSON getResponse().setContentType("application/json;charset=UTF-8"); } else { getResponse().setContentType("text/plain;charset=UTF-8"); } try { getResponse().getWriter().write(contentStr); } catch (Exception e) { throw new RuntimeException(e + " ", e); } } } }