本文是记录我在学习和使用若依时的学习笔记
1、为什么若依的controller类要继承BaseController类
我们在写项目的时候,会把一些很多相同的代码或使用相同的功能抽取出来,例如一些工具类。也会为了提现代码的高可用性,我们常用的是的把dao层进行抽取,在若依里面,抽了一些controller层常用的方法,然后进行继承。这样,在后面使用的时候,可以直接调用他,这样可以简化开发。他是controller层的一个通用数据处理。
2、日志记录
private static final Logger log = LoggerFactory.getLogger(CommonController.class);
当controller层继承了BaseController类,就可以直接打印日志了,它是通过传过来的class类名来获取对象,从而进行记录。日志级别由高到底是:fatal 、 error 、 warn 、 info 、 debug,
3、日期转换
@InitBinder
public void initBinder(WebDataBinder binder)
{
binder.registerCustomEditor(Date.class, new PropertyEditorSupport()
{
@Override
public void setAsText(String text)
{
setValue(DateUtils.parseDate(text)); //DateUtils 日期工具类
}
});
}
@InitBinder类
@InitBinder用于在@Controller中标注于方法上,表示为当前控制器注册一个属性编辑器,只对当前的Controller有效。
@InitBinder标注的方法必须有一个参数WebDataBinder。所谓的属性编辑器可以理解就是帮助我们完成参数绑定。
WebDataBinder是DataBinder的子类,用于完成由表单到JavaBean属性的绑定。
4、分页设置
在controller层可以直接调用startPage进行分页
/**
* 设置请求分页数据
*/
protected void startPage()
{
PageUtils.startPage();
}
通过调用PageUtils.startPage()方法。该类继承了PageHelper类,PageHelper是是mybatis 提供的分页插件,目前支持Oracle,Mysql,MariaDB,SQLite,Hsqldb,PostgreSQL六种数据库。。
该方法的需要在pom.xml上添加依赖
<!-- pagehelper 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
</dependency>
同时需要在application.yml进行配置
# PageHelper分页插件
pagehelper:
helperDialect: mysql
supportMethodsArguments: true
params: count=countSql
/**
* 设置请求分页数据
*/
public static void startPage()
{
PageDomain pageDomain = TableSupport.buildPageRequest();
//从TableSupport.buildPageRequest()中获取一些参数 放到分页里面 进行匹配
Integer pageNum = pageDomain.getPageNum(); //起始页,默认放1
Integer pageSize = pageDomain.getPageSize(); //获取每页的大小
String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy()); //升序还是降序
Boolean reasonable = pageDomain.getReasonable(); //分页参数合理化
// 分页插件使用PageHelper工具类完成分页设置
PageHelper.startPage(pageNum, pageSize, orderBy).setReasonable(reasonable);
}
PageDomain 是分页的一个数据类
public class PageDomain
{
/** 当前记录起始索引 */
private Integer pageNum;
/** 每页显示记录数 */
private Integer pageSize;
/** 排序列 */
private String orderByColumn;
/** 排序的方向desc或者asc */
private String isAsc = "asc";
/** 分页参数合理化 */
private Boolean reasonable = true;
TableSupport
/**
* 封装分页对象
*/
public static PageDomain getPageDomain()
{
//通过ServletUtils来获取参数请求,ServletUtils是一个客户端工具类
PageDomain pageDomain = new PageDomain();
pageDomain.setPageNum(Convert.toInt(ServletUtils.getParameter(PAGE_NUM), 1)); // //起始页,默认放1
pageDomain.setPageSize(Convert.toInt(ServletUtils.getParameter(PAGE_SIZE), 10)); //设置每页放多少条记录 每个记录是10
pageDomain.setOrderByColumn(ServletUtils.getParameter(ORDER_BY_COLUMN)); //排序列
pageDomain.setIsAsc(ServletUtils.getParameter(IS_ASC)); //排序分方向
pageDomain.setReasonable(ServletUtils.getParameterToBool(REASONABLE)); //分页参数合理化
return pageDomain;
}
public static PageDomain buildPageRequest()
{
return getPageDomain();
}
首先通过HttpServletRequest.getRequest.getParameter(name)来获得请求路径已经传过来的参数。然后放进PageDomain 里面。在PageUtils.startPage()方法中得到这些数据
5、分页数据封装
对分页查询的数据进行封装
/**
* 响应请求分页数据
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
protected TableDataInfo getDataTable(List<?> list)
{
TableDataInfo rspData = new TableDataInfo();
rspData.setCode(0); //设置消息状态码为0
rspData.setRows(list); //列表数据
rspData.setTotal(new PageInfo(list).getTotal()); //设置得到的list有多少 就是多少多少条记录 总记录数
return rspData;
}
@SuppressWarnings 是J2SE 提供的最后一个批注是 @SuppressWarnings。该批注的作用是给编译器一条指令,告诉它对被批注的代码元素内部的某些警告保持静默。
controller层如果要返回一些数据,他的返回类型是TableDataInfo ,然后通过该方法进行返回
public class TableDataInfo implements Serializable
{
private static final long serialVersionUID = 1L;
/** 总记录数 */
private long total;
/** 列表数据 */
private List<?> rows;
/** 消息状态码 */
private int code;
/** 消息内容 */
private String msg;
/**
* 表格数据对象
*/
public TableDataInfo()
{
}
/**
* 清理分页的线程变量
*/
protected void clearPage()
{
PageUtils.clearPage();
}
6、获取request、response、session
/**
* 获取request
*/
public HttpServletRequest getRequest()
{
return ServletUtils.getRequest();
}
/**
* 获取response
*/
public HttpServletResponse getResponse()
{
return ServletUtils.getResponse();
}
/**
* 获取session
*/
public HttpSession getSession()
{
return getRequest().getSession();
}
都是通过ServletUtils 工具类进行调用
在ServletUtils是实现了这个方法来获取request和response
public static ServletRequestAttributes getRequestAttributes()
{
// 接收到请求,记录请求内容
RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
return (ServletRequestAttributes) attributes;
}
我们可以一下RequestAttributes 方法的一个结构,其底层是实现了RequestAattributes
RequestContextHolder这个类的作用是通过操作RequestAttributes请求属性这个对象(绑定了线程)来间接处理请求相关的一些东西。所以你可以看到代码中首先拿到了RequestAttributes对象,当然这里要转成Servlet类型。
RequestAttributes 类如果不转型,那个attributes类是无法方便操作request、session这些原生servlet相关的对象或者属性的,因为本身Java Web最原始的实现就是servlet形式的,Spring框架当然会为其做特定的一些封装,也就是这个类的来源。
代码中首先通过属性拿到了HttpServletRequest对象,然后通过请求对象拿到session。
这里有个小问题,那就是既然里面已经有一个getSession(boolean allowCreate)方法了,那为啥不直接获取session对象呢?
在ServletUtils 其逻辑可以分为以下几步
//第一步, 接收到请求,记录请求内容
public static ServletRequestAttributes getRequestAttributes()
{
RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
return (ServletRequestAttributes) attributes;
}
//简化成一行代码为:
RequestAttributes attributes =(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//第二步,接收到request、response
public static HttpServletRequest getRequest()
{
return getRequestAttributes().getRequest();
}
public static HttpServletResponse getResponse()
{
return getRequestAttributes().getResponse();
}
//简化成一行代码
HttpServletRequest request = attributes.getRequest();
HttpServletRequest response= attributes.getResponse();
//第三步;获取参数
/**
* 获取String参数
*/
public static String getParameter(String name)
{
return getRequest().getParameter(name);
}
/**
* 获取String参数
*/
public static String getParameter(String name, String defaultValue)
{
return Convert.toStr(getRequest().getParameter(name), defaultValue);
}
/**
* 获取Integer参数
*/
public static Integer getParameterToInt(String name)
{
return Convert.toInt(getRequest().getParameter(name));
}
/**
* 获取Integer参数
*/
public static Integer getParameterToInt(String name, Integer defaultValue)
{
return Convert.toInt(getRequest().getParameter(name), defaultValue);
}
/**
* 获取Boolean参数
*/
public static Boolean getParameterToBool(String name)
{
return Convert.toBool(getRequest().getParameter(name));
}
/**
* 获取Boolean参数
*/
public static Boolean getParameterToBool(String name, Boolean defaultValue)
{
return Convert.toBool(getRequest().getParameter(name), defaultValue); //获取前端传过来的参数
}
7、响应返回结果
把有参、无参都放进其中,这样做可以调用,比较灵活多变。
**
* 返回成功消息
*/
public AjaxResult success(String message)
{
return AjaxResult.success(message);
}
/**
* 返回成功数据
*/
public static AjaxResult success(Object data)
{
return AjaxResult.success("操作成功", data);
}
/**
* 返回失败消息
*/
public AjaxResult error(String message)
{
return AjaxResult.error(message);
}
/**
* 返回错误码消息
*/
public AjaxResult error(Type type, String message)
{
return new AjaxResult(type, message);
}
8、获取用户信息
/**
* 获取用户缓存信息
*/
public SysUser getSysUser()
{
return ShiroUtils.getSysUser(); //从shiro哪里得到user
}
/**
* 设置用户缓存信息
*/
public void setSysUser(SysUser user)
{
ShiroUtils.setSysUser(user);
}
/**
* 获取登录用户id
*/
public Long getUserId()
{
return getSysUser().getUserId();
}
/**
* 获取登录用户名
*/
public String getLoginName()
{
return getSysUser().getLoginName();
}
从shiro哪里拿到用户的信息,如用户名 id等等
在ShiroUtils写了一个方法,只要用户进行登录,就会保存其中。放在BaseController里面,controller层起来类继承了BaseControlle只要想使用,可以直接调用即可,简单方便。
//获取用户登录的时候的用户
public static SysUser getSysUser()
{
SysUser user = null;
Object obj = getSubject().getPrincipal();
if (StringUtils.isNotNull(obj))
{
user = new SysUser();
BeanUtils.copyBeanProp(user, obj); //如果obj不是空的 就把obj里面的角色复制给user
}
return user;
}
9、总结
这几个模块功能都是若依controller层常用的方法,controller层的类继承了BaseController类,可以直接使用方法,这样可以简化代码,灵活多变。