web层Controller通用处理(表格数据处理、分页数据、sql操作、客户端servlet、字符串工具类)

BaseController(一)

public class BaseController{// slf4j-api-1.7.30.jarprotected final Logger logger = LoggerFactory.getLogger(BaseController.class);/**将前端传递过来的日期格式字符串,转换为Date类型spring-web-5.3.1.jar*/@InitBinderpublic void initBinder(WebDataBinder binder){binder.registerCustomEditor(Date.class, new PropertyEditorSupport() {@Overridepublic void setAsText(String text) {setValue(DateUtils.parseDate(text));}});}/**设置请求分页数据*/protected void startPage(){//构建分页对象 pagehelper-5.2.0.jarPageDomain pageDomain = TableSupport.buildPageRequest();Integer pageNum = pageDomain.getPageNum();Integer pageSize = pageDomain.getPageSize();if(null != pageNum && null != pageSize){String orderBy = pageDomain.getIsAsc() = null?"":SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());PageHelper.startPage(pageNum, pageSize, orderBy);}}/*** 获取request*/public HttpServletRequest getRequest() {return ServletUtils.getRequest();}/*** 获取response*/public HttpServletResponse getResponse() {return ServletUtils.getResponse();}/*** 获取session*/public HttpSession getSession() {return getRequest().getSession();}/**从请求的headeer中获取信息*/public long getCurrentUserId(){//通用常量 "current_id"String currentId = getRequest().getHeader(Constants.CURRENT_ID);// commons-lang3-3.11.jarif(StringUtils.isNotBlank(currentId)){return Long.valueOf(currentId);}return 0L;}public long getParkId() {String parkId = getRequest().getHeader(Constants.PARK_ID);if (StringUtils.isNotBlank(parkId)) {return Long.valueOf(parkId);}return 0L;}public String getLoginName() {return getRequest().getHeader(Constants.CURRENT_USERNAME);}/*** 响应请求分页数据*/@SuppressWarnings({"rawtypes", "unchecked"})protected TableDataInfo getDataTable(List<?> list) {TableDataInfo rspData = new TableDataInfo();rspData.setCode(0);rspData.setRows(list);rspData.setTotal(new PageInfo(list).getTotal());return rspData;}@SuppressWarnings({"rawtypes", "unchecked"})protected R result(List<?> list) {PageInfo<?> pageInfo = new PageInfo(list);Map<String, Object> m = new HashMap<String, Object>();m.put("rows", list);m.put("pageNum", pageInfo.getPageNum());m.put("total", pageInfo.getTotal());return R.ok(m);}/*** 响应返回结果** @param rows 影响行数* @return 操作结果*/protected R toAjax(int rows) {return rows > 0 ? R.ok() : R.error();}/*** 响应返回结果** @param result 结果* @return 操作结果*/protected R toAjax(boolean result) {return result ? R.ok() : R.error();}
}

=============================================================

表格数据处理

public class TableSupport{/*** 封装分页对象*/public static PageDomain getPageDomain() {PageDomain pageDomain = new PageDomain();pageDomain.setPageNum(ServletUtils.getParameterToInt(Constants.PAGE_NUM));pageDomain.setPageSize(ServletUtils.getParameterToInt(Constants.PAGE_SIZE));pageDomain.setOrderByColumn(ServletUtils.getParameter(Constants.ORDER_BY_COLUMN));pageDomain.setIsAsc(ServletUtils.getParameter(Constants.IS_ASC));return pageDomain;}public static PageDomain buildPageRequest() {return getPageDomain();}
}

分页数据

public class PageDomain{/*** 当前记录起始索引*/private Integer pageNum;/*** 每页显示记录数*/private Integer pageSize;/*** 排序列*/private String orderByColumn;/*** 排序的方向 "desc" 或者 "asc".*/private String isAsc;public String getOrderBy() {if (StringUtils.isEmpty(orderByColumn)) {return "";}return StringUtils.toUnderScoreCase(orderByColumn) + " " + isAsc;}public Integer getPageNum() {return pageNum;}public void setPageNum(Integer pageNum) {this.pageNum = pageNum;}public Integer getPageSize() {return pageSize;}public void setPageSize(Integer pageSize) {this.pageSize = pageSize;}public String getOrderByColumn() {return orderByColumn;}public void setOrderByColumn(String orderByColumn) {this.orderByColumn = orderByColumn;}public String getIsAsc() {return isAsc;}public void setIsAsc(String isAsc) {this.isAsc = isAsc;}
}

sql操作工具类

public class SqlUtil{/*** 仅支持字母、数字、下划线、空格、逗号(支持多个字段排序)*/public static String SQL_PATTERN = "[a-zA-Z0-9_\\ \\,]+";/*** 检查字符,防止注入绕过*/public static String escapeOrderBySql(String value) {if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value)) {return StringUtils.EMPTY;}return value;}/*** 验证 order by 语法是否符合规范*/public static boolean isValidOrderBySql(String value) {return value.matches(SQL_PATTERN);}
}

客户端工具类

public class ServletUtils{/*** 获取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);}/*** 获取request*/public static HttpServletRequest getRequest() {return getRequestAttributes().getRequest();}/*** 获取response*/public static HttpServletResponse getResponse() {return getRequestAttributes().getResponse();}/*** 获取session*/public static HttpSession getSession() {return getRequest().getSession();}public static ServletRequestAttributes getRequestAttributes() {RequestAttributes attributes = RequestContextHolder.getRequestAttributes();return (ServletRequestAttributes) attributes;}/*** 将字符串渲染到客户端** @param response 渲染对象* @param string   待渲染的字符串* @return null*/public static String renderString(HttpServletResponse response, String string) {try {response.setContentType("application/json");response.setCharacterEncoding("utf-8");response.getWriter().print(string);} catch (IOException e) {e.printStackTrace();}return null;}/*** 是否是Ajax异步请求** @param request*/public static boolean isAjaxRequest(HttpServletRequest request) {String accept = request.getHeader("accept");if (accept != null && accept.indexOf("application/json") != -1) {return true;}String xRequestedWith = request.getHeader("X-Requested-With");if (xRequestedWith != null && xRequestedWith.indexOf("XMLHttpRequest") != -1) {return true;}String uri = request.getRequestURI();if (StringUtils.inStringIgnoreCase(uri, ".json", ".xml")) {return true;}String ajax = request.getParameter("__ajax");if (StringUtils.inStringIgnoreCase(ajax, "json", "xml")) {return true;}return false;}
}

