• BaseController 的使用


    为了提现代码的高可用性,我们可以常见的把dao层进行抽取,service ,但是很少看见有controller的抽取,其实dao层也是可以被抽取的。

    首先我们定义一个BaseController接口

    package com.zhan.common.controller.base;
    
    import com.zhan.common.domain.base.Identifiable;
    import com.zhan.common.domain.base.Result;
    import org.springframework.data.domain.Pageable;
    import org.springframework.web.servlet.ModelAndView;
    
    
    /**
     * 基础控制器接口
     * @author LiuJunGuang
     * @date 2014年3月5日下午12:01:23
     */
    public interface BaseController<T extends Identifiable, Q extends T> {
       /**
        * 根据ID列表删除对象,如果idList 为空或者空列表则直接返回{@link Result},状态为OK
        * <blockquote>
        *     <table cellpadding=1 border=1  cellspacing=0 summary="Capturing group numberings">
        *        <tr>
        *            <th><tt>路径&nbsp;&nbsp;&nbsp;&nbsp;</tt></th>
        *           <th>访问方式&nbsp;&nbsp;&nbsp;&nbsp;</th>
        *            <th><tt>返回路径&nbsp;&nbsp;&nbsp;&nbsp;</tt></th>
        *      </tr>
        *      <tr>
        *            <th><tt>/sys/dictionary/delete</tt></th>
        *           <th>post</th>
        *            <th><tt>{@link Result}的json对象</tt></th>
        *      </tr>
        * </table>
        * </blockquote>
        * @param idList 要删除对象的ID列表
        * @return ModelAndView
        */
       public Result deleteList(String[] ids);
    
       /**
        * 删除一条记录
        * <blockquote>
        *     <table cellpadding=1 border=1  cellspacing=0 summary="Capturing group numberings">
        *        <tr>
        *            <th><tt>路径&nbsp;&nbsp;&nbsp;&nbsp;</tt></th>
        *           <th>访问方式&nbsp;&nbsp;&nbsp;&nbsp;</th>
        *            <th><tt>返回路径&nbsp;&nbsp;&nbsp;&nbsp;</tt></th>
        *      </tr>
        *      <tr>
        *            <th><tt>/sys/dictionary/${id}</tt></th>
        *           <th>delete</th>
        *            <th><tt>{@link Result}的json对象</tt></th>
        *      </tr>
        * </table>
        * </blockquote>
        * @param id 不能为null,则跳转到错误页面
        * @return ModelAndView
        */
       public Result deleteOne(String id);
    
       /**
        * 添加一条实体,实体不能为null
        * <blockquote>
        *     <table cellpadding=1 border=1  cellspacing=0 summary="Capturing group numberings">
        *        <tr>
        *            <th><tt>路径&nbsp;&nbsp;&nbsp;&nbsp;</tt></th>
        *           <th>访问方式&nbsp;&nbsp;&nbsp;&nbsp;</th>
        *            <th><tt>返回路径&nbsp;&nbsp;&nbsp;&nbsp;</tt></th>
        *      </tr>
        *      <tr>
        *            <th><tt>/sys/dictionary</tt></th>
        *           <th>post</th>
        *            <th><tt>redirect:/sys/dictionary/</tt></th>
        *      </tr>
        * </table>
        * </blockquote>
        * @param entity 要添加的实体
        * @return ModelAndView
        */
       public ModelAndView addOne(T entity);
    
       /**
        * 跳转到添加页面为insertXXX页面<br>示例Bean对象:SysDictionay->生成路径:/sys/dictionary
        * <blockquote>
        *     <table cellpadding=1 border=1  cellspacing=0 summary="Capturing group numberings">
        *        <tr>
        *            <th><tt>路径&nbsp;&nbsp;&nbsp;&nbsp;</tt></th>
        *           <th>访问方式&nbsp;&nbsp;&nbsp;&nbsp;</th>
        *            <th><tt>返回路径&nbsp;&nbsp;&nbsp;&nbsp;</tt></th>
        *      </tr>
        *      <tr>
        *            <th><tt>/sys/dictionary/add</tt></th>
        *           <th>get</th>
        *            <th><tt>/sys/dictionary/addDictionary.ftl</tt></th>
        *      </tr>
        * </table>
        * </blockquote>
        * @return ModelAndView
        */
       public ModelAndView addView();
    
       /**
        * 查询对象列表,返回页面 listXXX页面
        * <blockquote>
        *     <table cellpadding=1 border=1  cellspacing=0 summary="Capturing group numberings">
        *        <tr>
        *            <th><tt>路径&nbsp;&nbsp;&nbsp;&nbsp;</tt></th>
        *           <th>访问方式&nbsp;&nbsp;&nbsp;&nbsp;</th>
        *            <th><tt>返回路径&nbsp;&nbsp;&nbsp;&nbsp;</tt></th>
        *      </tr>
        *      <tr>
        *            <th><tt>/sys/dictionary</tt></th>
        *           <th>get</th>
        *            <th><tt>/sys/dictionary/listDictionary.ftl</tt></th>
        *      </tr>
        * </table>
        * </blockquote>
        * @param query 查询对象
        * @param pageable 分页参数与排序参数
        * @return  ModelAndView
        */
       public ModelAndView selectList(Q query, Pageable pageable);
    
       /**
        * 根据ID查询一个对象,返回页面为viewXXX页面
        * <blockquote>
        *     <table cellpadding=1 border=1  cellspacing=0 summary="Capturing group numberings">
        *        <tr>
        *            <th><tt>路径&nbsp;&nbsp;&nbsp;&nbsp;</tt></th>
        *           <th>访问方式&nbsp;&nbsp;&nbsp;&nbsp;</th>
        *            <th><tt>返回路径&nbsp;&nbsp;&nbsp;&nbsp;</tt></th>
        *      </tr>
        *      <tr>
        *            <th><tt>/sys/dictionary/${id}</tt></th>
        *           <th>get</th>
        *            <th><tt>/sys/dictionary/viewDictionary.ftl</tt></th>
        *      </tr>
        * </table>
        * </blockquote>
        * @param id 不能为null,则跳转到错误页面
        * @return ModelAndView
        */
       public ModelAndView viewOne(String id);
    
       /**
        * 更新一个实体,实体不能为null
        * <blockquote>
        *     <table cellpadding=1 border=1  cellspacing=0 summary="Capturing group numberings">
        *        <tr>
        *            <th><tt>路径&nbsp;&nbsp;&nbsp;&nbsp;</tt></th>
        *           <th>访问方式&nbsp;&nbsp;&nbsp;&nbsp;</th>
        *            <th><tt>返回路径&nbsp;&nbsp;&nbsp;&nbsp;</tt></th>
        *      </tr>
        *      <tr>
        *            <th><tt>/sys/dictionary/</tt></th>
        *           <th>put</th>
        *            <th><tt>{@link Result}已更新的实体对象json字符串</tt></th>
        *      </tr>
        * </table>
        * </blockquote>
        * @param entity 要更新的实体
        * @return Result
        */
       public ModelAndView editOne(T entity);
    
       /**
        * 跳转到更新页面为editXXX页面
        * <blockquote>
        *     <table cellpadding=1 border=1  cellspacing=0 summary="Capturing group numberings">
        *        <tr>
        *            <th><tt>路径&nbsp;&nbsp;&nbsp;&nbsp;</tt></th>
        *           <th>访问方式&nbsp;&nbsp;&nbsp;&nbsp;</th>
        *            <th><tt>返回路径&nbsp;&nbsp;&nbsp;&nbsp;</tt></th>
        *      </tr>
        *      <tr>
        *            <th><tt>/sys/dictionary/edit/${id}</tt></th>
        *           <th>get</th>
        *            <th><tt>/sys/dictionary/editDictionary.ftl</tt></th>
        *      </tr>
        * </table>
        * </blockquote>
        * @param id 不能为null,则跳转到错误页面
        * @return ModelAndView
        */
       public ModelAndView editView(String id);
    
       /*
       * ajax Post添加数据
       * */
       public Result postAdd(T entity);
    
       /*
       * ajax Post修改数据
       * */
       public Result postEdit(T entity);
    
    }

    basecontrollerImpl 接口的实现类

    package com.zhan.common.controller.base;
    
    import com.zhan.common.domain.ControllerPath;
    import com.zhan.common.domain.base.Identifiable;
    import com.zhan.common.domain.base.Result;
    import com.zhan.common.service.base.BaseService;
    import org.apache.commons.lang3.ArrayUtils;
    import org.apache.commons.lang3.StringUtils;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.data.domain.Page;
    import org.springframework.data.domain.Pageable;
    import org.springframework.data.web.PageableDefault;
    import org.springframework.http.MediaType;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.servlet.ModelAndView;
    
    import java.util.Arrays;
    
    /**
     * 基础控制器接口实现类
     * @author LiuJunGuang
     * @date 2014年3月5日下午12:03:13
     */
    public abstract class BaseControllerImpl<T extends Identifiable, Q extends T> implements BaseController<T, Q> {
       private Logger log = LoggerFactory.getLogger(BaseControllerImpl.class);
       /**
        * @fields path 页面路径信息
        */
       protected ControllerPath path = new ControllerPath(this.getClass());
    
       /**
        * 获取基础的服务
        * @return BaseService
        */
       protected abstract BaseService<T> getBaseService();
    
       @Override
       @ResponseBody
       @RequestMapping(value = "/delete", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_VALUE)
       public Result deleteList(String[] ids) {
          if (ArrayUtils.isEmpty(ids)) {
             log.error("未设置批量删除对象的ID号!对象:{}", path.getEntityName());
             return new Result(Result.Status.ERROR, "没有传入要删除的ID号数组!");
          }
          try {
             getBaseService().deleteByIdInBatch(Arrays.asList(ids));
          } catch (Exception e) {
             log.error("批量删除对象失败!对象:" + path.getEntityName(), e);
             return new Result(Result.Status.ERROR, "批量删除失败!");
          }
          return new Result(Result.Status.OK, ids.length);
       }
    
       @Override
       @ResponseBody
       @RequestMapping(value = "/{id}", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_VALUE)
       public Result deleteOne(@PathVariable("id") String id) {
          if (StringUtils.isBlank(id)) {
             log.error("要删除的ID号为null或空字符串!对象:{}", path.getEntityName());
             return new Result(Result.Status.ERROR, "没有传入要删除的ID号!");
          }
          int count = getBaseService().deleteById(id);
          if (count == 0)
             return new Result(Result.Status.ERROR, "要删除的记录不存在!");
          log.debug("成功删除{}个对象,id:{},对象:{}", count, id, path.getEntityName());
          return new Result(Result.Status.OK, count);
       }
    
       @Override
       @RequestMapping(method = RequestMethod.POST)
       public ModelAndView addOne(T entity) {
          getBaseService().insert(entity);
          return new ModelAndView(path.getRedirectListPath());
       }
    
       @Override
       @RequestMapping(value = "/add", method = RequestMethod.GET)
       public ModelAndView addView() {
          return new ModelAndView(path.getAddViewPath());
       }
    
       @Override
       @RequestMapping(method = RequestMethod.GET)
       public ModelAndView selectList(Q query, @PageableDefault Pageable pageable) {
          Page<T> page = getBaseService().queryPageList(query, pageable);
          ModelAndView mav = new ModelAndView(path.getListViewPath(), "page", page);
          mav.addObject("query", query);
          return mav;
       }
    
       @Override
       @RequestMapping(value = "/{id}", method = RequestMethod.GET)
       public ModelAndView viewOne(@PathVariable("id") String id) {
          Object obj = getBaseService().queryById(id);
          return new ModelAndView(path.getOneViewPath(), path.getEntityName(), obj);
       }
    
       @Override
       @RequestMapping(method = RequestMethod.PUT)
       public ModelAndView editOne(T entity) {
          getBaseService().updateById(entity);
          return new ModelAndView(path.getRedirectListPath());
       }
    
       @Override
       @RequestMapping(value = "/edit/{id}", method = RequestMethod.GET)
       public ModelAndView editView(@PathVariable("id") String id) {
          Object obj = getBaseService().queryById(id);
          return new ModelAndView(path.getEditViewPath(), path.getEntityName(), obj);
       }
       /*
       * ajax Post添加数据
       * */
       @Override
       @ResponseBody
       @RequestMapping(value = "/ajaxAdd", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
       public Result postAdd(T entity){
          getBaseService().insert(entity);
          return new Result(Result.Status.OK,null);
       }
    
       /*
       * ajax Post修改数据
       * */
    
       @Override
       @ResponseBody
       @RequestMapping(value = "/ajaxEdit", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
       public Result postEdit(T entity){
          getBaseService().updateById(entity);
          return new Result(Result.Status.OK,null);
    package com.zhan.common.domain;
    
    import com.zhan.common.constants.PagePrefix;
    import com.zhan.common.utils.BeanUtils;
    import com.zhan.common.utils.StringEx;
    import org.apache.commons.lang3.StringUtils;
    
    /**
     * Controller路径构建起
     * @author LiuJunGuang
     * @date 2014年3月5日下午3:11:43
     */
    public class ControllerPath {
    
       /**
        * @fields entityClass 简单的实体类
        */
       private Class<?> entityClass = null;
       /**
        * @fields URL_SEPARATOR 路径分隔符
        */
       private static final String URL_SEPARATOR = "/";
    
       /**
        * @fields entityName 实体名称
        */
       private String entityName = null;
       /**
        * @fields words 实体类路径
        */
       private String[] words = null;
    
       public ControllerPath(Class<?> genericClass) {
          if (genericClass == null) throw new IllegalArgumentException("[genericClass] - must not be null!");
    
          entityClass = BeanUtils.getGenericClass(genericClass);
    
          if (entityClass == null) throw new IllegalArgumentException(genericClass.getName() + "不是泛型类型!");
    
          words = getWords(entityClass.getSimpleName());
          entityName = words[words.length - 1];
       }
    
       /**
        * 获取显示页面路径  
        * @return String "sys/dictionary/viewDictionary" 
        */
       public String getOneViewPath() {
          StringBuilder sb = new StringBuilder();
          sb.append(getBasePath());
          sb.append(PagePrefix.VIEW);
          sb.append(StringEx.toUpperCaseFirstOne(entityName));
          return sb.toString();
       }
    
       /**
        * 显示列表路径
        * @return String "sys/dictionary/listDictionary" 
        */
       public String getListViewPath() {
          StringBuilder sb = new StringBuilder();
          sb.append(getBasePath());
          sb.append(PagePrefix.LIST);
          sb.append(StringEx.toUpperCaseFirstOne(entityName));
          return sb.toString();
       }
    
       /**
        * 添加页面路径信息
        * @return
        */
       public String getAddViewPath() {
          StringBuilder sb = new StringBuilder();
          sb.append(getBasePath());
          sb.append(PagePrefix.ADD);
          sb.append(StringEx.toUpperCaseFirstOne(entityName));
          return sb.toString();
       }
    
       /**
        * 添加页面路径信息
        * @return
        */
       public String getEditViewPath() {
          StringBuilder sb = new StringBuilder();
          sb.append(getBasePath());
          sb.append(PagePrefix.EDIT);
          sb.append(StringEx.toUpperCaseFirstOne(entityName));
          return sb.toString();
       }
    
       /**
        * 推送页面路径信息
        * @return
        */
       public String getPushViewPath() {
          StringBuilder sb = new StringBuilder();
          sb.append(getBasePath());
          sb.append(PagePrefix.PUSH);
          sb.append(StringEx.toUpperCaseFirstOne(entityName));
          return sb.toString();
       }
    
       /**
        * 获取删除返回路径,默认重定向到列表页面
        * @return
        */
       public String getRedirectListPath() {
          return "redirect:/" + getBasePath();
       }
    
       /**
        * 获取实体的名称,全小写
        * @return
        */
       public String getEntityName() {
          return entityName;
       }
    
       /**
        * 以字符串中的大写字母为标示拆分字符串,如果字符串为null或空则返回null
        * @param str
        * @return String[] 拆分后的字符串,已转换为全小写
        */
       private String[] getWords(String str) {
          if (StringUtils.isEmpty(str)) return null;
          String[] words = str.split("(?<!^)(?=[A-Z])");
          for (int i = 0; i < words.length; i++) {
             words[i] = StringUtils.lowerCase(words[i]);
          }
          return words;
       }
    
       /**
        * 获取类名路径信息,例如:SysDictionary 则返回  "sys/dictionary/"
        * @param clazz 类
        * @return String 类名路径信息
        */
       private String getBasePath() {
          StringBuffer sb = new StringBuffer();
          for (String word : words) {
             sb.append(word).append(URL_SEPARATOR);
          }
          return sb.toString();
       }
    
    }
    原文:https://blog.csdn.net/qq_36838191/article/details/80063043 
  • 相关阅读:
    工作后对单元测试学习的一点总结
    图片做按钮会将form表单自动提交
    转jMock Cookbook 中文版三
    转jMock Cookbook 中文版二
    转jMock Cookbook 中文版一
    JUnit4学习笔记(五):Theory(理论)测试
    JUnit4学习笔记(四):利用Rule扩展JUnit
    JUnit4学习笔记(三):assertThat语法与Matcher
    JUnit4学习笔记(二):参数化测试与假定(Assumption)
    junit学习一
  • 原文地址:https://www.cnblogs.com/h-c-g/p/10846661.html
Copyright © 2020-2023  润新知