为了提现代码的高可用性,我们可以常见的把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

BaseController 的使用的更多相关文章

  1. 从零开始,搭建博客系统MVC5+EF6搭建框架(3),添加Nlog日志、缓存机制(MemoryCache、RedisCache)、创建控制器父类BaseController

    一.回顾系统进度以及本章概要 目前博客系统已经数据库创建.以及依赖注入Autofac集成,接下来就是日志和缓存集成,这里日志用的是Nlog,其实还有其他的日志框架如log4,这些博客园都有很多介绍,这 ...

  2. [ionic开源项目教程] - 第11讲 封装BaseController实现controller继承

    关注微信订阅号:TongeBlog,可查看[ionic开源项目]全套教程. 截止到第10讲,tab1[健康]模块的功能基本已经完成了,但这一讲中,controller层又做了较大的改动,因为下一讲中t ...

  3. 利用.Net自带的票据完成BaseController的未登陆自动跳转到登陆页功能

    一:定义票据中要记录的字段类 /// <summary> /// 用户存在于浏览器端的身份票据(非持久) /// 非持久 FormsAuthenticationTicket 的isPers ...

  4. 在webAPI的BaseController上使用RoutePrefix

    在webAPI2.2中有支持,参考地址:https://docs.microsoft.com/en-us/aspnet/web-api/overview/releases/whats-new-in-a ...

  5. 工具类封装之--BaseController

    package cn.xxx.base; import cn.xxx.gecustomer.beans.GeCustomer; import cn.xxx.gecustomer.beans.GeCus ...

  6. 【干货】利用MVC5+EF6搭建博客系统(三)添加Nlog日志、缓存机制(MemoryCache、RedisCache)、创建控制器父类BaseController

    PS:如果图片模糊,鼠标右击复制图片网址,然后在浏览器中打开即可. 一.回顾系统进度以及本章概要 目前博客系统已经数据库创建.以及依赖注入Autofac集成,接下来就是日志和缓存集成,这里日志用的是N ...

  7. SSM 中 BaseController 使用 session

    转载: http://blog.sina.com.cn/s/blog_7085382f0102v9jg.html public class BaseController { //region Http ...

  8. MVC Controller 基类 BaseController 中的 Request

    今天修复mvc中的一个bug,需求是每个页面要获取当前URL链接中 host首是否正确,我把获取url的方法写到了Controller的基类BaseController(BaseController继 ...

  9. 登录控制 BaseController

    执行方法前 判断 sessin 登录信息 是否为空 ,空的话 返回 登录界面 并且给 LoginUser 赋值 public abstract class BaseController : Contr ...

  10. 使用Spring MVC后实现一个BaseController

    使用Spring MVC技术后,可以实现一个基类的Controller类来分装一些MVC常用的方法,其他的Controller都继承自这个BaseController,这样在使用常用的方法时将会变得非 ...

随机推荐

  1. js实现点击空白处隐藏

    部分业务要求除了某元素外点击其他对象,对应的元素隐藏,下面是一个demo效果, <!DOCTYPE html> <html> <head> <meta cha ...

  2. [JZOJ3303] 【集训队互测2013】城市规划

    题目 题目大意 求\(N\)个点的简单无向图的方案数(有编号). 结果对\(1004535809\)取模. 思考历程 感觉这个问题非常经典. 当时想到了一堆式子,但都觉得可能会有重和漏,于是弃掉了-- ...

  3. JavaScript - 常用对象相关

    1. String对象 length : 字符串的长度 charAt(index) : 返回指定位置的字符串, 下标从0开始 indexOf(str) : 返回指定的字符串在当前字符串中首次出现的位置 ...

  4. Date()日期转换和简单计算

    /** * 判断是否为闰年 * @param year * @return */ public boolean isLeap ( int year ) { if ( (year % 4 == 0 &a ...

  5. 单调栈——cf777E

    傻逼单调栈啊我怎么想了半天dp #include <bits/stdc++.h> using namespace std; typedef long long LL; typedef st ...

  6. 计算几何——线段和直线判交点poj3304

    #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #i ...

  7. Vue学习笔记——Vue-router

    转载:https://blog.csdn.net/guanxiaoyu002/article/details/81116616 第1节:Vue-router入门 .解读router/index.js文 ...

  8. div中包着文字,div出现隐藏的时候,文字总是在div外面。

    背景: 给博客加一个侧边栏,点击出现隐藏,每次点击出现或者隐藏,文字总是很突兀的就出来了. 解决: overflow:hidden

  9. 数据库小技巧:使用distinct去除重复行

    这里有2个表 问题question表 楼层question_floor表 需求:已知某用户的id为uid,实现“我的回复”功能,即查看我回复的所有问题 遇到的问题:如果直接对question表和que ...

  10. Mybatis功能架构及执行流程

    原文地址:http://blog.51cto.com/12222886/2052647 一.功能架构设计 功能架构讲解: 我们把Mybatis的功能架构分为三层: (1) API接口层:提供给外部使用 ...