字符串工具类

public class StringUtils extends org.apache.commons.lang3.StringUtils {/*** 空字符串*/private static final String NULLSTR = "";/*** 下划线*/private static final char SEPARATOR = '_';/*** 获取参数不为空值** @param value defaultValue 要判断的value* @return value 返回值*/public static <T> T nvl(T value, T defaultValue) {return value != null ? value : defaultValue;}/*** * 判断一个Collection是否为空, 包含List,Set,Queue** @param coll 要判断的Collection* @return true:为空 false:非空*/public static boolean isEmpty(Collection<?> coll) {return isNull(coll) || coll.isEmpty();}/*** * 判断一个Collection是否非空,包含List,Set,Queue** @param coll 要判断的Collection* @return true:非空 false:空*/public static boolean isNotEmpty(Collection<?> coll) {return !isEmpty(coll);}/*** * 判断一个对象数组是否为空** @param objects 要判断的对象数组*                * @return true:为空 false:非空*/public static boolean isEmpty(Object[] objects) {return isNull(objects) || (objects.length == 0);}/*** * 判断一个对象数组是否非空** @param objects 要判断的对象数组* @return true:非空 false:空*/public static boolean isNotEmpty(Object[] objects) {return !isEmpty(objects);}/*** * 判断一个Map是否为空** @param map 要判断的Map* @return true:为空 false:非空*/public static boolean isEmpty(Map<?, ?> map) {return isNull(map) || map.isEmpty();}/*** * 判断一个Map是否为空** @param map 要判断的Map* @return true:非空 false:空*/public static boolean isNotEmpty(Map<?, ?> map) {return !isEmpty(map);}/*** * 判断一个字符串是否为空串** @param str String* @return true:为空 false:非空*/public static boolean isEmpty(String str) {return isNull(str) || NULLSTR.equals(str.trim());}/*** * 判断一个字符串是否为非空串** @param str String* @return true:非空串 false:空串*/public static boolean isNotEmpty(String str) {return !isEmpty(str);}/*** * 判断一个对象是否为空** @param object Object* @return true:为空 false:非空*/public static boolean isNull(Object object) {return object == null;}/*** * 判断一个对象是否非空** @param object Object* @return true:非空 false:空*/public static boolean isNotNull(Object object) {return !isNull(object);}/*** * 判断一个对象是否是数组类型(Java基本型别的数组)** @param object 对象* @return true:是数组 false:不是数组*/public static boolean isArray(Object object) {return isNotNull(object) && object.getClass().isArray();}/*** 去空格*/public static String trim(String str) {return (str == null ? "" : str.trim());}/*** 截取字符串** @param str   字符串* @param start 开始* @return 结果*/public static String substring(final String str, int start) {if (str == null) {return NULLSTR;}if (start < 0) {start = str.length() + start;}if (start < 0) {start = 0;}if (start > str.length()) {return NULLSTR;}return str.substring(start);}/*** 截取字符串** @param str   字符串* @param start 开始* @param end   结束* @return 结果*/public static String substring(final String str, int start, int end) {if (str == null) {return NULLSTR;}if (end < 0) {end = str.length() + end;}if (start < 0) {start = str.length() + start;}if (end > str.length()) {end = str.length();}if (start > end) {return NULLSTR;}if (start < 0) {start = 0;}if (end < 0) {end = 0;}return str.substring(start, end);}/*** 格式化文本, {} 表示占位符<br>* 此方法只是简单将占位符 {} 按照顺序替换为参数<br>* 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>* 例:<br>* 通常使用:format("this is {} for {}", "a", "b") -> this is a for b<br>* 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>* 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>** @param template 文本模板,被替换的部分用 {} 表示* @param params   参数值* @return 格式化后的文本*/public static String format(String template, Object... params) {if (isEmpty(params) || isEmpty(template)) {return template;}return StrFormatter.format(template, params);}/*** 下划线转驼峰命名*/public static String toUnderScoreCase(String str) {if (str == null) {return null;}StringBuilder sb = new StringBuilder();// 前置字符是否大写boolean preCharIsUpperCase = true;// 当前字符是否大写boolean curreCharIsUpperCase = true;// 下一字符是否大写boolean nexteCharIsUpperCase = true;for (int i = 0; i < str.length(); i++) {char c = str.charAt(i);if (i > 0) {preCharIsUpperCase = Character.isUpperCase(str.charAt(i - 1));} else {preCharIsUpperCase = false;}curreCharIsUpperCase = Character.isUpperCase(c);if (i < (str.length() - 1)) {nexteCharIsUpperCase = Character.isUpperCase(str.charAt(i + 1));}if (preCharIsUpperCase && curreCharIsUpperCase && !nexteCharIsUpperCase) {sb.append(SEPARATOR);} else if ((i != 0 && !preCharIsUpperCase) && curreCharIsUpperCase) {sb.append(SEPARATOR);}sb.append(Character.toLowerCase(c));}return sb.toString();}/*** 是否包含字符串** @param str  验证字符串* @param strs 字符串组* @return 包含返回true*/public static boolean inStringIgnoreCase(String str, String... strs) {if (str != null && strs != null) {for (String s : strs) {if (str.equalsIgnoreCase(trim(s))) {return true;}}}return false;}/*** 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。 例如:HELLO_WORLD->HelloWorld** @param name 转换前的下划线大写方式命名的字符串* @return 转换后的驼峰式命名的字符串*/public static String convertToCamelCase(String name) {StringBuilder result = new StringBuilder();// 快速检查if (name == null || name.isEmpty()) {// 没必要转换return "";} else if (!name.contains("_")) {// 不含下划线,仅将首字母大写return name.substring(0, 1).toUpperCase() + name.substring(1);}// 用下划线将原始字符串分割String[] camels = name.split("_");for (String camel : camels) {// 跳过原始字符串中开头、结尾的下换线或双重下划线if (camel.isEmpty()) {continue;}// 首字母大写result.append(camel.substring(0, 1).toUpperCase());result.append(camel.substring(1).toLowerCase());}return result.toString();}/*** 驼峰式命名法 例如:user_name->userName*/public static String toCamelCase(String s) {if (s == null) {return null;}s = s.toLowerCase();StringBuilder sb = new StringBuilder(s.length());boolean upperCase = false;for (int i = 0; i < s.length(); i++) {char c = s.charAt(i);if (c == SEPARATOR) {upperCase = true;} else if (upperCase) {sb.append(Character.toUpperCase(c));upperCase = false;} else {sb.append(c);}}return sb.toString();}
}

=============================================

BaseController (二)

public class BaseController{protected final Logger logger = LoggerFactory.getLogger(this.class());/**将前台传递过来打的日期格式的字符串,自动转换为Data类型*/@InitBinderpublic void initBinder(WebDataBinder binder){binder.registerCustomEditor(Date.class, new PropertyEditorSupport(){@Overridepublic void setAsText(String text){setValue(DateUtils.parseDate(text));}});}/**设置请求分页数据*/protected void startPage(){PageUtils.startPage();}/**设置请求排序数据*/protected void startOrderBy(){PageDomain pageDomain = TableSupport.buildPageRequest;if(StringUtils.isNotEmpty(pageDomain.getOrderBy())){String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());PageHelper.orderBy(orderBy);}}/**清理分页的线程变量*/protected void clearPage(){PageUtils.clearPage();}/**获取request*/public HttpServletRequest getRequest(){return ServletUtils.getRequest();}/**获取response*/public HttpServletResponse getResponse(){return ServletUtils.getResponse();}/**获取session*/public HttpSession getSession(){return getRequest().getSession();}/**响应请求分页数据*/@SuppressWarnings({ "rawtypes", "unchecked" })protected TableDataInfo getDataTable(List<?> list){TableDataInfo rspData = new TableDataInfo();rspData.setCode(0);rspData.setRows(list);rspData.setTotal(new PageInfo(list).getTotal());return rspData;	}/*** 响应返回结果* * @param rows 影响行数* @return 操作结果	*/protected AjaxResult toAjax(int rows){return rows > 0 ? success():error();}protected AjaxResult toAjax(boolean result){return result?success():error();}//返回成功public AjaxResult success(){return AjaxResult.success();}//返回失败public AjaxResult error(){return AjaxResult.error();}//返回成功消息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);}/**页面跳转*/public String redirect(String url){return StringUtils.format("redirect:{}",url);}/**获取用户缓存信息*/public SysUser getSysUser(){return ShiroUtils.getSysUser();}/*** 设置用户缓存信息*/public void setSysUser(SysUser user){ShiroUtils.setSysUser(user);}/*** 获取登录用户id*/public Long getUserId(){return getSysUser().getUserId();}/*** 获取登录用户名*/public String getLoginName(){return getSysUser().getLoginName();}}

PageUtils工具

分页工具类

public class PageUtils extends PageHelper{/*** 设置请求分页数据*/public static void startPage(){PageDomain pageDomain = TableSupport.buildPageRequest();Integer pageNum = pageDomain.getPageNum();Integer pageSize = pageDomain.getPageSize();String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());Boolean reasonable = pageDomain.getReasonable();PageHelper.startPage(pageNum, pageSize, orderBy).setReasonable(reasonable);}/*** 清理分页的线程变量*/public static void clearPage(){PageHelper.clearPage();}
}

