SpirngBoot + Vue 前后端分离开发工具代码

在这里插入图片描述

✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉
🍎个人主页:Leo的博客
💞当前专栏: Java从入门到精通
✨特色专栏: MySQL学习
🥭本文内容:SpirngBoot + Vue 前后端分离开发工具代码
🖥️个人小站 :个人博客,欢迎大家访问
📚个人知识库: Leo知识库,欢迎大家访问

1.MybatisPlus配置类

导入依赖

<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
package com.jerry.common.config.mp;import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** ClassName: MybatisPlusConfig* Package: com.jerry.common.config.mp* Description:** @Author gaoziman* @Create 2023-03-01 11:17* @Version 1.0*/@Configuration
@MapperScan("com.jerry.auth.mapper")
public class MybatisPlusConfig {/*** 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除)*/@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));return interceptor;}@Beanpublic ConfigurationCustomizer configurationCustomizer() {return configuration -> configuration.setUseDeprecatedExecutor(false);}			
}	

2.使用mybatisplus分页查询

第一种

    /*** 条件分页查询** @param page           当前页* @param pageSize       分页大小* @param sysRoleQueryVo 条件查询对象* @return*/@ApiOperation("条件分页查询")@GetMapping("{page}/{pageSize}")private Result page(@PathVariable int page, @PathVariable int pageSize, SysRoleQueryVo sysRoleQueryVo) {// 1、创建 page 对象, 传递分页查询的参数Page<SysRole> sysRolePage = new Page<>(page, pageSize);// 2、构造分页查询条件, 判断条件是否为空,不为空进行封装LambdaQueryWrapper<SysRole> lambdaQueryWrapper = new LambdaQueryWrapper<>();String roleName = sysRoleQueryVo.getRoleName();if (!StringUtils.isEmpty(roleName)) {// 封装lambdaQueryWrapper.like(SysRole::getRoleName,roleName);}// 3、调用方法实现分页查询sysRoleService.page(sysRolePage, lambdaQueryWrapper);return Result.ok(sysRolePage);}

第二种

 @PreAuthorize("hasAuthority('bnt.sysUser.list')")@ApiOperation("条件分页查询")@GetMapping("/page/{pageNum}/{pageSize}")public Result pageQueryUser(@PathVariable Long pageNum,@PathVariable Long pageSize,SysUserQueryVo sysUserQueryVo) {//1 创建Page对象,传递分页相关参数//page 当前页  limit 每页显示记录数Page<SysUser> pageParam = new Page<>(pageNum,pageSize);//2 调用service方法IPage<SysUser>  page =  userService.selectByPage(pageParam,sysUserQueryVo);return Result.success(page);}
<select id="selectByPage" resultMap="sysUserMap">SELECT * FROM  sys_user<where><if test="vo.keyword != '' and vo.keyword != null ">and (username like CONCAT('%',#{vo.keyword},'%')or name like CONCAT('%',#{vo.keyword},'%')or phone like CONCAT('%',#{vo.keyword},'%'))</if><if test="vo.createTimeBegin != null and vo.createTimeBegin !=''">and create_time >= #{vo.createTimeBegin}</if><if test="vo.createTimeEnd !=null and vo.createTimeEnd !=''">and create_time &lt;=#{vo.createTimeEnd}</if>and is_deleted = 0</where></select>

3.统一返回的结果

package com.trs.common.result;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;/*** 公共返回对象** @author gaoziman* @date 2022/8/7*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result {/*** 状态码*/private Integer code;/*** 提示信息*/private String message;/*** 返回对象*/private Object data;/*** 成功返回结果** @param resultCodeEnum 提示信息* @return 返回成功*/public static Result success(ResultCodeEnum resultCodeEnum) {return new Result(resultCodeEnum.getCode(), resultCodeEnum.getMessage(), null);}/*** 成功返回结果** @param resultCodeEnum 提示信息* @param data 返回数据* @return 返回成功*/public static Result success(ResultCodeEnum resultCodeEnum, Object data) {return new Result(resultCodeEnum.getCode(), resultCodeEnum.getMessage(), data);}/*** 失败返回结果** @param resultCodeEnum 提示信息* @return 返回失败*/public static Result error(ResultCodeEnum resultCodeEnum) {return new Result(resultCodeEnum.getCode(), resultCodeEnum.getMessage(), null);}/*** 失败返回结果** @param message 提示信息* @return 返回失败*/public static Result error(String message) {return new Result(500, message, null);}/*** 失败返回结果** @param resultCodeEnum 提示信息* @param data 返回数据* @return 返回失败*/public static Result error(ResultCodeEnum resultCodeEnum, Object data) {return new Result(resultCodeEnum.getCode(), resultCodeEnum.getMessage(), data);}/*** 失败返回结果** @param message 提示信息* @return 返回失败*/public static Result error(ResultCodeEnum resultCodeEnum, String message) {return new Result(resultCodeEnum.getCode(), resultCodeEnum.getMessage(), null);}/*** 失败返回结果** @param code 状态码* @param message 提示信息* @return 返回失败*/public static Result error(Integer code, String message) {return new Result(code, message, null);}
}
package com.trs.common.result;import lombok.Getter;/*** 统一返回结果状态信息类** @author 高自满*/
@Getter
public enum ResultCodeEnum {SUCCESS(200,"成功"),FAIL(201, "失败"),SERVICE_ERROR(2012, "服务异常"),DATA_ERROR(204, "数据异常"),LOGIN_AUTH(401, "尚未登录,请重新登录"),PERMISSION(209, "没有权限"),LOGIN_MOBLE_ERROR(210,"登录认证失败" ),ACCOUNT_STOP(211,"账号已停用" ),TOKEN_ERR(212,"token异常"),PERMISSION_ERR(403,"权限不足,请联系管理员"),COMMENT_SUCCESS(200,"评论成功,请等待管理员审核" ),COMMENT_SUCCESS_S(200,"评论成功" ),COMMENT_ERROR(501,"评论失败" );private Integer code;private String message;private ResultCodeEnum(Integer code, String message) {this.code = code;this.message = message;}
}

4.Redis配置类

导入依赖

	<!-- Redis依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>
package com.trs.blog.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;/*** Redis配置类** @author : gaoziman* @date  2023/5/2 10:32*/
@Configuration
public class RedisConfig {/*** Redis序列化*/@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();// String类型key序列器redisTemplate.setKeySerializer(new StringRedisSerializer());// String类型value序列器redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());// Hash类型kay序列器redisTemplate.setHashKeySerializer(new StringRedisSerializer());// Hash类型value序列器redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());// 设置连接工厂redisTemplate.setConnectionFactory(redisConnectionFactory);return redisTemplate;}
}

5.代码生成器

导入依赖

    <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.4.1</version></dependency><dependency><groupId>org.apache.velocity</groupId><artifactId>velocity-engine-core</artifactId><version>2.0</version></dependency>
package com.trs.serviceUtil.util;import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;/*** @author gaoziman* 代码生成器*/
public class CodeGet {public static void main(String[] args) {// 1、创建代码生成器AutoGenerator mpg = new AutoGenerator();// 2、全局配置// 全局配置GlobalConfig gc = new GlobalConfig();gc.setOutputDir("E:\\exer_code\\cisyam-blog\\blog-parent\\service-blog"+"/src/main/java");gc.setServiceName("%sService");	//去掉Service接口的首字母Igc.setAuthor("manman");gc.setOpen(false);mpg.setGlobalConfig(gc);// 3、数据源配置DataSourceConfig dsc = new DataSourceConfig();dsc.setUrl("jdbc:mysql://localhost:3306/blog?serverTimezone=GMT%2B8&useSSL=false");dsc.setDriverName("com.mysql.cj.jdbc.Driver");dsc.setUsername("root");dsc.setPassword("root");dsc.setDbType(DbType.MYSQL);mpg.setDataSource(dsc);// 4、包配置PackageConfig pc = new PackageConfig();pc.setParent("com.trs");pc.setModuleName("blog"); //模块名pc.setController("controller");pc.setService("service");pc.setEntity("pojo");pc.setMapper("mapper");mpg.setPackageInfo(pc);// 5、策略配置StrategyConfig strategy = new StrategyConfig();strategy.setInclude("week_view");strategy.setNaming(NamingStrategy.underline_to_camel);//数据库表映射到实体的命名策略strategy.setColumnNaming(NamingStrategy.underline_to_camel);//数据库表字段映射到实体的命名策略strategy.setEntityLombokModel(true); // lombok 模型 @Accessors(chain = true) setter链式操作strategy.setRestControllerStyle(true); //restful api风格控制器strategy.setControllerMappingHyphenStyle(true); //url中驼峰转连字符mpg.setStrategy(strategy);// 6、执行mpg.execute();}
}

6.工具类

拷贝工具类

package com.trs.blog.util;import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;import java.util.ArrayList;
import java.util.List;/*** 集合对象复制工具类** @author gaoziman* @date  2023/5/1 23:32*/
public class BeanCopyUtil {/*** 复制集合** @param source 复制的原对象集合* @param clazz 对象类型* @param <T> 泛型* @return 复制完成的集合*/public static <T> List<T> copyList(List source, Class<T> clazz) {List<T> target = new ArrayList<>();if (!CollectionUtils.isEmpty(source)) {if (!CollectionUtils.isEmpty(source)) {for (Object c : source) {T obj = copy(c, clazz);target.add(obj);}}}return target;}/*** 复制对象** @param source 复制的原对象* @param clazz 对象类型* @param <T> 泛型* @return 复制完成的新对象*/public static <T> T copy(Object source, Class<T> clazz) {if (source == null) {return null;}T obj = null;try {obj = clazz.newInstance();} catch (Exception e) {e.printStackTrace();}BeanUtils.copyProperties(source, obj);return obj;}/*** 将传来的Object对象转为指定的List集合** @param object 传来的Object对象* @param clazz 指定类型* @param <T> 泛型* @return 指定的List集合*/public static <T> List<T> castObjectToList(Object object, Class<T> clazz) {List<T> result = new ArrayList<>();// 如果传来的对象属于List集合if (object instanceof List<?>) {for (Object o : (List<T>) object) {result.add(clazz.cast(o));}return result;}return null;}
}

集合工具类

package com.trs.blog.util;import org.springframework.util.StringUtils;import java.util.ArrayList;
import java.util.List;/*** 集合工具类** @author gaoziman* @date  2023/5/1 23:32*/
public class CollectionUtil {/*** 将传来的字符串数据转为整型集合** @param str 字符串数据* @return 整型集合*/public static List<Integer> stringToIntegerList(String str) {if (StringUtils.isEmpty(str)) {return null;}// 去除字符串两边的[]str = str.substring(1, str.length() - 1);// 根据 , 进行分割String[] split = str.split(",");List<Integer> result = new ArrayList<>();for (String s : split) {result.add(Integer.parseInt(s));}return result;}
}

IP地址工具类

package com.trs.blog.util;import com.alibaba.fastjson.JSON;
import eu.bitwalker.useragentutils.UserAgent;import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.List;
import java.util.Map;import static com.trs.common.constant.CommonConst.LOCAL_HOST;/*** IP地址工具类** @author gaoziman* @date  2023/5/1 23:32*/
public class IpUtil {/*** 获取当前IP地址以及IP所属源** @return IP地址*/public static String getCurIpAddress(HttpServletRequest request) {String ipAddress = null;try {ipAddress = request.getHeader("x-forwarded-for");if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {ipAddress = request.getHeader("Proxy-Client-IP");}if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {ipAddress = request.getHeader("WL-Proxy-Client-IP");}if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {// 获取到本机的远程IP地址ipAddress = request.getRemoteAddr();if (LOCAL_HOST.equals(ipAddress)) {// 根据网卡取本机配置的IPInetAddress inet = null;try {inet = InetAddress.getLocalHost();} catch (UnknownHostException e) {e.printStackTrace();}ipAddress = inet.getHostAddress();}}// 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割if (ipAddress != null && ipAddress.length() > 15) {// = 15if (ipAddress.indexOf(",") > 0) {ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));}}} catch (Exception e) {ipAddress = "";}return ipAddress;}/*** 解析ip地址** @param ipAddress ip地址* @return 解析后的ip地址*/public static String getIpSource(String ipAddress) {try {URL url = new URL("http://opendata.baidu.com/api.php?query=" + ipAddress + "&co=&resource_id=6006&oe=utf8");BufferedReader reader = new BufferedReader(new InputStreamReader(url.openConnection().getInputStream(), "utf-8"));String line = null;StringBuffer result = new StringBuffer();while ((line = reader.readLine()) != null) {result.append(line);}reader.close();Map map = JSON.parseObject(result.toString(), Map.class);List<Map<String, String>> data = (List) map.get("data");return data.get(0).get("location");} catch (Exception e) {return "";}}/*** 获取用户的访问设备** @param request 请求* @return 用户访问设备*/public static UserAgent getUserAgent(HttpServletRequest request){return UserAgent.parseUserAgentString(request.getHeader("User-Agent"));}
}

JWT处理Token工具类

package com.trs.blog.util;import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;import java.util.Date;
import java.util.HashMap;
import java.util.Map;/*** Jwt处理Token工具类*  * @author gaoziman* @date  2023/5/1 23:32*/
@Component
public class JwtTokenUtil {/*** 用户名的key*/private static final String CLAIM_KEY_USERNAME = "sub";/*** JWT的创建时间*/private static final String CLAIM_KEY_CREATED = "created";/*** 秘钥*/@Value("${jwt.secret}")private String secret;/*** token失效时间*/@Value("${jwt.expiration}")private Long expiration;/*** 根据用户信息生成token** @param userDetails 用户信息* @return 生成的token*/public String generateToken(UserDetails userDetails) {// 定义token中存储数据的载荷Map<String, Object> claims = new HashMap<>();// 1. 用户名claims.put(CLAIM_KEY_USERNAME, userDetails.getUsername());// 2. 签发时间claims.put(CLAIM_KEY_CREATED, new Date());// 签发tokenreturn generateToken(claims);}/*** 根据载荷生成token** @param claims 载荷* @return 生成的token*/private String generateToken(Map<String, Object> claims) {return Jwts.builder()// 1. 设置载荷.setClaims(claims)// 2. 设置失效时间.setExpiration(generateExpirationDate())// 3. 设置签名.signWith(SignatureAlgorithm.HS512, secret)// 签发token.compact();}/*** 生成token失效时间** @return token的失效时间*/private Date generateExpirationDate() {// token失效时间:当前系统时间 + 自己定义的时间return new Date(System.currentTimeMillis() + expiration * 1000);}/*** 从token中获取用户名** @param token token* @return 当前token中存储的用户名*/public String getUserNameFromToken(String token) {String userName;try {// 从token中获取到载荷Claims claims = getClaimsFromToken(token);// 通过载荷获取到用户名userName = claims.getSubject();} catch (Exception e) {// 如果出现异常则将 userName 设置为空userName = null;}return userName;}/*** 从token中获取载荷** @param token token* @return token中的载荷*/private Claims getClaimsFromToken(String token) {Claims claims = null;try {claims = Jwts.parser()// 解密的秘钥.setSigningKey(secret).parseClaimsJws(token).getBody();} catch (Exception e) {e.printStackTrace();}return claims;}/*** 判断token是否可以被刷新** @param token token* @return token是否可以被刷新*/public boolean canRefresh(String token) {return !isTokenExpired(token);}/*** 判断token是否失效** @param token token* @return 当前token是否失效*/private boolean isTokenExpired(String token) {Date expiredDate = getExpiredDateFromToken(token);// 如果失效时间是在当前时间之前肯定是失效的return expiredDate.before(new Date());}/*** 获取token中的失效时间** @param token token* @return 当前token中的失效时间*/private Date getExpiredDateFromToken(String token) {// 从当前token中获取载荷Claims claims = getClaimsFromToken(token);// 从载荷中返回失效时间return claims.getExpiration();}/*** 刷新token** @param token 用户携带的 token* @return 刷新后的 token*/public String refreshToken(String token) {// 从当前token中获取载荷Claims claims = getClaimsFromToken(token);// 更新载荷中的失效时间改成当前时间claims.put(CLAIM_KEY_CREATED, new Date());// 重新生成tokenreturn generateToken(claims);}/*** 判断token是否有效** @param token 用户携带的 token* @param userDetails 载荷* @return token 是否有效*/public boolean validateToken(String token, UserDetails userDetails) {// 通过token是否已经过期、荷载中的用户属性与userDetails中的用户属性是否一致String userName = getUserNameFromToken(token);return userName.equals(userDetails.getUsername()) && !isTokenExpired(token);}
}

时间转化工具类

package com.trs.blog.util;import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;/*** 时间转化工具类** @author gaoziman* @date  2023/5/1 23:32*/
public class TimeUtil {/*** LocalDateTime 转 String** @param time LocalDateTime* @return 对应的字符串*/public static String localDateTimeToString(LocalDateTime time) {return time.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));}/*** 获取当前时间(字符串格式)** @return 当前时间*/public static String getNowTime(){SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");return df.format(new Date());}/*** 获取当前时间(字符串格式)** @return 当前时间*/public static String getNowDate(){SimpleDateFormat df = new SimpleDateFormat("MM-dd");return df.format(new Date());}/*** String 转 LocalDate** @param time String* @return LocalDate*/public static LocalDate stringToLocalDateDay(String time){DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");return LocalDate.parse(time, df);}/*** String 转 LocalDate** @param time String* @return LocalDate*/public static LocalDate stringToLocalDate(String time){DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");return LocalDate.parse(time, df);}/*** String 转 LocalDateTime** @param time String* @return LocalDateTime*/public static LocalDateTime stringToLocalDateTimeDay(String time){// 先转LocalDate ===> 再转LocalDateTimeLocalDate localDate = stringToLocalDateDay(time);return localDate.atTime(LocalTime.now());}/*** String转LocalDateTime (yyyy-MM-dd HH:mm:ss格式)** @param time String格式时间* @return LocalDateTime*/public static LocalDateTime stringToLocalDateTime(String time){// 先转LocalDate ===> 再转LocalDateTimeLocalDate localDate = stringToLocalDate(time);return localDate.atTime(LocalTime.now());}/*** LocalDate转String** @param time LocalDate* @return String*/public static String localDateToString(LocalDate time) {return time.format(DateTimeFormatter.ofPattern("MM-dd"));}}

UUID生成工具类

package com.trs.blog.util;import java.util.UUID;/*** UUID生成工具类** @author gaoziman* @date  2023/5/1 23:32*/
public class UuidUtil {public static String[] chars = new String[]{"a", "b", "c", "d", "e", "f","g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s","t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5","6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I","J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V","W", "X", "Y", "Z"};/*** 获取短UUID** @return 16位UUID*/public static String getShortUuid() {StringBuffer shortBuffer = new StringBuffer();String uuid = UuidUtil.getUuid();for (int i = 0; i < 8; i++) {String str = uuid.substring(i * 4, i * 4 + 4);int x = Integer.parseInt(str, 16);// 对62取余shortBuffer.append(chars[x % 0x3E]);}return shortBuffer.toString();}/*** 获得32位UUID*/public static String getUuid() {String uuid = UUID.randomUUID().toString();//去掉“-”符号return uuid.replaceAll("-", "");}}

MD5工具类

package com.trs.common.util;import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;public final class MD5 {public static String encrypt(String strSrc) {try {char hexChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8','9', 'a', 'b', 'c', 'd', 'e', 'f' };byte[] bytes = strSrc.getBytes();MessageDigest md = MessageDigest.getInstance("MD5");md.update(bytes);bytes = md.digest();int j = bytes.length;char[] chars = new char[j * 2];int k = 0;for (int i = 0; i < bytes.length; i++) {byte b = bytes[i];chars[k++] = hexChars[b >>> 4 & 0xf];chars[k++] = hexChars[b & 0xf];}return new String(chars);} catch (NoSuchAlgorithmException e) {e.printStackTrace();throw new RuntimeException("MD5加密出错!!+" + e);}}public static void main(String[] args) {System.out.println(MD5.encrypt("123456"));}
}

7.knife4j文档

引入依赖

<!--knife4j-->
<dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId>
</dependency>
package com.trs.serviceUtil.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;import java.util.ArrayList;
import java.util.List;/*** knife4j配置信息*/
@Configuration
@EnableSwagger2WebMvc
public class Knife4jConfig {@Beanpublic Docket adminApiConfig(){List<Parameter> pars = new ArrayList<>();ParameterBuilder tokenPar = new ParameterBuilder();tokenPar.name("token").description("用户token").defaultValue("").modelRef(new ModelRef("string")).parameterType("header").required(false).build();pars.add(tokenPar.build());//添加head参数endDocket adminApi = new Docket(DocumentationType.SWAGGER_2).groupName("adminApi").apiInfo(adminApiInfo()).select()//只显示admin路径下的页面.apis(RequestHandlerSelectors.basePackage("com.trs")).paths(PathSelectors.regex("/.*")).build().globalOperationParameters(pars);return adminApi;}private ApiInfo adminApiInfo(){return new ApiInfoBuilder().title("后台管理系统-API文档").description("本文档描述了个人博客后台管理系统接口定义").version("1.0").contact(new Contact("manman", "http://manamn.space", "2942894660@qq.com")).build();}}

8.文件上传

导入依赖

<!-- 阿里云OSS文件上传开始 --><!-- 阿里云 OSS --><dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>3.14.1</version></dependency><!--日期时间工具--><dependency><groupId>joda-time</groupId><artifactId>joda-time</artifactId><version>2.10.14</version></dependency><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.4</version></dependency><!-- 阿里云OSS文件上传结束 -->
#阿里云文件上传
aliyun:oss:endpoint: ************keyid: ************keysecret:  ************bucketname: ************

配置类读取配置文件

package com.trs.demo.oss;import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;/*** oss属性*/
@Data
@Component
@ConfigurationProperties(prefix = "aliyun.oss")
public class OssProperties {private String endPoint;private String keyId;private String keySecret;private String bucketName;
}

Controller

package com.trs.demo.controller;import com.trs.demo.service.FileService;
import com.trs.demo.util.Result;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;import javax.annotation.Resource;@RestController
@RequestMapping("/oss/file")
public class OSSController {@Resourceprivate FileService fileService;/*** 文件上传** @param file* @param module* @return*/@PostMapping("/upload")public Result upload(MultipartFile file, String module) {//返回上传到oss的路径String url = fileService.upload(file, module);return Result.ok(url).message("文件上传成功");}
}

Service

package com.trs.demo.service.impl;import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.trs.demo.oss.OssProperties;
import com.trs.demo.service.FileService;
import org.apache.commons.io.FilenameUtils;
import org.joda.time.DateTime;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;/*** @author : gaoziman* @description :* @date 2023/5/8 9:47*/
@Service
public class FileServiceImpl  implements FileService {/*** oss属性*/@Resourceprivate OssProperties ossProperties;/*** 文件上传** @param file   文件上传对象* @param module 文件夹名称* @return {@link String}*/@Overridepublic String upload(MultipartFile file, String module) {//获取地域节点String endPoint = ossProperties.getEndPoint();//获取AccessKeyIdString keyId = ossProperties.getKeyId();//获取AccessKeySecretString keySecret = ossProperties.getKeySecret();//获取BucketNameString bucketName = ossProperties.getBucketName();try {//创建OSSClient实例OSS ossClient = new OSSClientBuilder().build(endPoint, keyId,keySecret);//上传文件流InputStream inputStream = file.getInputStream();//获取旧名称String originalFilename = file.getOriginalFilename();//获取文件后缀名String extension = FilenameUtils.getExtension(originalFilename);//将文件名重命名String newFileName = UUID.randomUUID().toString().replace("-", "") + "." + extension;//使用当前日期进行分类管理String datePath = new DateTime().toString("yyyy/MM/dd");//构建文件名newFileName = module + "/" + datePath + "/" + newFileName;//调用OSS文件上传的方法ossClient.putObject(bucketName, newFileName, inputStream);//关闭OSSClientossClient.shutdown();//返回文件地址return "https://" + bucketName + "." + endPoint + "/" + newFileName;} catch (IOException e) {e.printStackTrace();}return null;}/*** 删除文件** @param url url*/@Overridepublic void deleteFile(String url) {//获取地域节点String endPoint = ossProperties.getEndPoint();//获取AccessKeyIdString keyId = ossProperties.getKeyId();//获取AccessKeySecretString keySecret = ossProperties.getKeySecret();//获取BucketNameString bucketName = ossProperties.getBucketName();try {//创建OSSClient实例OSS ossClient = new OSSClientBuilder().build(endPoint, keyId, keySecret);//组装文件地址String host = "https://" + bucketName + "." + endPoint + "/";//获取文件名称String objectName = url.substring(host.length());//删除文件ossClient.deleteObject(bucketName, objectName);} catch (Exception e) {e.printStackTrace();}}
}

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

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

相关文章

软件测试技术之地图导航的测试用例

外观测试 屏幕显示不能有花屏、黑点和闪屏&#xff0c;清晰度、亮度、颜色要正常。 检测所有按键都能起到相应作用&#xff0c;是否手感不良。 UI显示状态、颜色、清晰度、效果。 控制&#xff1a;放大&#xff0c;缩小&#xff0c;音量调节功能测试。 交叉路口查询测试&am…

HAL库STM32串口开启DMA接收数据

STM32CubeMx的配置 此博客仅仅作为记录&#xff0c;这个像是有bug一样&#xff0c;有时候好使&#xff0c;有时候不好&#xff0c;所以趁现在好使赶紧记录一下&#xff0c;很多地方用到串口接收数据&#xff0c;DMA又是一种非常好的接收方式&#xff0c;可以节约CPU的时间&…

Redis(哈希Hash和发布订阅模式)

哈希是一个字符类型字段和值的映射表。 在Redis中&#xff0c;哈希是一种数据结构&#xff0c;用于存储键值对的集合。哈希可以理解为一个键值对的集合&#xff0c;其中每个键都对应一个值。哈希在Redis中的作用主要有以下几点&#xff1a; 1. 存储对象&#xff1a;哈希可以用…

米家竞品分析

一、项目描述 1. 竞品分析描述 分析市场直接竞品和潜在竞品&#xff0c;优化产品核心结构和页面布局&#xff0c;确立产品核心功能定位。了解目标用户核心需求&#xff0c;挖掘用户魅力型需求&#xff0c;以及市场现状为产品迭代做准备。 2. 产品测试环境 二、市场 1. 行业…

AI自动直播软件,ai无人直播工具2.0支持多平台矩阵直播一键同步直播脚本内容【直播脚本+使用技术教程】

AI实景直播软件简介&#xff1a; 支持一台手机自动直播&#xff0c;支持语音和文字同时回复&#xff0c;商品自动弹窗&#xff0c;支持抖音、快手、视频号、美团平台直播&#xff0c;支持矩阵直播&#xff0c;一键同步直播脚本内容。 设备需求&#xff1a; 安卓手机&#xf…

TensorRT量化实战课YOLOv7量化:YOLOv7-QAT量化

目录 前言1. YOLOv7-QAT流程2. QAT训练流程 前言 手写 AI 推出的全新 TensorRT 模型量化实战课程&#xff0c;链接。记录下个人学习笔记&#xff0c;仅供自己参考。 该实战课程主要基于手写 AI 的 Latte 老师所出的 TensorRT下的模型量化&#xff0c;在其课程的基础上&#xff…

在做题中学习(30):字符串相加

思路&#xff1a; 相加时要转换成对应的数字&#xff0c;所以让字符数字-0 如‘9’-‘0’&#xff08;ASCII&#xff09;57-489 9110&#xff0c;会进1&#xff0c;把进位保存起来&#xff0c;只取0头插到新串里。 头插时要转换对应字符数字&#xff0c;所以让对应的数字‘…

数据结构:红黑树的插入实现(C++)

个人主页 &#xff1a; 个人主页 个人专栏 &#xff1a; 《数据结构》 《C语言》《C》《Linux》 文章目录 一、红黑树二、红黑树的插入三、代码实现总结 一、红黑树 红黑树的概念&#xff1a; 红黑树是一颗二叉搜索树&#xff0c;但在每个节点上增加一个存储位表示节点的颜色&…

深入理解栈与队列:从基本概念到高级实现

&#x1f493; 博客主页&#xff1a;江池俊的博客⏩ 收录专栏&#xff1a;数据结构探索&#x1f449;专栏推荐&#xff1a;✅cpolar ✅C语言进阶之路&#x1f4bb;代码仓库&#xff1a;江池俊的代码仓库&#x1f525;编译环境&#xff1a;Visual Studio 2022&#x1f389;欢迎大…

golang中的并发模型

并发模型 传统的编程语言&#xff08;如C、Java、Python等&#xff09;并非为并发而生的&#xff0c;因此它们面对并发的逻辑多是基于操作系统的线程。其并发的执行单元&#xff08;线程&#xff09;之间的通信利用的也是操作系统提供的线程或进程间通信的原语&#xff0c;比如…

【Unity】单例模式及游戏声音管理类应用

【Unity】单例模式及游戏声音管理类应用 描述 在日常游戏项目开发中&#xff0c;单例模式是一种常用的设计模式&#xff0c;它允许在应用程序的生命周期中只创建一个对象实例&#xff0c;并提供对该实例的全局访问点。通过使用单例模式&#xff0c;可以提高代码的可维护性和可…

2024年山东省职业院校技能大赛中职组 “网络安全”赛项竞赛试题-B卷

2024年山东省职业院校技能大赛中职组 “网络安全”赛项竞赛试题-B卷 2024年山东省职业院校技能大赛中职组 “网络安全”赛项竞赛试题-B卷A模块基础设施设置/安全加固&#xff08;200分&#xff09;A-1&#xff1a;登录安全加固&#xff08;Windows, Linux&#xff09;A-2&#…

Verilog基础:仿真时x信号的产生和x信号对于各运算符的特性

相关阅读 Verilog基础https://blog.csdn.net/weixin_45791458/category_12263729.html?spm1001.2014.3001.5482 信号爆x也许是所有IC人的噩梦&#xff0c;满屏的红色波形常让人头疼不已&#xff0c;但x信号的产生原因却常常只有几种&#xff0c;只要遵循一定的代码规范&#…

超聚变服务器关闭超线程CPU的步骤(完整版)

前言: 笨鸟先飞&#xff0c;好记性不如烂笔头。 我们项目都用不到超线程CPU&#xff0c;所以调测设备的时候都需要关掉&#xff0c;最近新设备换成了超聚变的服务器&#xff0c;这篇记录我关闭&#xff08;超聚变&#xff09;服务器超线程CPU的方法步骤。 关闭超线程CPU的步骤…

JS-项目实战-鼠标悬浮变手势(鼠标放单价上生效)

1、鼠标悬浮和离开事件.js //当页面加载完成后执行后面的匿名函数 window.onload function () {//get:获取 Element:元素 By:通过...方式//getElementById()根据id值获取某元素let fruitTbl document.getElementById("fruit_tbl");//table.rows:获取这个表格…

基于单片机音乐弹奏播放DS1302万年历显示及源程序

一、系统方案 1、本设计采用51单片机作为主控器。 2、DS1302计时显示年月日时分秒。 3、按键可以弹奏以及播放音乐&#xff0c;内置16首音乐。 二、硬件设计 原理图如下&#xff1a; 三、单片机软件设计 1、首先是系统初始化 /时钟显示**/ void init_1602_ds1302() { write…

机器学习-搜索技术:从技术发展到应用实战的全面指南

在本文中&#xff0c;我们全面探讨了人工智能中搜索技术的发展&#xff0c;从基础算法如DFS和BFS&#xff0c;到高级搜索技术如CSP和优化问题的解决方案&#xff0c;进而探索了机器学习与搜索的融合&#xff0c;最后展望了未来的趋势和挑战&#xff0c;提供了对AI搜索技术深刻的…

Lesson 04 模板入门

C&#xff1a;渴望力量吗&#xff0c;少年&#xff1f; 文章目录 一、泛型编程1. 引入2. 函数模板&#xff08;1&#xff09;函数模板概念&#xff08;2&#xff09;函数模板格式&#xff08;3&#xff09;函数模板的原理&#xff08;4&#xff09;函数模板的实例化&#xff08…

uniapp优化h5项目-摇树优化,gzip压缩和删除console.log

1.摇树优化 勾选摇树优化,打包删除死代码 2.gzip压缩和删除console.log 安装插件webpack和compression-webpack-plugin webpack插件 npm install webpack4.46.0 --save-devcompression-webpack-plugin插件 npm install compression-webpack-plugin6.1.1 --save-devconst Com…

PMCW体制雷达系列文章(4) – PMCW雷达之抗干扰

说明 本文作为PMCW体制雷达系列文章之一&#xff0c;主要聊聊FMCW&PMCW两种体制雷达的干扰问题。事实上不管是通信领域还是雷达领域&#xff0c;对于一切以电磁波作为媒介的信息传递活动&#xff0c;干扰是无处不在的。近年来&#xff0c;随着雷达装车率的提高&#xff0c;…