/211AuthcenterProject/authcenter-web/src/main/java/com/fdhay/authcenter/web/controller/base/BaseController.java
Java | 420 lines | 267 code | 46 blank | 107 comment | 18 complexity | 6ed9232d30cfcdfb5027b777c4c97a0e MD5 | raw file
Possible License(s): LGPL-2.1, MPL-2.0-no-copyleft-exception
- package com.fdhay.authcenter.web.controller.base;
-
- import java.io.File;
- import java.io.IOException;
- import java.io.StringWriter;
- import java.io.UnsupportedEncodingException;
- import java.net.URLEncoder;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.UUID;
-
- import javax.annotation.Resource;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
-
- import org.apache.commons.lang.StringUtils;
- import org.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
- import org.springframework.stereotype.Controller;
- import org.springframework.validation.ObjectError;
- import org.springframework.web.bind.annotation.ExceptionHandler;
- import org.springframework.web.servlet.ModelAndView;
- import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
- import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver;
-
- import com.alibaba.fastjson.JSON;
- import com.fdhay.authcenter.common.Constants;
- import com.fdhay.authcenter.common.util.FileUtils;
- import com.fdhay.authcenter.domain.User;
- import com.fdhay.authcenter.service.SessionService;
- import com.fdhay.authcenter.web.controller.base.helper.SessionHelper;
- import com.fdhay.authcenter.web.controller.base.interceptor.ControllerContext;
-
- import freemarker.template.Configuration;
- import freemarker.template.Template;
-
- @Controller
- public class BaseController {
-
- protected Log logger = LogFactory.getLog(getClass());
- //默认的freemarker配置器
- @Resource private FreeMarkerConfigurer freemarkerConfigurer;
- @Resource private FreeMarkerViewResolver viewResolver;
- @Resource private SessionService sessionService;
-
- protected String CONTEXT_PATH_KEY = "contextPath";
- protected String CONTEXT_FULL_PATH_KEY = "contextFullPath";
-
- protected int DEFAULT_HTTP_PORT = 80;
- private String VIEW_CONTENT_KEY = "viewContent";
-
- private String DEFAULT_LAYOUT_VIEW_NAME = "common/layout/default-layout";
- private String EXCEPTION_VIEW_NAME = "common/exception/exception-message";
-
- private String FREEMARKER_SUFFIX = ".ftl";
- private String CONTENT_TYPE_OF_JSON = "text/html; charset=utf-8";//fix IE ajax fileupload issue, so change type from application/json to text/html
- private String CONTENT_TYPE_OF_TEXT = "text/plain; charset=utf-8";
- private String CONTENT_TYPE_OF_HTML = "text/html; charset=utf-8";
-
- private Map<String, Object> defaultModelMap = new HashMap<String, Object>(1);
- private Map<String, Object> modelMap = null;
- private List<ObjectError> errorList = null;
-
- private static final String KEY_OF_MODEL_MAP = "modelMap";
- private static final String KEY_OF_ERROR_LIST = "errorList";
-
- //自定义的freemarker,用于加载自定义路径下的模板
- private Configuration customFreemarkerConfiguration = new Configuration();
-
- @SuppressWarnings("unchecked")
- public Map<String, Object> getModelMap() {
- modelMap = (Map<String, Object>) ControllerContext.getContext().get(KEY_OF_MODEL_MAP);
- if(modelMap == null){
- modelMap = new HashMap<String, Object>(1);
- ControllerContext.getContext().put(KEY_OF_MODEL_MAP, modelMap);
- }
- return modelMap;
- }
-
- public void setModelMap(Map<String, Object> modelMap) {
- this.modelMap = modelMap;
- }
-
- @SuppressWarnings("unchecked")
- public List<ObjectError> getErrorList() {
- errorList = (ArrayList<ObjectError>) ControllerContext.getContext().get(KEY_OF_ERROR_LIST);
- if(errorList == null){
- errorList = new ArrayList<ObjectError>(1);
- ControllerContext.getContext().put(KEY_OF_ERROR_LIST, errorList);
- }
- return errorList;
- }
-
- protected HttpServletRequest getRequest(){
- return ControllerContext.getContext().getRequest();
- }
-
- protected HttpServletResponse getResponse(){
- return ControllerContext.getContext().getResponse();
- }
-
- protected User getLoginUser(){
- return (User) ControllerContext.getContext().get(Constants.KEY_OF_LOGIN_USER);
- }
-
- protected String getLoginUserCookie(){
- return (String) ControllerContext.getContext().get(Constants.KEY_OF_LOGIN_USER_COOKIE);
- }
-
- /**
- * 使用默认layout布局页面展示viewName的内容
- * @param viewName - 视图页面的全路径名,不含后缀。
- * Eg: "message/message-info", 表示使用页面 /WEB-INF/view/message/message-info.ftl
- * @param modelMap - 视图页面需要的变量<key, value>键值对。页面使用Eg:${message!}
- * @return
- */
- public ModelAndView toView(String viewName, Map<String, Object> modelMap){
- return this.toViewWithLayout(viewName, getDefaultLayout(), modelMap);
- }
-
- /**
- * 使用默认layout布局页面展示content的内容
- * @param content
- * @param modelMap
- * @return
- */
- public ModelAndView toViewOfContent(String content, Map<String, Object> modelMap){
- return this.toViewOfContentWithLayout(content, getDefaultLayout(), modelMap);
- }
-
- /**
- * 获取默认布局页面
- * @return
- */
- protected String getDefaultLayout() {
- return DEFAULT_LAYOUT_VIEW_NAME;
- }
-
- /**
- * 使用layoutPageName布局页面作为布局模板,展示viewName页面生成的内容
- * @param viewName- 视图页面的全路径名,不含后缀。
- * Eg: "message/message-info", 表示使用页面 /WEB-INF/view/message/message-info.ftl
- * @param layoutPageName - 模板布局页面,Eg:"common/layout/myself-layout"
- * @param modelMap - 视图页面需要的变量<key, value>键值对。页面使用Eg:${message!}
- * @return
- */
- public ModelAndView toViewWithLayout(String viewName, String layoutPageName, Map<String, Object> modelMap){
- Map<String, Object> mergedMap = mergedModelMap(defaultModelMap, modelMap);
- //
- String resultContent = getContentFromTemplate(viewName, mergedMap);
- mergedMap.put(VIEW_CONTENT_KEY, resultContent);
- //
- ModelAndView mv = new ModelAndView();
- mv.setViewName(layoutPageName);
- mv.addAllObjects(mergedMap);
- logger.info("visit view page ===> " + viewName + FREEMARKER_SUFFIX);
- return mv;
- }
-
- /**
- * 使用layoutPageName布局页面作为布局模板,展示content的内容
- * @param content - 在模板中展示的内容
- * @param layoutPageName - 模板布局页面,Eg:"common/layout/myself-layout"
- * @param modelMap - 视图页面需要的变量<key, value>键值对。页面使用Eg:${message!}
- * @return
- */
- public ModelAndView toViewOfContentWithLayout(String content, String layoutPageName, Map<String, Object> modelMap){
- Map<String, Object> mergedMap = mergedModelMap(defaultModelMap, modelMap);
- mergedMap.put(VIEW_CONTENT_KEY, content);
- //
- ModelAndView mv = new ModelAndView();
- mv.setViewName(layoutPageName);
- mv.addAllObjects(mergedMap);
- logger.info("visit view content === ");
- return mv;
- }
-
- /**
- * 从freemarker模板中获得解析后的内容
- * @param viewName - 视图页面的全路径名,不含后缀,默认为 .ftl
- * <p>
- * Eg: "message/message-info", 表示使用页面 /WEB-INF/view/message/message-info.ftl
- * </p>
- * @param modelMap - 视图页面需要的变量<key, value>键值对。页面使用Eg:${message!}
- * @return - 解析后的内容
- */
- public String getContentFromTemplate(String viewName, Map<String, Object> modelMap) {
- return this.processTemplate(freemarkerConfigurer.getConfiguration(), viewName + FREEMARKER_SUFFIX, modelMap);
- }
-
- /**
- * 从freemarker模板中获得解析后的内容
- * @param viewName - 视图页面的全路径名,不含后缀。
- * @param viewSuffix - 视图页面的后缀,eg: .json/.ftl
- * <p>
- * Eg: "message/message-info", ".json" 表示使用页面 /WEB-INF/view/message/message-info.ftl
- * </p>
- * @param modelMap - 视图页面需要的变量<key, value>键值对。页面使用Eg:${message!}
- * @return 解析后的内容
- */
- public String getContentFromTemplate(String viewName, String viewSuffix, Map<String, Object> modelMap) {
- return this.processTemplate(freemarkerConfigurer.getConfiguration(), viewName + viewSuffix, modelMap);
- }
- /**
- * 从指定的目录加载模板,并解析模板返回解析后的内容
- * @param templateDir - 指定的目录加载模板
- * @param viewNameIncludeSuffix - 视图页面的全路径名,需含后缀,eg: myViewPage.html
- * @param modelMap - 视图页面需要的变量<key, value>键值对。页面使用Eg:${message!}
- * @return - 解析后的内容
- * @throws IOException
- */
- public String getContentFromTemplateDir(String templateDir, String viewNameIncludeSuffix, Map<String, Object> modelMap) throws IOException {
- //设置新的Template load目录
- try {
- customFreemarkerConfiguration.setDirectoryForTemplateLoading(new File(templateDir));
- customFreemarkerConfiguration.setDefaultEncoding(Constants.DEFAULT_CHARSET);
- } catch (IOException e1) {
- logger.error(e1);
- throw e1;
- }
- FileUtils.checkFileExist(templateDir + "/" + viewNameIncludeSuffix);
- String resultContent = processTemplate(customFreemarkerConfiguration, viewNameIncludeSuffix, modelMap);
- return resultContent;
- }
-
- private String processTemplate(Configuration freemarkerConfiguration, String viewNameIncludeSuffix, Map<String, Object> modelMap) {
- StringWriter resultWriter = new StringWriter();
- try {
- Template template = freemarkerConfiguration.getTemplate(viewNameIncludeSuffix);
- template.process(mergedModelMap(defaultModelMap, modelMap), resultWriter);
- } catch (Exception e) {
- logger.error(e);
- throw new RuntimeException(e);
- }
- return resultWriter.toString();
- }
-
- /**
- * 不使用layout布局页面,直接把viewName指向的页面内容输出。
- * @param viewName
- * @param modelMap
- * @return
- */
- public ModelAndView toViewWithoutLayout(String viewName, Map<String, Object> modelMap){
- ModelAndView mv = new ModelAndView();
- mv.setViewName(viewName);
- mv.addAllObjects(mergedModelMap(defaultModelMap, modelMap));
- logger.info("visit view page ===> " + viewName + FREEMARKER_SUFFIX);
- return mv;
- }
-
- /**
- * 把参数对象作为json串输出到客户端。
- * @param javaObject
- */
- public ModelAndView toJSON(Object javaObject){
- return sendToClient(CONTENT_TYPE_OF_JSON, JSON.toJSONString(javaObject));
- }
-
- public ModelAndView toText(String text){
- return sendToClient(CONTENT_TYPE_OF_TEXT, text);
- }
-
- public ModelAndView toHTML(String html){
- return sendToClient(CONTENT_TYPE_OF_HTML, html);
- }
-
- /**
- * 用于处理异常的
- * @return
- */
- @ExceptionHandler({Exception.class})
- public ModelAndView exception(Exception e) {
- String errorCode = getRequest().getParameter(Constants.KEY_OF_ERROR_CODE);
- String errorMsg = (String) getRequest().getAttribute(Constants.KEY_OF_ERROR_MSG);
-
- logger.error("do ExceptionHandler --> " +
- " [errorCode=" + errorCode + "]" +
- " [errorMsg=" + errorMsg + "]", e);
- //request的attribute中存在的属性底层会加入到model对象中。
- getModelMap().put(Constants.KEY_OF_ERROR_CODE, errorCode);
- //返回exception试图
- return toError(EXCEPTION_VIEW_NAME, getModelMap());
- }
-
- public ModelAndView toError(String viewName, Map<String, Object> modelMap){
- ModelAndView mv = new ModelAndView();
- mv.setViewName(viewName);
- mv.addAllObjects(modelMap);
- logger.info("visit error page ===> " + viewName + FREEMARKER_SUFFIX);
- return mv;
- }
-
- public ModelAndView toError(String errorMsg){
- return toError(404, errorMsg);
- }
-
- public ModelAndView toError(int errorCode, String errorMsg){
- try {
- getRequest().setAttribute(Constants.KEY_OF_ERROR_MSG, errorMsg);
- getResponse().sendError(errorCode, errorMsg);
- } catch (IOException e) {
- logger.error(e);
- }
- return null;
- }
-
- private ModelAndView sendToClient(String contentType, String content){
- logger.debug("send to client content type = " + contentType);
- //logger.debug("send to client content = " + content);
- HttpServletResponse response = getResponse();
- response.setContentType(contentType);
- try {
- response.getWriter().print(content);
- response.flushBuffer();
- } catch (IOException e) {
- logger.error(e);
- }
- return null;
- }
-
- private Map<String, Object> mergedModelMap(Map<String, Object> defaultModelMap, Map<String, Object> modelMap){
- Map<String, Object> mergedModelMap = new HashMap<String, Object>();
- //把参数传递过来的modelMap合并到mergedModelMap。
- if(defaultModelMap != null){
- mergedModelMap.putAll(defaultModelMap);
- }
- if(modelMap != null){
- mergedModelMap.putAll(modelMap);
- }
- if(!mergedModelMap.containsKey(CONTEXT_PATH_KEY)){
- mergedModelMap.put(CONTEXT_PATH_KEY, getContextPath());
- }
- if(!mergedModelMap.containsKey(CONTEXT_FULL_PATH_KEY)){
- mergedModelMap.put(CONTEXT_FULL_PATH_KEY, getContextFullPath());
- }
- if(!mergedModelMap.containsKey(KEY_OF_ERROR_LIST) && !getErrorList().isEmpty()){
- mergedModelMap.put(KEY_OF_ERROR_LIST, getErrorList());
- }
- //每次请求都生成OTRToken
- mergedModelMap.put(Constants.KEY_OF_OTRTOKEN, refreshOTRToken());
- //如果有登陆用户,把登陆用户设置到model中
- User loginUser = this.getLoginUser();
- if(loginUser != null){
- mergedModelMap.put(Constants.KEY_OF_LOGIN_USER, loginUser);
- }
- return mergedModelMap;
- }
-
- protected String refreshOTRToken() {
- String OTRToken = UUID.randomUUID().toString();
- logger.debug("---> generated new OTRToken=" + OTRToken);
- Map<String, Object> sessonContext = sessionService.getSessionContext(SessionHelper.getSessionCookieValue(getRequest(), getResponse()));
- sessonContext.put(Constants.KEY_OF_OTRTOKEN, OTRToken);
- return OTRToken;
- }
-
- /**
- *
- * @return - eg: /to211-web
- */
- protected String getContextPath() {
- return getRequest().getContextPath();
- }
-
- /**
- *
- * @return - eg: http://www.to211.com/to211-web
- */
- protected String getContextFullPath(){
- return getServerFullPath() + getContextPath();
- }
-
- /**
- *
- * @return eg: http://www.to211.com:80
- */
- private String getServerFullPath() {
- StringBuilder contextURL = new StringBuilder();
- contextURL.append(getRequest().getScheme())
- .append("://")
- .append(getRequest().getServerName());
- if(getRequest().getServerPort() != DEFAULT_HTTP_PORT){
- contextURL.append(":")
- .append(getRequest().getServerPort());
- }
- return contextURL.toString();
- }
-
- /**
- * 获取全路径http url,eg:http://www.to211.com/url
- * @param url - eg:/url
- * @return - eg: http://www.to211.com/url
- */
- protected String getContextFullPathURL(String url){
- if(StringUtils.isEmpty(url)){
- return url;
- }
- if(url.startsWith(getServerFullPath())){
- return url;
- }
- return getServerFullPath() + url;
- }
-
- /**
- * 获取内部转发地址
- * @param location - eg: xxx
- * @return /forwardInternal?location=xxx
- */
- protected String getForwardInternalPath(String location){
- try {
- return String.format("%s/forwardInternal?location=%s", getContextPath(), URLEncoder.encode(location, Constants.DEFAULT_CHARSET));
- } catch (UnsupportedEncodingException e) {
- logger.error(e);
- }
- return "";
- }
- }