PageDomain

/*** 分页数据* * @author ruoyi*/
public class PageDomain
{/** 当前记录起始索引 */private Integer pageNum;/** 每页显示记录数 */private Integer pageSize;/** 排序列 */private String orderByColumn;/** 排序的方向desc或者asc */private String isAsc = "asc";/** 分页参数合理化 */private Boolean reasonable = true;public String getOrderBy(){if (StringUtils.isEmpty(orderByColumn)){return "";}return StringUtils.toUnderScoreCase(orderByColumn) + " " + isAsc;}public Integer getPageNum(){return pageNum;}public void setPageNum(Integer pageNum){this.pageNum = pageNum;}public Integer getPageSize(){return pageSize;}public void setPageSize(Integer pageSize){this.pageSize = pageSize;}public String getOrderByColumn(){return orderByColumn;}public void setOrderByColumn(String orderByColumn){this.orderByColumn = orderByColumn;}public String getIsAsc(){return isAsc;}public void setIsAsc(String isAsc){this.isAsc = isAsc;}public Boolean getReasonable(){if (StringUtils.isNull(reasonable)){return Boolean.TRUE;}return reasonable;}public void setReasonable(Boolean reasonable){this.reasonable = reasonable;}}

TableSupport

表格数据处理

public class TableSupport{/*** 当前记录起始索引*/public static final String PAGE_NUM = "pageNum";/*** 每页显示记录数*/public static final String PAGE_SIZE = "pageSize";/*** 排序列*/public static final String ORDER_BY_COLUMN = "orderByColumn";/*** 排序的方向 "desc" 或者 "asc".*/public static final String IS_ASC = "isAsc";/*** 分页参数合理化*/public static final String REASONABLE = "reasonable";/*** 封装分页对象*/public static PageDomain getPageDomain(){PageDomain pageDomain = new PageDomain();pageDomain.setPageNum(Convert.toInt(ServletUtils.getParameter(PAGE_NUM), 1));pageDomain.setPageSize(Convert.toInt(ServletUtils.getParameter(PAGE_SIZE), 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();}
}

SqlUtil

sql操作工具类

/*** sql操作工具类* * @author ruoyi*/
public class SqlUtil
{/*** 定义常用的 sql关键字*/public static String SQL_REGEX = "and |extractvalue|updatexml|exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |or |+|user()";/*** 仅支持字母、数字、下划线、空格、逗号、小数点(支持多个字段排序)*/public static String SQL_PATTERN = "[a-zA-Z0-9_\\ \\,\\.]+";/*** 限制orderBy最大长度*/private static final int ORDER_BY_MAX_LENGTH = 500;/*** 检查字符,防止注入绕过*/public static String escapeOrderBySql(String value){if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value)){throw new UtilException("参数不符合规范,不能进行查询");}if (StringUtils.length(value) > ORDER_BY_MAX_LENGTH){throw new UtilException("参数已超过最大限制,不能进行查询");}return value;}/*** 验证 order by 语法是否符合规范*/public static boolean isValidOrderBySql(String value){return value.matches(SQL_PATTERN);}/*** SQL关键字检查*/public static void filterKeyword(String value){if (StringUtils.isEmpty(value)){return;}String[] sqlKeywords = StringUtils.split(SQL_REGEX, "\\|");for (String sqlKeyword : sqlKeywords){if (StringUtils.indexOfIgnoreCase(value, sqlKeyword) > -1){throw new UtilException("参数存在SQL注入风险");}}}
}

