通过easyui的filebox上传文件

本篇文章重点分享一下怎么通过easyui的filebox实现文件上传的功能,从前端代码到后端接口都会展示给大家。

1、form表单同步上传

传统的文件上传会把<input type="file" />放到一个<form></form>里,设置form表单的提交方式为post,而且数据传输格式为multipart/form-data

<form method="post" action="/upload" enctype="multipart/form-data">请选择文件:<input type="file" name="file" /><input type="submit" value="提交" />
</form>

2、异步文件上传

以上是表单的同步提交,如果要实现异步文件上传的话,又该怎么做呢?

首先,说一下异步文件上传的基本思路:

文件上传框可以不放在<form>里,而是在<form>标签里面设置一个隐藏域,保存我们文件上传之后后端返回来的url,同时可以通过url回显图片。

本篇文章中,文件上传输入框放在了form表单里,方便通过easyui表单的validate方法验证必填项。

接下来开始步入正题,贴上前端页面的代码:

<!DOCTYPE html>
<html><head><meta charset="utf-8" /><link rel="stylesheet" href="/css/themes/icon.css"/><link rel="stylesheet" href="/css/themes/default/easyui.css" /><title>法宝管理>>法宝类型列表</title><script src="/js/public/jquery.min.js"></script><script src="/js/easyui/jquery.easyui.min.js"></script><script src="/js/easyui/easyui-lang-zh_CN.js"></script><script src="/js/public/util.js"></script><script src="/js/public/public.js"></script><script src="/js/fabao/fabao_category_list.js"></script></head><body><form id="search_form"><table style="border-spacing:5px;"><tr><td><input id="_type" /></td><td><input id="_name" /></td><td><a id="search">搜索</a></td><td><a id="clear">清空</a></td></tr></table></form><!-- 法宝类型对话框 --><div id="fabao_category_dialog" style="display:none;"><form id="fabao_category_form"><input type="hidden" id="id" name="id" /><table style="border-spacing:5px;"><tr><td>法宝名称</td><td><input id="name" name="name" /></td><td>法宝类型</td><td><input id="type" name="type" /></td></tr><tr><td>法宝信息</td><td colspan="3"><input id="note" name="note" /></td></tr></table></form></div><!-- 修改法宝图片对话框 --><div id="upload_dialog" style="display:none;"><form id="upload_form"><input type="hidden" id="categoryId" name="id" /><input type="hidden" id="image" name="image" /><table style="border-spacing:5px;"><tr><td>上传图片</td><td><input id="upload" /></td></tr><tr><td>图片预览</td><td><img id="img" height="80" /></td></tr></table></form></div><table id="fabao_category_list"></table></body>
</html>

以上是一个完整页面的HTML代码,我们只需要关注以下代码片段,其中设置了一个<input type="hidden" />用于保存文件上传的回显图片URL,当我们提交表单时,会把这个url一起提交到后台,这时候只需要完成通过ID修改图片的操作。

<div id="upload_dialog" style="display:none;"><form id="upload_form"><input type="hidden" id="categoryId" name="id" /><input type="hidden" id="image" name="image" /><table style="border-spacing:5px;"><tr><td>上传图片</td><td><input id="upload" /></td></tr><tr><td>图片预览</td><td><img id="img" height="80" /></td></tr></table></form>
</div>

页面的js代码如下:(注意:这里的datagrid的ajax请求方式默认是get,博主修改了easyui.min.js,并把默认方式改成了post)

