BaseController 的使用

本文介绍了一个通用控制器接口(BaseController)的设计思路与实现方法,通过抽象公共的CRUD操作,简化了Spring MVC应用中控制器的开发过程。该设计支持实体的增删改查,并提供了统一的路径映射和响应格式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

}
}}


<think>好的,用户的问题是关于如何在项目中添加和配置BaseController或其相关框架。首先,我需要明确用户提到的BaseController是什么。根据提供的引用内容,特别是引用[1]和[2],BaseController似乎是在CodeIgniter和若依(RuoYi)框架中使用的一个基类控制器,用于提供通用功能,比如视图自动加载或布局支持。 接下来,用户可能是在使用类似CodeIgniter或Spring MVC的框架,需要集成BaseController。但引用中提到的CodeIgniter-base-controller项目已经被标记为弃用,所以需要提醒用户这一点。此外,引用[3]和[4]涉及Spring MVC的注解和配置,说明用户可能对Spring MVC中的控制器配置也有兴趣。 我需要分情况讨论,因为不同的框架有不同的配置方法。首先处理CodeIgniter的情况,然后是若依框架,最后是Spring MVC,因为用户可能混淆了不同框架中的BaseController概念。 对于CodeIgniter,虽然原项目已弃用,但安装步骤仍然可以给出,同时建议替代方案。对于若依框架,引用[2]提到继承BaseController,需要说明其用途和配置方法。在Spring MVC中,通常不会直接使用BaseController,但可以通过自定义基类来实现类似功能,需要指导用户如何创建和配置。 此外,用户可能不太清楚不同框架之间的区别,需要明确区分,并提供每一步的具体操作,比如依赖添加、继承类、方法重写等。同时,要检查是否有遗漏的步骤,比如自动加载配置或注解的使用,确保配置正确。 最后,生成相关问题时要覆盖不同框架和常见问题,帮助用户进一步探索可能的需求。</think>### 如何添加和配置 BaseController 或相关框架 #### 一、CodeIgniter 的 BaseController 配置(已弃用) 引用[1]提到的 `codeigniter-base-controller` 是一个已弃用的项目,但若需参考其实现逻辑: 1. **手动实现基类控制器** - 在 `application/core/` 目录下创建 `MY_Controller.php` ```php class BaseController extends CI_Controller { public function __construct() { parent::__construct(); // 添加通用逻辑(如视图自动加载) } } ``` - 其他控制器继承此基类: ```php class UserController extends BaseController { // 控制器方法 } ``` #### 二、若依(RuoYi)框架的 BaseController 引用[2]提到若依框架通过继承 `BaseController` 实现通用功能(如日志记录、权限验证): 1. **配置步骤** - 查看 `BaseController` 的源码位置(通常位于 `framework/web/core` 目录) - 新建控制器时直接继承: ```java @Controller @RequestMapping("/user") public class UserController extends BaseController { // 使用基类提供的公共方法 } ``` - 确保项目依赖包含若依的 `framework` 模块(通过 Maven/Gradle 配置) #### 三、Spring MVC 自定义基类控制器 引用[3][4]提到 Spring MVC 中可通过自定义基类实现通用逻辑: 1. **创建 BaseController 类** ```java @Controller public class BaseController { // 通用方法(如统一响应格式) protected ResponseEntity<Result> success(Object data) { return ResponseEntity.ok(Result.success(data)); } } ``` 2. **子类控制器继承** ```java @RestController @RequestMapping("/api") public class UserController extends BaseController { @GetMapping("/users") public ResponseEntity<Result> getUsers() { return success(userService.getAll()); } } ``` 3. **依赖配置(Maven)** ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> ``` #### 四、通用注意事项 1. **框架兼容性** - 不同框架的 `BaseController` 实现方式不同,需遵循各自规范(如 CodeIgniter 要求文件路径,Spring 依赖注解) 2. **功能扩展** - 基类通常用于封装:请求预处理、日志记录、权限校验等[^2][^4] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值