ServletUtils

客户端工具类

public class ServletUtils{/*** 定义移动端请求的所有可能类型*/private final static String[] agent = { "Android", "iPhone", "iPod", "iPad", "Windows Phone", "MQQBrowser" };/*** 获取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);}/*** 获取request*/public static HttpServletRequest getRequest(){return getRequestAttributes().getRequest();}/*** 获取response*/public static HttpServletResponse getResponse(){return getRequestAttributes().getResponse();}/*** 获取session*/public static HttpSession getSession(){return getRequest().getSession();}public static ServletRequestAttributes getRequestAttributes(){RequestAttributes attributes = RequestContextHolder.getRequestAttributes();return (ServletRequestAttributes) attributes;}/*** 将字符串渲染到客户端* * @param response 渲染对象* @param string 待渲染的字符串* @return null*/public static String renderString(HttpServletResponse response, String string){try{response.setContentType("application/json");response.setCharacterEncoding("utf-8");response.getWriter().print(string);}catch (IOException e){e.printStackTrace();}return null;}/*** 是否是Ajax异步请求* * @param request*/public static boolean isAjaxRequest(HttpServletRequest request){String accept = request.getHeader("accept");if (accept != null && accept.contains("application/json")){return true;}String xRequestedWith = request.getHeader("X-Requested-With");if (xRequestedWith != null && xRequestedWith.contains("XMLHttpRequest")){return true;}String uri = request.getRequestURI();if (StringUtils.inStringIgnoreCase(uri, ".json", ".xml")){return true;}String ajax = request.getParameter("__ajax");return StringUtils.inStringIgnoreCase(ajax, "json", "xml");}/*** 判断User-Agent 是不是来自于手机*/public static boolean checkAgentIsMobile(String ua){boolean flag = false;if (!ua.contains("Windows NT") || (ua.contains("Windows NT") && ua.contains("compatible; MSIE 9.0;"))){// 排除 苹果桌面系统if (!ua.contains("Windows NT") && !ua.contains("Macintosh")){for (String item : agent){if (ua.contains(item)){flag = true;break;}}}}return flag;}/*** 内容编码* * @param str 内容* @return 编码后的内容*/public static String urlEncode(String str){try{return URLEncoder.encode(str, Constants.UTF8);}catch (UnsupportedEncodingException e){return StringUtils.EMPTY;}}/*** 内容解码* * @param str 内容* @return 解码后的内容*/public static String urlDecode(String str){try{return URLDecoder.decode(str, Constants.UTF8);}catch (UnsupportedEncodingException e){return StringUtils.EMPTY;}}
}

AjaxResult操作消息提醒

/*** 操作消息提醒** @author ruoyi*/
public class AjaxResult extends HashMap<String, Object>
{private static final long serialVersionUID = 1L;/** 状态码 */public static final String CODE_TAG = "code";/** 返回内容 */public static final String MSG_TAG = "msg";/** 数据对象 */public static final String DATA_TAG = "data";/*** 状态类型*/public enum Type{/** 成功 */SUCCESS(0),/** 警告 */WARN(301),/** 错误 */ERROR(500);private final int value;Type(int value){this.value = value;}public int value(){return this.value;}}/*** 初始化一个新创建的 AjaxResult 对象,使其表示一个空消息。*/public AjaxResult(){}/*** 初始化一个新创建的 AjaxResult 对象** @param type 状态类型* @param msg 返回内容*/public AjaxResult(Type type, String msg){super.put(CODE_TAG, type.value);super.put(MSG_TAG, msg);}/*** 初始化一个新创建的 AjaxResult 对象** @param type 状态类型* @param msg 返回内容* @param data 数据对象*/public AjaxResult(Type type, String msg, Object data){super.put(CODE_TAG, type.value);super.put(MSG_TAG, msg);if (StringUtils.isNotNull(data)){super.put(DATA_TAG, data);}}/*** 返回成功消息** @return 成功消息*/public static AjaxResult success(){return AjaxResult.success("操作成功");}/*** 返回成功数据** @return 成功消息*/public static AjaxResult success(Object data){return AjaxResult.success("操作成功", data);}/*** 返回成功消息** @param msg 返回内容* @return 成功消息*/public static AjaxResult success(String msg){return AjaxResult.success(msg, null);}/*** 返回成功消息** @param msg 返回内容* @param data 数据对象* @return 成功消息*/public static AjaxResult success(String msg, Object data){return new AjaxResult(Type.SUCCESS, msg, data);}/*** 返回警告消息** @param msg 返回内容* @return 警告消息*/public static AjaxResult warn(String msg){return AjaxResult.warn(msg, null);}/*** 返回警告消息** @param msg 返回内容* @param data 数据对象* @return 警告消息*/public static AjaxResult warn(String msg, Object data){return new AjaxResult(Type.WARN, msg, data);}/*** 返回错误消息** @return*/public static AjaxResult error(){return AjaxResult.error("操作失败");}/*** 返回错误消息** @param msg 返回内容* @return 警告消息*/public static AjaxResult error(String msg){return AjaxResult.error(msg, null);}/*** 返回错误消息** @param msg 返回内容* @param data 数据对象* @return 警告消息*/public static AjaxResult error(String msg, Object data){return new AjaxResult(Type.ERROR, msg, data);}/*** 是否为成功消息** @return 结果*/public boolean isSuccess(){return Objects.equals(Type.SUCCESS.value, this.get(CODE_TAG));}/*** 是否为警告消息** @return 结果*/public boolean isWarn(){return Objects.equals(Type.WARN.value, this.get(CODE_TAG));}/*** 是否为错误消息** @return 结果*/public boolean isError(){return Objects.equals(Type.ERROR.value, this.get(CODE_TAG));}/*** 方便链式调用** @param key 键* @param value 值* @return 数据对象*/@Overridepublic AjaxResult put(String key, Object value){super.put(key, value);return this;}
}

ShiroUtils工具

shiro-core-1.12.0.jar

public class ShiroUtils{public static Subject getSubject(){return SecurityUtils.getSubject();}public static Session getSession(){return SecurityUtils.getSubject().getSession();}public static void logout(){getSubject().logout();}public static SysUser getSysUser(){SysUser user = null;Object obj = getSubject().getPrincipal();if(StringUtils.isNotNull(obj)){user = new SysUser();BeanUtils.copyBeanProp(user,obj);}return user;}public static void setSysUser(SysUser user){Subject subject = getSubject();PrincipalCollection principalCollection = subject.getPrincipals();String realmName = principalCollection.getRealmNames().iterator().next();PrincipalCollection newPrincipalCollection = new SimplePrincipalCollection(user,realmName);//重新加载Principalsubject.runAs(newPrincipalCollection);}public static Long getUserId(){return getSysUser().getUserId().longValue();}public static String getLoginName(){return getSysUser().getLoginName();}public static String getIp(){return StringUtils.substring(getSubject().getSession().getHost(), 0, 128);}public static String getSessionId(){return String.valueOf(getSubject().getSession().getId());}/**生成随机盐*/public static String randomSalt(){// 一个Byte占两个字节,此处生成的3字节,字符串长度为6SecureRandomNumberGenerator secureRandom = new SecureRandomNumberGenerator();String hex = secureRandom.nextBytes(3).toHex();return hex;}
}

StringUtils工具

/*** 字符串工具类* * @author ruoyi*/
public class StringUtils extends org.apache.commons.lang3.StringUtils
{/** 空字符串 */private static final String NULLSTR = "";/** 下划线 */private static final char SEPARATOR = '_';/*** 获取参数不为空值* * @param value defaultValue 要判断的value* @return value 返回值*/public static <T> T nvl(T value, T defaultValue){return value != null ? value : defaultValue;}/*** * 判断一个Collection是否为空, 包含List,Set,Queue* * @param coll 要判断的Collection* @return true:为空 false:非空*/public static boolean isEmpty(Collection<?> coll){return isNull(coll) || coll.isEmpty();}/*** * 判断一个Collection是否非空,包含List,Set,Queue* * @param coll 要判断的Collection* @return true:非空 false:空*/public static boolean isNotEmpty(Collection<?> coll){return !isEmpty(coll);}/*** * 判断一个对象数组是否为空* * @param objects 要判断的对象数组** @return true:为空 false:非空*/public static boolean isEmpty(Object[] objects){return isNull(objects) || (objects.length == 0);}/*** * 判断一个对象数组是否非空* * @param objects 要判断的对象数组* @return true:非空 false:空*/public static boolean isNotEmpty(Object[] objects){return !isEmpty(objects);}/*** * 判断一个Map是否为空* * @param map 要判断的Map* @return true:为空 false:非空*/public static boolean isEmpty(Map<?, ?> map){return isNull(map) || map.isEmpty();}/*** * 判断一个Map是否为空* * @param map 要判断的Map* @return true:非空 false:空*/public static boolean isNotEmpty(Map<?, ?> map){return !isEmpty(map);}/*** * 判断一个字符串是否为空串* * @param str String* @return true:为空 false:非空*/public static boolean isEmpty(String str){return isNull(str) || NULLSTR.equals(str.trim());}/*** * 判断一个字符串是否为非空串* * @param str String* @return true:非空串 false:空串*/public static boolean isNotEmpty(String str){return !isEmpty(str);}/*** * 判断一个对象是否为空* * @param object Object* @return true:为空 false:非空*/public static boolean isNull(Object object){return object == null;}/*** * 判断一个对象是否非空* * @param object Object* @return true:非空 false:空*/public static boolean isNotNull(Object object){return !isNull(object);}/*** * 判断一个对象是否是数组类型(Java基本型别的数组)* * @param object 对象* @return true:是数组 false:不是数组*/public static boolean isArray(Object object){return isNotNull(object) && object.getClass().isArray();}/*** 去空格*/public static String trim(String str){return (str == null ? "" : str.trim());}/*** 截取字符串* * @param str 字符串* @param start 开始* @return 结果*/public static String substring(final String str, int start){if (str == null){return NULLSTR;}if (start < 0){start = str.length() + start;}if (start < 0){start = 0;}if (start > str.length()){return NULLSTR;}return str.substring(start);}/*** 截取字符串* * @param str 字符串* @param start 开始* @param end 结束* @return 结果*/public static String substring(final String str, int start, int end){if (str == null){return NULLSTR;}if (end < 0){end = str.length() + end;}if (start < 0){start = str.length() + start;}if (end > str.length()){end = str.length();}if (start > end){return NULLSTR;}if (start < 0){start = 0;}if (end < 0){end = 0;}return str.substring(start, end);}/*** 格式化文本, {} 表示占位符<br>* 此方法只是简单将占位符 {} 按照顺序替换为参数<br>* 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>* 例:<br>* 通常使用:format("this is {} for {}", "a", "b") -> this is a for b<br>* 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>* 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>* * @param template 文本模板,被替换的部分用 {} 表示* @param params 参数值* @return 格式化后的文本*/public static String format(String template, Object... params){if (isEmpty(params) || isEmpty(template)){return template;}return StrFormatter.format(template, params);}/*** 是否为http(s)://开头* * @param link 链接* @return 结果*/public static boolean ishttp(String link){return StringUtils.startsWithAny(link, Constants.HTTP, Constants.HTTPS);}/*** 字符串转set* * @param str 字符串* @param sep 分隔符* @return set集合*/public static final Set<String> str2Set(String str, String sep){return new HashSet<String>(str2List(str, sep, true, false));}/*** 字符串转list* * @param str 字符串* @param sep 分隔符* @param filterBlank 过滤纯空白* @param trim 去掉首尾空白* @return list集合*/public static final List<String> str2List(String str, String sep, boolean filterBlank, boolean trim){List<String> list = new ArrayList<String>();if (StringUtils.isEmpty(str)){return list;}// 过滤空白字符串if (filterBlank && StringUtils.isBlank(str)){return list;}String[] split = str.split(sep);for (String string : split){if (filterBlank && StringUtils.isBlank(string)){continue;}if (trim){string = string.trim();}list.add(string);}return list;}/*** 判断给定的collection列表中是否包含数组array 判断给定的数组array中是否包含给定的元素value** @param collection 给定的集合* @param array 给定的数组* @return boolean 结果*/public static boolean containsAny(Collection<String> collection, String... array){if (isEmpty(collection) || isEmpty(array)){return false;}else{for (String str : array){if (collection.contains(str)){return true;}}return false;}}/*** 查找指定字符串是否包含指定字符串列表中的任意一个字符串同时串忽略大小写** @param cs 指定字符串* @param searchCharSequences 需要检查的字符串数组* @return 是否包含任意一个字符串*/public static boolean containsAnyIgnoreCase(CharSequence cs, CharSequence... searchCharSequences){if (isEmpty(cs) || isEmpty(searchCharSequences)){return false;}for (CharSequence testStr : searchCharSequences){if (containsIgnoreCase(cs, testStr)){return true;}}return false;}/*** 驼峰转下划线命名*/public static String toUnderScoreCase(String str){if (str == null){return null;}StringBuilder sb = new StringBuilder();// 前置字符是否大写boolean preCharIsUpperCase = true;// 当前字符是否大写boolean curreCharIsUpperCase = true;// 下一字符是否大写boolean nexteCharIsUpperCase = true;for (int i = 0; i < str.length(); i++){char c = str.charAt(i);if (i > 0){preCharIsUpperCase = Character.isUpperCase(str.charAt(i - 1));}else{preCharIsUpperCase = false;}curreCharIsUpperCase = Character.isUpperCase(c);if (i < (str.length() - 1)){nexteCharIsUpperCase = Character.isUpperCase(str.charAt(i + 1));}if (preCharIsUpperCase && curreCharIsUpperCase && !nexteCharIsUpperCase){sb.append(SEPARATOR);}else if ((i != 0 && !preCharIsUpperCase) && curreCharIsUpperCase){sb.append(SEPARATOR);}sb.append(Character.toLowerCase(c));}return sb.toString();}/*** 是否包含字符串* * @param str 验证字符串* @param strs 字符串组* @return 包含返回true*/public static boolean inStringIgnoreCase(String str, String... strs){if (str != null && strs != null){for (String s : strs){if (str.equalsIgnoreCase(trim(s))){return true;}}}return false;}/*** 删除最后一个字符串** @param str 输入字符串* @param spit 以什么类型结尾的* @return 截取后的字符串*/public static String lastStringDel(String str, String spit){if (!StringUtils.isEmpty(str) && str.endsWith(spit)){return str.subSequence(0, str.length() - 1).toString();}return str;}/*** 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。 例如:HELLO_WORLD->HelloWorld* * @param name 转换前的下划线大写方式命名的字符串* @return 转换后的驼峰式命名的字符串*/public static String convertToCamelCase(String name){StringBuilder result = new StringBuilder();// 快速检查if (name == null || name.isEmpty()){// 没必要转换return "";}else if (!name.contains("_")){// 不含下划线,仅将首字母大写return name.substring(0, 1).toUpperCase() + name.substring(1);}// 用下划线将原始字符串分割String[] camels = name.split("_");for (String camel : camels){// 跳过原始字符串中开头、结尾的下换线或双重下划线if (camel.isEmpty()){continue;}// 首字母大写result.append(camel.substring(0, 1).toUpperCase());result.append(camel.substring(1).toLowerCase());}return result.toString();}/*** 驼峰式命名法* 例如:user_name->userName*/public static String toCamelCase(String s){if (s == null){return null;}if (s.indexOf(SEPARATOR) == -1){return s;}s = s.toLowerCase();StringBuilder sb = new StringBuilder(s.length());boolean upperCase = false;for (int i = 0; i < s.length(); i++){char c = s.charAt(i);if (c == SEPARATOR){upperCase = true;}else if (upperCase){sb.append(Character.toUpperCase(c));upperCase = false;}else{sb.append(c);}}return sb.toString();}/*** 查找指定字符串是否匹配指定字符串列表中的任意一个字符串* * @param str 指定字符串* @param strs 需要检查的字符串数组* @return 是否匹配*/public static boolean matches(String str, List<String> strs){if (isEmpty(str) || isEmpty(strs)){return false;}for (String pattern : strs){if (isMatch(pattern, str)){return true;}}return false;}/*** 判断url是否与规则配置: * ? 表示单个字符; * * 表示一层路径内的任意字符串,不可跨层级; * ** 表示任意层路径;* * @param pattern 匹配规则* @param url 需要匹配的url* @return*/public static boolean isMatch(String pattern, String url){AntPathMatcher matcher = new AntPathMatcher();return matcher.match(pattern, url);}@SuppressWarnings("unchecked")public static <T> T cast(Object obj){return (T) obj;}/*** 数字左边补齐0,使之达到指定长度。注意,如果数字转换为字符串后,长度大于size,则只保留 最后size个字符。* * @param num 数字对象* @param size 字符串指定长度* @return 返回数字的字符串格式,该字符串为指定长度。*/public static final String padl(final Number num, final int size){return padl(num.toString(), size, '0');}/*** 字符串左补齐。如果原始字符串s长度大于size,则只保留最后size个字符。* * @param s 原始字符串* @param size 字符串指定长度* @param c 用于补齐的字符* @return 返回指定长度的字符串,由原字符串左补齐或截取得到。*/public static final String padl(final String s, final int size, final char c){final StringBuilder sb = new StringBuilder(size);if (s != null){final int len = s.length();if (s.length() <= size){for (int i = size - len; i > 0; i--){sb.append(c);}sb.append(s);}else{return s.substring(len - size, len);}}else{for (int i = size; i > 0; i--){sb.append(c);}}return sb.toString();}
}

BeanUtils工具

public class BeanUtils extends org.springframework.beans.BeanUtils{{/** * 匹配getter方法的正则表达式 */private static final Pattern GET_PATTERN = Pattern.compile("get(\\p{javaUpperCase}\\w*)");/** * 匹配setter方法的正则表达式 */private static final Pattern SET_PATTERN = Pattern.compile("set(\\p{javaUpperCase}\\w*)");/*** Bean属性复制工具方法。* * @param dest 目标对象* @param src 源对象*/public static void copyBeanProp(Object dest, Object src){try{//spring-beans-5.3.27.jarcopyProperties(src, dest);}catch (Exception e){e.printStackTrace();}}/*** 获取对象的setter方法。* * @param obj 对象* @return 对象的setter方法列表*/public static List<Method> getSetterMethods(Object obj){// setter方法列表List<Method> setterMethods = new ArrayList<Method>();// 获取所有方法Method[] methods = obj.getClass().getMethods();// 查找setter方法for (Method method : methods){Matcher m = SET_PATTERN.matcher(method.getName());if (m.matches() && (method.getParameterTypes().length == 1)){setterMethods.add(method);}}// 返回setter方法列表return setterMethods;}/*** 获取对象的getter方法。* * @param obj 对象* @return 对象的getter方法列表*/public static List<Method> getGetterMethods(Object obj){// getter方法列表List<Method> getterMethods = new ArrayList<Method>();// 获取所有方法Method[] methods = obj.getClass().getMethods();// 查找getter方法for (Method method : methods){Matcher m = GET_PATTERN.matcher(method.getName());if (m.matches() && (method.getParameterTypes().length == 0)){getterMethods.add(method);}}// 返回getter方法列表return getterMethods;}/*** 检查Bean方法名中的属性名是否相等。<br>* 如getName()和setName()属性名一样,getName()和setAge()属性名不一样。* * @param m1 方法名1* @param m2 方法名2* @return 属性名一样返回true,否则返回false*/public static boolean isMethodPropEquals(String m1, String m2){return m1.substring(BEAN_METHOD_PROP_INDEX).equals(m2.substring(BEAN_METHOD_PROP_INDEX));}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/55387.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

浅析阿里云灵积(平台)模型服务

简介&#xff1a; DashScope灵积模型服务以模型为中心&#xff0c;致力于面向AI应用开发者提供品类丰富、数量众多的模型选择&#xff0c;并为其提供开箱即用、能力卓越、成本经济的模型服务API。DashScope灵积模型服务依托达摩院等机构的优质模型&#xff0c;在阿里云基础设施…

软考高级系统架构设计师系列论文七十三:论中间件在SIM卡应用开发中的作用

软考高级系统架构设计师系列论文七十三:论中间件在SIM卡应用开发中的作用 一、中间件相关知识点二、摘要三、正文四、总结一、中间件相关知识点 软考高级系统架构设计师:构件与中间件技术二、摘要 我曾于近期参与过一个基于SIM卡应用的开发项目,并在项目中担任系统分析的工作…

Linux性能计数器

目录 一、简介二、sys_perf_event_open1、参数 struct perf_event_attr2、参数 pid3、参数 cpu4、参数 group_fd5、参数 flags6、记录信息的环形缓冲区 三、计数器(组)的启用或禁用四、示例代码 一、简介 性能计数器是在大多数现代cpu上可用的特殊硬件寄存器。这些寄存器统计特…

rke安装k8s

1、修改集群中各物理机主机名hostname文件 # 查看 cat /etc/hostname # 命令修改 hostnamectl set-hostname k8s-master2、实现主机名与ip地址解析 # 查看cat /etc/hosts # 修改 vi /etc/hosts3、配置ip_forward过滤机制 # 修改 vi /etc/sysctl.conf net.ipv4.ip_forward1…

CGY-OS 正式开源!【软件编写篇】

上一篇文章&#xff1a;CGY-OS 正式开源&#xff01;_cgy091107的博客-CSDN博客 一、软件编写基础要求 在编写CGY-OS的应用程序之前&#xff0c;您需要&#xff1a; 1. 安装python3.10&#xff0c;配置好CGY-OS。 2.掌握python3的基本语法、lambda表达式、各种简单的数据结构。…

【Python】PySpark

前言 Apache Spark是用于大规模数据&#xff08;large-scala data&#xff09;处理的统一&#xff08;unified&#xff09;分析引擎。 简单来说&#xff0c;Spark是一款分布式的计算框架&#xff0c;用于调度成百上千的服务器集群&#xff0c;计算TB、PB乃至EB级别的海量数据…

LabVIEW是如何控制硬件的?

概述 工程 师 和 科学 家 可以 使用 LabVIEW 与 数千 种 不同 的 硬件 设备 无缝 集成&#xff0c; 并 通过 方便 的 功能 和 跨 所有 硬件 的 一致 编 程 框架 帮助 节省 开发 时间。 内容 通过更简单的系统集成节省开发时间 连接到任何硬件 NI 硬件 第三方硬件 快速找到…

ubuntu18.04复现yolo v8之最终章,realsenseD435i+yolo v8完美运行

背景&#xff1a;上一篇博客我们已经为复现yolov8配置好了环境&#xff0c;如果前面的工作顺利进行&#xff0c;我们已经完成了90%&#xff08;学习类程序最难的是环境配置&#xff09;。 接下来将正式下载yolov8的相关代码&#xff0c;以及进行realsenseD435i相机yolo v8的de…

【学习FreeRTOS】第16章——FreeRTOS事件标志组

1.事件标志组简介 事件标志位&#xff1a;用一个位&#xff0c;来表示事件是否发生 事件标志组是一组事件标志位的集合&#xff0c; 可以简单的理解事件标志组&#xff0c;就是一个整数。 事件标志组的特点&#xff1a; 它的每一个位表示一个事件&#xff08;高8位不算&…

C++学习笔记总结练习:数组离散化的方法

数组离散化 1 问题描述 离散化一个序列的前提是我们只关心这个序列里面元素的相对大小&#xff0c;而不关心绝对大小&#xff08;即只关心元素在序列中的排名&#xff09;&#xff1b;离散化的目的是让原来分布零散的值聚集到一起&#xff0c;减少空间浪费。那么如何获得元素…

linux入门详解

文章目录 一、引言1.1 开发环境1.2 生产环境1.3 测试环境1.4 操作系统的选择 二、Linux介绍2.1 Linux介绍2.2 Linux的版本2.3 Linux和Windows区别 三、Linux安装3.1 安装VMware3.2 安装Xterm3.3 在VMware中安装Linux3.3.1 选择安装方式3.3.2 指定镜像方式3.3.3 选择操作系统类型…

qt创建临时文件

1、临时文件系统 在 Linux 系统中&#xff0c;创建临时文件系统很简单&#xff0c;执行如下指令即可&#xff1a; mount -t tmpfs -o size1024m tmpfs /mnt/tmp 挂载成功后&#xff0c;在 /mnt/tmp 这个挂载点下创建的所有文件都将会是临时文件, 也就是说&#xff1a;当电脑关…

《C语言编程环境搭建》工欲善其事 必先利其器

C语言编译器 GCC 系列 GNU编译器套装(英语&#xff1a;GNU Compiler Collection&#xff0c;缩写为GCC)&#xff0c;指一套编程语言编译器&#xff0c;常被认为是跨平台编译器的事实标准。原名是&#xff1a;GNU C语言编译器(GNU C Compiler)。 MinGW 又称mingw32 &#xff0c…

DevOps中的持续测试优势和工具

持续测试 DevOps中的持续测试是一种软件测试类型&#xff0c;它涉及在软件开发生命周期的每个阶段测试软件。持续测试的目标是通过早期测试和经常测试来评估持续交付过程的每一步的软件质量。 DevOps中的持续测试流程涉及开发人员、DevOps、QA和操作系统等利益相关者。 持续…

组件库的使用和自定义组件

目录 一、组件库介绍 1、什么是组件 2、组件库介绍 3、arco.design 二、组件库的使用 1、快速上手 2、主题定制 3、暗黑模式 4、语言国际化 5、业务常见问题 三、自定义组件 2、组件开发规范 3、示例实践guide-tip 4、业务组件快速托管 一、组件库介绍 1、什么是…

9个python自动化脚本,PPT批量生成缩略图、添加图片、重命名

引言 最近一番在整理资料&#xff0c;之前买的PPT资源很大很多&#xff0c;但归类并不好&#xff0c;于是一番准备把这些PPT资源重新整理一下。统计了下&#xff0c;这些PPT资源大概有2000多个&#xff0c;一共30多G&#xff0c;一个一个手动整理这个投入产出比也太低了。 作为…

openGauss学习笔记-49 openGauss 高级特性-索引推荐

文章目录 openGauss学习笔记-49 openGauss 高级特性-索引推荐49.1 单query索引推荐49.2 虚拟索引49.3 workload级别索引推荐 openGauss学习笔记-49 openGauss 高级特性-索引推荐 openGauss的索引推荐的功能&#xff0c;共包含三个子功能&#xff1a;单query索引推荐、虚拟索引…

数据结构基础:P3-树(上)----编程作业02:List Leaves

本系列文章为浙江大学陈越、何钦铭数据结构学习笔记&#xff0c;系列文章链接如下&#xff1a; 数据结构(陈越、何钦铭)学习笔记 文章目录 一、题目描述二、整体思路与实现代码 一、题目描述 题目描述&#xff1a; 给定一棵树&#xff0c;按照从上到下、从左到右的顺序列出所有…

【填坑向】MySQL常见报错及处理系列(ERROR! The server quit without updating PID file)

本系列其他文章 【填坑向】MySQL常见报错及处理系列&#xff08;Communications link failure & Access denied for user ‘root‘‘localhost‘&#xff09;_AQin1012的博客-CSDN博客翻一下大致的意思就是默认会按照如下的顺序读取配置文件&#xff0c;我上面贴出的配置文…

⛳ Docker 安装 MySQL

&#x1f38d;目录 ⛳ Docker 安装 MySQL&#x1f69c; 一、搜索 mysql , 查看版本&#x1f3a8; 二、拉取mysql镜像&#x1f463; 三、建立容器的挂载文件&#x1f9f0; 四、创建mysql配置文件&#xff0c;my.conf&#x1f3ed; 五、根据镜像产生容器&#x1f381; 六、远程连…