let requestUrl;
let types = ["主动法宝", "被动法宝"];function addHandler() {requestUrl = "/fabao_category/insert";$("#fabao_category_dialog").dialog("open");
}function editHandler() {let rowData = $("#fabao_category_list").datagrid("getSelected");if (rowData) {requestUrl = "/fabao_category/updateById";$("#id").val(rowData.id);$("#name").textbox("setValue", rowData.name);$("#type").combobox("setValue", rowData.type);$("#note").textbox("setValue", rowData.note);$("#fabao_category_dialog").dialog("open");} else {alertMsg("请选择要修改的记录!", "warning");}
}function imageHandler() {let rowData = $("#fabao_category_list").datagrid("getSelected");if (rowData) {requestUrl = "/fabao_category/updateById";$("#categoryId").val(rowData.id);$("#image").val(rowData.image);$("#img").attr("src", rowData.image);$("#upload_dialog").dialog("open");} else {alertMsg("请选择要修改的记录!", "warning");}
}$(document).ready(function() {$("#_type").combobox({width: 150,prompt: "法宝类型",panelHeight: "auto",data: getJsonData(types)});$("#_name").textbox({prompt: "请输入法宝名称"});// 搜索按钮$("#search").linkbutton({iconCls: "icon-search"}).click(function() {let type = $("#_type").combobox("getValue");let name = $("#_name").textbox("getValue");$("#fabao_category_list").datagrid("load", {type: type,name: name});});$("#clear").linkbutton({iconCls: "icon-delete"}).click(function() {$("#search_form").form("clear");});$("#name").textbox({width: 120,required: true});$("#type").combobox({width: 120,required: true,panelHeight: "auto",data: getJsonData(types)});$("#note").textbox({width: 314,height: 80,required: true,multiline: true});$("#fabao_category_dialog").dialog({title: "法宝信息",modal: true,closed: true,closable: false,draggable: false,buttons: [{iconCls: "icon-save",text: "保存",handler: function() {let selector = "#fabao_category_form";checkForm(selector, function () {let data = $(selector).serialize();post(requestUrl, data, function(response) {showMsg(response.message);$(selector).form("clear");$("#fabao_category_dialog").dialog("close");$("#fabao_category_list").datagrid("reload");}, error);});}}, {iconCls: "icon-cancel",text: "取消",handler: function() {$("#fabao_category_dialog").dialog("close");$("#fabao_category_form").form("clear");}}]});// 文件上传框$("#upload").filebox({buttonText: "选择文件",width: 200,required: true,onChange: function() {fileUpload(this, "/fabao_category/upload");}});// 上传图片对话框$("#upload_dialog").dialog({title: "法宝图片",modal: true,closed: true,closable: false,draggable: false,buttons: [{iconCls: "icon-save",text: "保存",handler: function() {let selector = "#upload_form";checkForm(selector, function () {let data = $(selector).serialize();post(requestUrl, data, function(response) {showMsg(response.message);resetValue("#upload");$(selector).form("clear");$("#upload_dialog").dialog("close");$("#fabao_category_list").datagrid("reload");}, error);});}}, {iconCls: "icon-cancel",text: "取消",handler: function() {resetValue("#upload");$("#upload_form").form("clear");$("#upload_dialog").dialog("close");}}]});// 法宝类型数据列表$("#fabao_category_list").datagrid({url: "/fabao_category/selectByPage",striped: true,fitColumns: true,singleSelect: true,height: table_height,pagination: true,pageList: pageList,pageSize: pageList[0],loadFilter: function(result){if (result.code === 200){return result.data;} else {return null;}},toolbar: [{iconCls: "icon-add",text: "添加",handler: function() {addHandler()}}, "-", {iconCls: "icon-edit",text: "修改",handler: function() {editHandler();}}, "-", {iconCls: "icon-image",text: "图片",handler: function() {imageHandler();}}],columns: [[{field: "id", title: "编号", align: "center"},{field: "name", title: "法宝名称", align: "center", width: 100},{field: "type", title: "类型", align: "center", width: 100,formatter: function(value) {return "<div>" + types[value] + "</div>";}},{field: "image", title: "图片", align: "center", width: 40, formatter: function(value) {return "<img height='" + size + "' src='" + value + "' />";}},{field: "note", title: "法宝信息", align: "center", width: 400,formatter: function(value) {return "<div class='ell'>" + value + "</div>";}}]]});});

重点看以下代码片段

let requestUrl;function imageHandler() {let rowData = $("#fabao_category_list").datagrid("getSelected");if (rowData) {requestUrl = "/fabao_category/updateById";$("#categoryId").val(rowData.id);$("#image").val(rowData.image);$("#img").attr("src", rowData.image);$("#upload_dialog").dialog("open");} else {alertMsg("请选择要修改的记录!", "warning");}
}$(document).ready(function() {$("#upload").filebox({buttonText: "选择文件",width: 200,required: true,onChange: function() {fileUpload(this, "/fabao_category/upload");}});$("#upload_dialog").dialog({title: "法宝图片",modal: true,closed: true,closable: false,draggable: false,buttons: [{iconCls: "icon-save",text: "保存",handler: function() {let selector = "#upload_form";checkForm(selector, function () {let data = $(selector).serialize();post(requestUrl, data, function(response) {showMsg(response.message);resetValue("#upload");$(selector).form("clear");$("#upload_dialog").dialog("close");$("#fabao_category_list").datagrid("reload");}, error);});}}, {iconCls: "icon-cancel",text: "取消",handler: function() {$("#upload_form").form("clear");$("#upload_dialog").dialog("close");}}]});});

当我们选中某行数据时,点击【图片】按钮,就会打开我们的文件上传的对话框,同时如果这行记录本来的图片不为空,也会显示出来,并且设置隐藏域<input id="image" />的value为该记录的image值。

效果图片大概是这样

当我们点击上传文件后面的选择框并选择图片上传时,会提交post请求到接口"/fabao_category/upload",完成文件的上传,上传成功后会返回文件的相对路径,然后重新设置图片预览后面的的图片的src属性为返回的URL。

当我们点击保存按钮时,会通过ajax的post请求的方式提交表单数据到我们的"/fabao_category/updateById"接口,就是修改法宝类型信息的接口。数据修改成功之后会刷新表格数据。

$("#fabao_category_list").datagrid("reload");

 js文件里的多个方法来自于util.js

let wkf = "该功能暂未开放,敬请期待~";
let base = "http://localhost:9091/api/mhxysy";
base = "";/*** 封装的ajax get请求* @param url 请求url* @param params 请求参数* @param success 成功回调函数* @param error 失败回调函数* @param async 是否异步*/
function get(url, params, success, error, async = true) {$.ajax({type: "GET",url: base + url,data: params,cache: false,async: async,dataType: "json",processData: true,success: success,error: error});
}/*** 封装的ajax post请求* @param url 请求url* @param params 请求参数* @param success 成功回调函数* @param error 失败回调函数* @param async 是否异步*/
function post(url, params, success, error, async = true) {$.ajax({type: "POST",url: base + url,data: params,async: async,cache: false,dataType: "json",processData: true,success: success,error: error});
}/*** Ajax POST请求* @param url 请求路径* @param data 请求参数* @param success 成功回调* @param error 失败回调*/
function ajaxPost(url, data, success, error) {$.ajax({url: base + url,data: data,cache: false,async: true,type: "POST",dataType: "json",processData: false,contentType: false,success: success,error: error});
}let error = (res) => {console.log(res);if (res && res.responseJSON) {let response = res.responseJSON;if (res.status && res.status === 404) {let message;if(response.path) {message = "路径" + response.path + "不存在。";} else {message = response.message;}alertMsg(message, "error");} else {alertMsg(response.message, "error");}}
}/*** 右下角弹出消息提示* @param message 提示消息* @param type 消息类型*/
function showMsg(message, type = "slide") {$.messager.show({title: "消息",msg: message,timeout: 3000,showType: type});
}/** 弹出提示* @param message 提示消息* @param type 提示类型:warning/error/info/question*/
function alertMsg(message, type = "info") {$.messager.alert("提示", message, type);
}/*** 重置文件上传组件的值* @param selector 组件的选择器*/
function resetValue(selector) {$(selector).filebox("initValue", null);
}/*** 功能未开放*/
function unopen() {alertMsg(wkf);
}function unselected() {alertMsg("请选择一条记录!", "warning");
}function fileUpload(_obj, url) {let file = $(_obj).context.ownerDocument.activeElement.files[0];let form = new FormData();form.append("file", file);ajaxPost(url, form, function (result) {let image = result.data;$("#image").val(image);$("#img").attr("src", image);}, error);
}/*** 验证表单* @param selector 选择器* @param func 表单验证通过后执行的操作*/
function checkForm(selector, func) {let $form = $(selector);let bool = $form.form("validate");if (bool) {func();} else {alertMsg("请填写正确的表单项", "warning");}
}/*** 根据数组获取json格式的数据* @param arr*/
function getJsonData(arr) {let jsonData = [];for (let i = 0; i < arr.length; i++) {let elem = {"value": i + "", "text": arr[i]};jsonData.push(elem);}return jsonData;
}/*** 初始化easyui数据列表datagrid* @param selector 选择器* @param url 加载数据的URL* @param toolbar 头部工具栏* @param columns 表格的列* @param height 表格高度* @param pageList 分页参数* @param rownumbers 是否显示行号*/
function asDatalist(selector, url, toolbar, columns, height = 432, pageList = [10, 20, 50, 100], rownumbers = false) {$(selector).datagrid({url: url,striped: true,height: height,fitColumns: true,singleSelect: true,rownumbers: rownumbers,pagination: true,pageList: pageList,pageSize: pageList[0],loadFilter: function(result){if (result.code === 200){return result.data;} else {return null;}},toolbar: toolbar,columns: columns});
}

接下来看一下后端的接口怎么写的:

FabaoCategoryController.java

package cn.edu.sgu.www.mhxysy.controller.fabao;import cn.edu.sgu.www.mhxysy.restful.JsonResult;
import cn.edu.sgu.www.mhxysy.restful.PageResult;
import cn.edu.sgu.www.mhxysy.entity.fabao.FabaoCategory;
import cn.edu.sgu.www.mhxysy.pager.fabao.FabaoCategoryPager;
import cn.edu.sgu.www.mhxysy.service.fabao.FabaoCategoryService;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;import java.io.IOException;
import java.util.List;@RestController
@Api(tags = "法宝类型控制器类")
@RequestMapping(path = "/fabao_category", produces="application/json; charset=utf-8")
public class FabaoCategoryController {private final FabaoCategoryService service;@Autowiredpublic FabaoCategoryController(FabaoCategoryService service) {this.service = service;}@ApiOperation("添加法宝类型")@RequestMapping(value = "/insert", method = RequestMethod.POST)public JsonResult<Void> insert(FabaoCategory category) {service.insert(category);return JsonResult.success("添加成功");}@ApiOperation("通过id修改法宝类型信息")@RequestMapping(value = "/updateById", method = RequestMethod.POST)public JsonResult<Void> updateById(FabaoCategory category) {service.updateById(category);return JsonResult.success("修改成功");}@ApiOperation("查询全部法宝类型")@RequestMapping(value = "/selectAll", method = RequestMethod.GET)public List<FabaoCategory> selectAll() {return service.selectAll();}@ApiOperation("通过id查询法宝类型信息")@RequestMapping(value = "/selectById", method = RequestMethod.GET)public FabaoCategory selectById(@RequestParam Integer id) {return service.selectById(id);}@ApiOperation("分页查询法宝类型列表")@RequestMapping(value = "/selectByPage", method = RequestMethod.POST)public JsonResult<PageResult<FabaoCategory>> selectByPage(FabaoCategoryPager pager) {Page<FabaoCategory> result = service.selectByPage(pager);return JsonResult.restPage(result);}@ApiOperation("上传图片")@RequestMapping(value = "/upload", method = RequestMethod.POST)public JsonResult<String> upload(MultipartFile file) throws IOException {String url = service.upload(file);return JsonResult.success(null, url);}}

 FabaoCategoryServiceImpl.java

package cn.edu.sgu.www.mhxysy.service.fabao.impl;import cn.edu.sgu.www.mhxysy.util.StringUtils;
import cn.edu.sgu.www.mhxysy.base.Pager;
import cn.edu.sgu.www.mhxysy.consts.DirectoryConsts;
import cn.edu.sgu.www.mhxysy.entity.fabao.FabaoCategory;
import cn.edu.sgu.www.mhxysy.mapper.fabao.FabaoCategoryMapper;
import cn.edu.sgu.www.mhxysy.pager.fabao.FabaoCategoryPager;
import cn.edu.sgu.www.mhxysy.service.fabao.FabaoCategoryService;
import cn.edu.sgu.www.mhxysy.util.UploadUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;import java.io.IOException;
import java.util.List;/*** @author heyunlin* @version 1.0*/
@Service
public class FabaoCategoryServiceImpl implements FabaoCategoryService {private final UploadUtils uploadUtils;private final FabaoCategoryMapper mapper;@Autowiredpublic FabaoCategoryServiceImpl(UploadUtils uploadUtils, FabaoCategoryMapper mapper) {this.uploadUtils = uploadUtils;this.mapper = mapper;}@Overridepublic void insert(FabaoCategory category) {mapper.insert(category);}@Overridepublic void updateById(FabaoCategory category) {mapper.updateById(category);}@Overridepublic List<FabaoCategory> selectAll() {return mapper.selectList(null);}@Overridepublic FabaoCategory selectById(Integer id) {return mapper.selectById(id);}@Overridepublic Page<FabaoCategory> selectByPage(FabaoCategoryPager pager) {QueryWrapper<FabaoCategory> wrapper = new QueryWrapper<>();Page<FabaoCategory> page = Pager.ofPage(pager);wrapper.eq(pager.getType() != null,"type", pager.getType());wrapper.like(StringUtils.isNotEmpty(pager.getName()),"name", pager.getName());return mapper.selectPage(page, wrapper);}@Overridepublic String upload(MultipartFile file) throws IOException {String directory = DirectoryConsts.DIRECTORY_FABAO;return uploadUtils.upload(file, directory);}}

DirectoryConsts.java

DirectoryConsts就是一个存放常量的接口,保存项目用到的文件上传的相对路径

package cn.edu.sgu.www.mhxysy.consts;/*** 常量工具类* 定义了项目用到的文件上传路径相对根路径root的文件夹*/
public interface DirectoryConsts {/*** 角色图片上传文件夹*/String DIRECTORY_ROLE = "/role/head";/*** 烹饪图片上传文件夹*/String DIRECTORY_CUISINE = "/cuisine";/*** 药品图片上传文件夹*/String DIRECTORY_MEDICINE = "/medicine";/*** 角色日常记录图片上传文件夹*/String DIRECTORY_DAILY_RECORD = "/daily_record";/*** 角色时装图片上传文件夹*/String DIRECTORY_ROLE_SHIZHUANG = "/role_shizhuang";/*** 特技图片上传文件夹*/String DIRECTORY_TETJ = "/teji";/*** 法宝图片上传文件夹*/String DIRECTORY_FABAO = "/fabao";/*** 坐骑图片上传文件夹*/String DIRECTORY_ZUOQI = "/zuoqi";/*** 门派图片上传文件夹*/String DIRECTORY_SCHOOL = "/school";/*** 门派法宝图片上传文件夹*/String DIRECTORY_SCHOOL_FABAO = "/school_fabao";/*** 器灵图片上传文件夹*/String DIRECTORY_QILING = "/qiling";/*** 宠物图片上传文件夹*/String DIRECTORY_CHONGWU = "/chongwu";/*** 助战图片上传文件夹*/String DIRECTORY_PARTNER = "/partner";/*** 助战图片上传文件夹*/String DIRECTORY_PARTNER_SKILL = "/partner_skill";/*** 装备图片上传文件夹*/String DIRECTORY_EQUIPMENT = "/equipment";/*** 修炼技能图片上传文件夹*/String DIRECTORY_XIULIAN = "/xiulian";/*** 变身卡图片上传文件夹*/String DIRECTORY_BIANSHENKA = "/bianshenka";/*** 坐骑技能图片上传文件夹*/String DIRECTORY_ZUOQI_SKILL = "/zuoqi_skill";/*** 门派技能图片上传文件夹*/String DIRECTORY_SCHOOL_SKILL = "/school_skill";/*** 宠物技能图片上传文件夹*/String DIRECTORY_CHONGWU_SKILL = "/chongwu_skill";/*** 宠物内丹图片上传文件夹*/String DIRECTORY_CHONGWU_NEIDAN = "/chongwu_neidan";/*** 宠物套装技能图片上传文件夹*/String DIRECTORY_CHONGWU_TAOZHUANG = "/chongwu_taozhuang";/*** 宠物专属内丹图片上传文件夹*/String DIRECTORY_ZHUANSHUNEIDAN = "/zhuanshu_neidan";/*** 器灵套装图片上传文件夹*/String DIRECTORY_QILING_TAOZHUANG = "/qiling_taozhuang";/*** 宠物装备图片上传文件夹*/String DIRECTORY_CHONGWU_EQUIPMENT = "/chongwu_equipment";/*** 器灵套装图片上传文件夹*/String DIRECTORY_QILING_TAOZHUANG_IMAGE = "/qiling_taozhuang_image";/*** 星印图片上传文件夹*/String DIRECTORY_XINGYIN = "/xingyin";/*** 星印图片上传文件夹*/String DIRECTORY_XINGYIN_SKILL = "/xingyin_skill";/*** 星印特效图片上传文件夹*/String DIRECTORY_XINGYIN_TEXIAO = "/xingyin_texiao";/*** 装备制造书图片上传文件夹*/String DIRECTORY_FORGE_BOOK = "/forge_book";
}

UploadUtils.java

UploadUtils是文件上传工具类,定义为组件,因为要读取配置文件

package cn.edu.sgu.www.mhxysy.util;import cn.edu.sgu.www.mhxysy.restful.ResponseCode;
import cn.edu.sgu.www.mhxysy.exception.GlobalException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;import java.io.File;
import java.io.IOException;/*** 文件上传工具类* @author heyunlin* @version 1.0*/
@Component
public class UploadUtils {/*** 文件上传根路径*/@Value("${uploads.path}")private String root;public String getRoot() {return root;}/*** 图片上传* @param file MultipartFile对象* @param directory 文件上传目录* @return JsonResult<String>*/public String upload(MultipartFile file, String directory) throws IOException {boolean result = check(file);if (result) {// 获取文件名String fileName = StringUtils.getFileName(file);// 创建目标对象File targetFile = new File(root + directory, fileName);// 保存文件file.transferTo(targetFile);return directory + "/" + fileName;}return null;}/*** 检查文件格式* @param file MultipartFile*/private boolean check(MultipartFile file) {if (file == null) {throw new GlobalException(ResponseCode.BAD_REQUEST, "您未上传任何图片!");}String filename = file.getOriginalFilename();if (StringUtils.isNotEmpty(filename)) {String fileType = StringUtils.getFileType(filename).toLowerCase();// 图片文件名后缀String picPrefix = ".webp,.jpeg,.jpg,.png";if (!picPrefix.contains(fileType)) {throw new GlobalException(ResponseCode.BAD_REQUEST, "只允许上传格式为" + picPrefix + "的图片");}return true;} else {throw new GlobalException(ResponseCode.BAD_REQUEST, "获取上传的文件名失败~");}}}

StringUtils.java

这是字符串工具类,封装常用的字符串相关方法

package cn.edu.sgu.www.mhxysy.util;import org.springframework.web.multipart.MultipartFile;import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;/*** String工具类* @author heyunlin* @version 1.0*/
public class StringUtils {/*** 判断字符串是否为null或""* 字符串为""或null返回true,否则返回false* @param str 要判断的字符串* @return boolean*/public static boolean isEmpty(String str) {return str == null || str.isEmpty() || isBlank(str);}/*** 判断字符串是否为""或null* 字符串为""或null返回false,否则返回true* @param str 要判断的字符串* @return boolean*/public static boolean isNotEmpty(String str) {return !isEmpty(str);}/*** 判断字符串是否为空白字符* 字符串为空白字符返回true,否则返回false* @param str 要判断的字符串* @return boolean*/public static boolean isBlank(String str) {return str.trim().length() == 0;}/*** 判断字符串是否不是空白字符* 字符串不是空白字符返回true,否则返回false* @param str 要判断的字符串* @return boolean*/public static boolean isNotBlank(String str) {return !isBlank(str);}/*** 判断字符串是否为null或""* 字符串为""或null返回true,否则返回false* @param str 要判断的字符串* @return boolean*/public static boolean isNullOrEmpty(String str) {return str == null || str.isEmpty();}/*** 检查字符串是否包含空白字符* 如果不包含空格返回true,否则返回false* @param str 需要比较的字符串* @return boolean*/public static boolean check(String str) {// 去除空白字符后字符串的长度int realLength = str.replaceAll("\\s", "").length();// 字符串原来的长度int originalLength = str.length();return realLength == originalLength;}/*** 根据当前时间生成UUID* @return String*/public static String uuid() {DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");LocalDateTime localDate = LocalDateTime.now();return localDate.format(formatter);}/*** 通过文件名获取文件类型* @param fileName 文件名*/public static String getFileType(String fileName) {// 得到文件名中最后一次出现"."的位置int index = fileName.lastIndexOf('.');// 文件类型统一转换为小写return fileName.substring(index).toLowerCase();}/*** 获取文件名* @param filename String* @return String 由当前时间生成的新文件名*/public static String getFileName(String filename) {// 返回uuid.文件类型,如:20220618131456.jpgreturn uuid() + getFileType(filename);}/*** 获取文件名* @param file MultipartFile对象* @return String 由当前时间生成的新文件名*/public static String getFileName(MultipartFile file) {// 得到上传文件的原始文件名String filename = file.getOriginalFilename();// 判断文件名是否为空if (isNullOrEmpty(filename)) {throw new RuntimeException("获取文件名失败!");}// 返回uuid.文件类型,如:20220618131456.jpgreturn uuid() + getFileType(filename);}/*** 驼峰命名转下划线命名* @param str 待转换的字符串* @return String*/public static String toLowerCase(String str) {// 小写和大写紧挨一起的地方加上分隔符_,然后全部转为小写str = str.replaceAll("([a-z])([A-Z])", "$1_$2");return str.toLowerCase();}/*** 下划线命名转驼峰命名* @param str 待转换的字符串* @return String*/private static String toUpperCase(String str) {// 将下划线替换为空格StringBuilder under= new StringBuilder();str = str.toLowerCase().replace("_", " ");// 将字符串根据空格分割成数组String[] array = str.split(" ");// 将每个单词首字母大写for (String s : array) {String letter = s.substring(0, 1).toUpperCase() + s.substring(1);under.append(letter);}return under.toString();}}

 最后是统一自定义异常GlobalException

package cn.edu.sgu.www.mhxysy.exception;import cn.edu.sgu.www.mhxysy.restful.ResponseCode;
import lombok.Data;
import lombok.EqualsAndHashCode;/*** 自定义异常* @author heyunlin* @version 1.0*/
@Data
@EqualsAndHashCode(callSuper = true)
public class GlobalException extends RuntimeException {private ResponseCode responseCode;public GlobalException(ResponseCode responseCode, String message) {super(message);setResponseCode(responseCode);}}

配合全局异常处理类,就可以在项目运行过程时发生异常主动捕获,并调用对应的异常处理方法返回响应对象

package cn.edu.sgu.www.mhxysy.exception.handler;import cn.edu.sgu.www.mhxysy.restful.JsonResult;
import cn.edu.sgu.www.mhxysy.restful.ResponseCode;
import cn.edu.sgu.www.mhxysy.exception.GlobalException;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;import javax.servlet.http.HttpServletResponse;/*** 全局异常处理类* @author heyunlin* @version 1.0*/
@RestControllerAdvice
public class GlobalExceptionHandler {/*** 处理GlobalException* @param e GlobalException* @return JsonResult<Void>*/@ExceptionHandler(GlobalException.class)public JsonResult<Void> handlerGlobalException(HttpServletResponse response, GlobalException e) {System.err.println(e.getMessage());e.printStackTrace();response.setStatus(e.getResponseCode().getValue());return JsonResult.error(e.getResponseCode(), e);}/*** 处理BindException* @param e BindException* @return JsonResult<Void>*/@ExceptionHandler(BindException.class)@ResponseStatus(HttpStatus.BAD_REQUEST)public JsonResult<Void> handlerBindException(BindException e) {e.printStackTrace();BindingResult bindingResult = e.getBindingResult();FieldError fieldError = bindingResult.getFieldError();assert fieldError != null;String defaultMessage = fieldError.getDefaultMessage();return JsonResult.error(ResponseCode.BAD_REQUEST, defaultMessage);}/*** 处理Exception* @param e Exception* @return JsonResult<Void>*/@ExceptionHandler(Exception.class)@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)public JsonResult<Void> handlerException(Exception e) {e.printStackTrace();return JsonResult.error(ResponseCode.ERROR, e);}}

整个项目的结构如下

 好了,这篇文章就分享到这里了,如果文章对你有所帮助,不要忘了点赞+收藏哦~

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

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

相关文章

MySQL8.0版本在CentOS系统的配置教程

1.MySQL安装 MySQL安装完成后&#xff0c;会自动配置为名称叫做&#xff1a;mysqld的服务&#xff0c;可以被systemctl所管理&#xff0c;我们在进行系统的配置时&#xff0c;主要修改root密码和允许root远程登录。 # 通过grep命令&#xff0c;在/var/log/mysqld.log文件中&a…

【人工智能】— 深度神经网络、卷积神经网络(CNN)、多卷积核、全连接、池化

【人工智能】— 深度神经网络、卷积神经网络&#xff08;CNN&#xff09;、多卷积核、全连接、池化 深度神经网络训练训练深度神经网络参数共享 卷积神经网络&#xff08;CNN&#xff09;卷积多卷积核卷积全连接最大池化卷积池化拉平向量激活函数优化小结 深度神经网络训练 Pr…

浅谈智能安全用电系统在轨道交通中的应用

安科瑞 华楠 摘要&#xff1a; 随着轨道交通电气设备的增加和用电负荷的变大&#xff0c;用电安全问题愈发突出&#xff0c;而对电力状况在线监测和故障预警是实现安全用电的关键。本文研究了轨道交通安全用电智能监测系统。该系统通过电力载波技术可利用原电缆进行数据传输&am…

面向开发人员的 ChatGPT 提示词教程中文版 - ChatGPT 版

面向开发人员的 ChatGPT 提示词教程中文版 - ChatGPT 版 1. 指南1-1. 提示的指南1-2. 配置1-3. 提示语原则原则 1: 写出清晰而具体的指示技巧 1: 使用分隔符来清楚地表明输入的不同部分技巧 2: 要求提供结构化的输出技巧 3: 要求模型检查条件是否得到满足技巧 4: "少许样本…

初学帆软踩得坑——数据填报_Excel数据导入

第一次做数据填报&#xff0c;按照教程做完在用excel导入工具本地数据报表的时候出现 1、整块空白合并单元格&#xff0c;数据无法填入的现象 2、表格重新导入一批&#xff0c;无法成功入库&#xff0c;导致只能导入一次&#xff0c;如下图&#xff1a; 说明&#xff1a;点击…

云原生时代数据治理的变革与创新

随着数字化进程的深入&#xff0c;企业对数据的依赖日益加深&#xff0c;数据资源的重要性愈发凸显。如何管好、用好数据&#xff0c;做好数据治理工作&#xff0c;发挥数据资源价值&#xff0c;成为企业提质增效过程中的重要议题。 在本次直播中&#xff0c;我们介绍了数据治…

如何在矩池云复现开源对话语言模型 ChatGLM

ChatGLM-6B 是一个开源的、支持中英双语的对话语言模型&#xff0c;基于 General Language Model (GLM) 架构&#xff0c;具有 62 亿参数。结合模型量化技术&#xff0c;用户可以在消费级的显卡上进行本地部署&#xff08;INT4 量化级别下最低只需 6GB 显存&#xff09;。 Chat…

python GUI工具之PyQt5模块,pyCharm 配置PyQt5可视化窗口

https://doc.qt.io/qt-5/qtwidgets-module.html https://doc.qt.io/qt-5/qt.html#AlignmentFlag-enum 一、简介 PyQt是Qt框架的Python语言实现&#xff0c;由Riverbank Computing开发&#xff0c;是最强大的GUI库之一。PyQt提供了一个设计良好的窗口控件集合&#xff0c;每一…

物联网应用中的 Wi-Fi 6

近年来&#xff0c;设备智联在我们的日常生活中越来越常见。从智能家居设备到工业自动化系统&#xff0c;物联网技术正在改变我们与世界交互的方式。随着物联网设备的不断增多&#xff0c;对可靠、高容量和低功耗无线连接的需求变得尤为迫切。这就是 Wi-Fi 6&#xff08;即 802…

八、云尚办公系统-管理端-审批设置

云尚办公系统&#xff1a;管理端-审批设置 B站直达【为尚硅谷点赞】: https://www.bilibili.com/video/BV1Ya411S7aT 本博文以课程相关为主发布&#xff0c;并且融入了自己的一些看法以及对学习过程中遇见的问题给出相关的解决方法。一起学习一起进步&#xff01;&#xff01;…

【前端工程化】深入浅出vite(一)--vite的优点及原理、性能优化

Vite 需要 Node.js 版本 14.18&#xff0c;16。然而&#xff0c;有些模板需要依赖更高的 Node 版本才能正常运行&#xff0c;当你的包管理器发出警告时&#xff0c;请注意升级你的 Node 版本。 背景 webpack支持多种模块化&#xff0c;将不同模块的依赖关系构建成依赖图来进行…

解决IDEA连接数据库后,xml中写SQL语句不提醒数据库表字段问题

有时候我们新建了一个项目&#xff0c;或者新建了一个工程&#xff0c;明明为此项目或者工程连接了数据库&#xff0c;并且一切正确&#xff0c;但是在xml中书写SQL语句就是不提示数据库表中的相关字段&#xff0c;无论是表名也好&#xff0c;还是字段名也好&#xff0c;通通不…