//MusicAssistTools类
package com.example.demo.assist;
import com.example.demo.mapper.LoveMusicMapper;
import com.example.demo.mapper.MusicMapper;
import com.example.demo.model.Music;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import javax.annotation.Resource;
import java.io.File;
import java.util.HashMap;
@Component
public class MusicAssistTools {
@Resource
private MusicMapper musicMapper;
@Resource
private LoveMusicMapper loveMusicMapper;
@Value("${music.path}")
private String path;
private Object TransactionAspectSupport;
// 单个音乐的删除(三方面删除:music表、lovemusic表 和 服务器)
@Transactional
public Object deleteSingleMusic(Integer musicId){
// 先查出来,看看数据库里有没有这个音乐的信息
Music music = musicMapper.getMusicByNameAndSingerOrId(new Music(musicId));
// 没找到直接返回错误信息
if(music == null){
return "删除失败,数据库中没有音乐!";
}
// 删除数据库里的音乐
Integer result = musicMapper.deleteMusicById(musicId);
if(result != 1){
// 删除操作失败了
return "数据库删除失败!";
}
// 删除 lovemusic 表里的音乐 收藏记录
Integer res = loveMusicMapper.removeCollectMusicByMusicId(musicId);
if(res == null){
return "收藏音乐表删除失败!";
}
// 删除服务器里的音乐文件(.mp3)
String filename = path + music.getMname()+".mp3";
File file = new File(filename);
if(!file.exists()){
// 手动回滚,还原数据库中的原有数据
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return "删除失败,找不到该文件";
}
boolean delete = file.delete();
if(delete){
HashMap<String,Object> map = new HashMap<>();
map.put("result","success");
map.put("message","删除成功");
return map;
}else{
// 手动回滚,还原数据库中的原有数据
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return "音乐文件删除失败!";
}
}
}
//LoveMusicController类
package com.example.demo.controller;
import com.example.demo.model.User;
import com.example.demo.service.LoveMusicService;
import com.example.demo.tools.Constant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/lovemusic")
public class LoveMusicController {
@Autowired
private LoveMusicService loveMusicService;
// 收藏音乐
@PostMapping("/collectmusic") // 必须要有用户登录
public Object loveMusic(@SessionAttribute(Constant.USER_INFO_SESSION_KEY) User user,
@RequestParam("id") Integer musicId){
if(musicId == null){
return "参数为空!";
}
return loveMusicService.loveMusic(user,musicId);
}
//查询收藏的音乐(有参数就根据音乐名来模糊匹配,没有就查询全部)
@GetMapping("/getlovemusic")
public Object getMusicSingleOrList(@SessionAttribute(Constant.USER_INFO_SESSION_KEY) User user,
@RequestParam(value = "musicname",required = false) String musicName,
@RequestParam Integer pageNum,
@RequestParam Integer pageSize){
if(user == null || user.getUid() == 0){
return "没有用户信息";
}
return loveMusicService.getMusicSingleOrList(pageNum,pageSize,user,musicName);
}
// 音乐取消收藏
@PostMapping("/removelovemusic")
public Object removeLoveMusic(@SessionAttribute(Constant.USER_INFO_SESSION_KEY) User user,
@RequestParam("id") Integer musicId){
if(user == null || user.getUid() == 0){
return "用户未登录!";
}
return loveMusicService.removeLoveMusic(user.getUid(),musicId);
}
}
//MusicController类
package com.example.demo.controller;
import com.example.demo.model.User;
import com.example.demo.service.MusicService;
import com.example.demo.tools.Constant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.HashMap;
import java.util.List;
@RestController
@RequestMapping("/music")
public class MusicController {
@Autowired
private MusicService musicService;
@Value("${music.path}")
private String path;
// 上传音乐
@PostMapping("/upload")
public Object upload(@SessionAttribute(value = Constant.USER_INFO_SESSION_KEY) User user,
@RequestParam(value = "singer") String singer,
@RequestParam(value = "filename") MultipartFile file){
// 检查前端 singer 和 file 参数是否为null
if(!StringUtils.hasLength(singer) || file.isEmpty() || file.getSize() == 0 ){
// 返回 msg 信息
return "歌手或音乐文件不合法!";
}
return musicService.upload(user,singer,file);
}
// 删除单个音乐
@PostMapping("/delete")
public Object deleteMusicById( @SessionAttribute(Constant.USER_INFO_SESSION_KEY) User user,
@RequestParam("mid") Integer id){
if(id == null){
return "id不合法!";
}
if(user.getStatus().equals(false)){
HashMap<String,Object> map = new HashMap<>();
map.put("result","fail");
map.put("message","不是管理员,无法删除!");
return map;
}
return musicService.deleteMusicById(id);
}
// 批量删除音乐
@PostMapping("/deletesel")
public Object deleteMusicList(@SessionAttribute(Constant.USER_INFO_SESSION_KEY) User user,
@RequestParam("id[]")List<Integer> idList){
// 判空
if(idList == null || idList.size() == 0){
return "参数不正确!";
}
if(user.getStatus().equals(false)){
return "非管理员不能删除音乐!";
}
return musicService.deleteMusicList(idList);
}
// 查询音乐(传入为 null 时,表示查询全部,有参数时表示根据名称来模糊查询)
@GetMapping("/getmusic")
public Object getMusicByNameOrAll(@RequestParam(value = "musicname",required = false) String musicName,
@RequestParam Integer pageNum, // 第几页
@RequestParam Integer pageSize){ // 每页有几条数据
return musicService.getMusicByNameOrAll(pageNum,pageSize,musicName);
}
}
//UserController类
package com.example.demo.controller;
import com.example.demo.model.User;
import com.example.demo.service.UserService;
import com.example.demo.tools.Constant;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
@RestController
@RequestMapping("/user") //一级路径
public class UserController {
@Resource
private UserService userService;
// post 方法进行登录
@PostMapping("/login")
public Object login(HttpServletRequest request,
@RequestParam("username") String username,
@RequestParam("password") String password){
//参数校验
if(!StringUtils.hasLength(username) || !StringUtils.hasLength(password)){
//说明参数非法
return "用户名或密码为null";
}
//封装成一个 user 对象,方便 service 层的使用
User user = new User();
user.setUsername(username);
user.setPassword(password);
//调用 service 中的接口查询 user 对象信息
return userService.login(request,user);
}
// 用户注册
@PostMapping("/register")
public Object register(@RequestParam("username")String username,
@RequestParam("password1")String password1,
@RequestParam("password2")String password2){
// 1. 检查参数
if(!StringUtils.hasLength(username) || !StringUtils.hasLength(password1) || !StringUtils.hasLength(password2)){
// 参数有误
return "用户名或密码为空";
}
if(!password1.equals(password2)){
return "密码错误";
}
User user = new User();
user.setUsername(username);
user.setPassword(password1);
return userService.register(user);
}
// 用户注销
@GetMapping("/cancel")
public Object cancelUser(HttpServletRequest request){
HttpSession session = request.getSession(false);
if(session != null && session.getAttribute(Constant.USER_INFO_SESSION_KEY) != null){
session.removeAttribute(Constant.USER_INFO_SESSION_KEY);
HashMap<String,Object> map = new HashMap<>();
map.put("result","success");
map.put("message","注销成功!");
return map;
}
return "注销失败!";
}
// 获取用户信息
@GetMapping("/getuser")
public Object getUserMessage(@SessionAttribute(Constant.USER_INFO_SESSION_KEY) User user){
user.setPassword("");
return user;
}
}
//AppConfig类
package com.example.demo.interceptor;
import com.example.demo.tools.CheckTypeMP3;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
// 将自定义拦截器加入到系统配置中
@Configuration
public class AppConfig implements WebMvcConfigurer {
@Autowired
private UserLoginIdInterceptor userLoginIdInterceptor;
// 添加拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 添加用户登录拦截器
registry.addInterceptor(userLoginIdInterceptor)
.addPathPatterns("/**") // 拦截所有 url
.excludePathPatterns("/user/login") // 排除登录接口
.excludePathPatterns("/user/register")
.excludePathPatterns("/login.html") // 排除登录页面
.excludePathPatterns("/**/*.js") // 排除静态资源
.excludePathPatterns("/**/*.css")
.excludePathPatterns("/**/*.jpg")
.excludePathPatterns("/**/*.png")
.excludePathPatterns("/register.html");
}
// 通过 IOC 来管理 BCrypt 对象
@Bean
public BCryptPasswordEncoder getBCryptPasswordEncoder(){
return new BCryptPasswordEncoder();
}
// 提前将 检查MP3格式的类交给 IOC容器来管理
@Bean
public CheckTypeMP3 getCheckTypeMP3(){
return new CheckTypeMP3();
}
}
//Application类
package com.example.demo.interceptor;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.context.annotation.Bean;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import java.util.Arrays;
@SpringBootApplication
public class Application {
@Bean
public HttpMessageConverters converters() {
return new HttpMessageConverters(
false, Arrays.asList(new MappingJackson2HttpMessageConverter()));
}
}
//ExceptionInterceptor类
package com.example.demo.interceptor;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.util.HashMap;
// 对异常进行统一处理
@RestControllerAdvice
public class ExceptionInterceptor {
@ExceptionHandler(Exception.class)
public Object exceptionInterceptor(Exception e){
HashMap<String,Object> map = new HashMap<>();
map.put("status",0);
map.put("data","");
map.put("msg","异常信息:"+e.getMessage());
return map;
}
}
//ReturnTypeInterceptor类
package com.example.demo.interceptor;
import com.example.demo.tools.Result;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import java.util.HashMap;
// 统一返回类型处理
@ControllerAdvice
public class ReturnTypeInterceptor implements ResponseBodyAdvice {
@Override
public boolean supports(MethodParameter returnType, Class converterType) {
// 如果触发了异常拦截,就不用进行统一处理
String name = returnType.getMethod().getName();
if("exceptionInterceptor".equals(name)){
return false;
}
// 如果是播放音乐,就不经过统一类型返回
if("getMusic".equals(name)){
return false;
}
return true;
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType,
MediaType selectedContentType,
Class selectedConverterType,
ServerHttpRequest request,
ServerHttpResponse response) {
Object obj = null;
// 通过判断是否是一个 String 类型来决定是否有错误信息
if(body instanceof String){
obj = Result.fail(body);
// 解决 不能返回一个 String 的第二种方式 ,封装一个 toJsonString 方法
// return toJsonString(obj);
} else{
obj = Result.success(body);
}
return obj;
}
private Object toJsonString(Object response){
try {
// 通过 jackson 来将对象转换成一个 json 格式的字符串
return new ObjectMapper().writeValueAsString(response);
} catch (JsonProcessingException e) {
// 表示转换不了
e.printStackTrace();
}
return null;
}
}
// UserLoginIdInterceptor类
package com.example.demo.interceptor;
import com.example.demo.tools.Constant;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
// 用户身份验证拦截器
@Component
public class UserLoginIdInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
// 1. 获取 session
HttpSession session = request.getSession(false);
// 2. 判断
if(session == null || session.getAttribute(Constant.USER_INFO_SESSION_KEY) == null){
// 没有登录就重定向到 用户登录页面
response.sendRedirect("/login.html");
return false;
}
return true;
}
}
//LoveMusic类
package com.example.demo.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class LoveMusic {
private Integer loveId;
private Integer userId;
private Integer musicId;
}
//Music类
package com.example.demo.model;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Music {
private Integer mid;
private String mname;
private String msinger;
@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date createtime;
private String url;
private Integer uid;
private User userInfo;
public Music(String mname,String msinger){
this.mname = mname;
this.msinger = msinger;
}
public Music(Integer mid){
this.mid = mid;
}
}
//User类
package com.example.demo.model;
import lombok.Data;
@Data
public class User {
private Integer uid;
private String username;
private String password;
private Boolean status;
}
//LoveMusicService类
package com.example.demo.service;
import com.example.demo.mapper.LoveMusicMapper;
import com.example.demo.model.LoveMusic;
import com.example.demo.model.Music;
import com.example.demo.model.User;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
@Service
public class LoveMusicService {
@Resource
private LoveMusicMapper loveMusicMapper;
// 收藏音乐
public Object loveMusic(User user, Integer musicId){
// 根据 userId 和 musicId 查询 lovemusic 数据
LoveMusic loveMusic = loveMusicMapper.getLoveMusicByUidAndMid(user.getUid(), musicId);
if(loveMusic != null){
return "重复收藏!";
}
// 添加歌曲
Boolean result = loveMusicMapper.addLoveMusic(user.getUid(), musicId);
if(!result){
return "添加失败!";
}
HashMap<String,Object> map = new HashMap<>();
map.put("result","success");
map.put("message","收藏音乐成功");
return map;
}
// 查询收藏音乐文件(两种情况:有参模糊查,无参查全部)
public Object getMusicSingleOrList(int pageNum , int pageSize ,User user,String musicName){
List<Music> ret = loveMusicMapper.getMusicSingleOrList(user.getUid(),musicName);
HashMap<String,Object> map = new HashMap<>();
// 判断查询结果
if(ret == null || ret.size() == 0){
return "用户收藏音乐为空";
}
map.put("num",ret.size());
PageHelper.startPage(pageNum,pageSize);
List<Music> musicList = loveMusicMapper.getMusicSingleOrList(user.getUid(),musicName);
PageInfo<Music> pageInfo = new PageInfo<>(musicList);
map.put("musicList",pageInfo.getList());
return map;
}
// 取消音乐的收藏
public Object removeLoveMusic(Integer userId,Integer musicId){
Integer result = loveMusicMapper.removeCollectMusic(userId, musicId);
if(result != 1){
return "音乐取消收藏失败";
}
List<Music> list = loveMusicMapper.getMusicSingleOrList(userId, null);
HashMap<String,Object> map = new HashMap<>();
map.put("result","success");
map.put("message","取消收藏成功!");
map.put("musicTotal",list.size());
return map;
}
}
//MusicService类
package com.example.demo.service;
import com.example.demo.assist.MusicAssistTools;
import com.example.demo.mapper.MusicMapper;
import com.example.demo.model.Music;
import com.example.demo.model.User;
import com.example.demo.tools.CheckTypeMP3;
import com.example.demo.tools.Constant;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.File;
import java.util.HashMap;
import java.util.List;
@Service
public class MusicService {
@Resource
private MusicMapper musicMapper;
@Autowired
private CheckTypeMP3 checkTypeMP3;
@Value("${music.path}")
private String path;
@Autowired
private MusicAssistTools musicAssistTools;
// 上传音乐
public Object upload(User user, String singer, MultipartFile file) {
File f = null;
// 上传文件
try {
// 拿到 整个文件名(文件名+后缀)
String filename = file.getOriginalFilename();
// 拿到文件名
assert filename != null;
int index = filename.lastIndexOf(".");
String title = filename.substring(0,index);
// 检查该首音乐是否重复上传(歌名和歌手都相同就表示重复)
Music musicByName = musicMapper.getMusicByNameAndSingerOrId(new Music(title,singer));
if(musicByName != null){
return "歌曲已在音乐库中!";
}
// 检查 歌手 不同, 歌名 相同的情况:返回上传失败(歌名不能重复信息)
Music result = musicMapper.getMusicByNameAndSingerOrId(new Music(title, null));
if(result != null){
// 说明有相同的歌名,直接上传会覆盖掉之前的音乐
return "歌名重复!";
}
// 拼接文件路径(后面需要请求到后端接口来实现传输字节数据)
String musicPath = path + filename;
f = new File(musicPath);
// 如果路径不存在就创建一个
if (!f.exists()) {
f.mkdirs();
}
// 将上传的文件写入到本地
file.transferTo(f);
// 检查上传的文件是否是 mp3 格式
boolean flag = checkTypeMP3.checkTypeMP3(f);
if(!flag){
// 删除该文件
f.delete();
return "文件不是mp3格式!";
}
// 将文件封装成一个 Music对象
Music music = new Music();
music.setMsinger(singer);
music.setUid(user.getUid());
music.setUrl(Constant.MUSIC_PATH+filename);
music.setMname(title);
// 将音乐信息更新到数据库中
Integer upload = musicMapper.upload(music);
if (upload == 1) {
HashMap<String,Object> map = new HashMap<>();
map.put("result","success");
map.put("redirect","list.html"); // 文件上传成功,应该需要返回到列表页(后序实现)
return map;
}
// 走到这里说明 服务器上传成功,但是 数据库上传 失败了。所以需要删除一些文件。
if(f != null){
boolean d = f.delete();
if(!d){
return "收尾删除音乐文件工作失败!";
}
}
} catch (Exception e) {
if(f != null){
f.delete();
}
// 一旦抛出异常就表示上传失败
e.printStackTrace();
return "上传失败!";
}
// 说明上传失败了!
return "上传失败!";
}
// 单个音乐的删除
public Object deleteMusicById(Integer id){
Object obj = musicAssistTools.deleteSingleMusic(id);
if(!(obj instanceof String)){
HashMap<String,Object> ret = (HashMap<String, Object>) obj;
List<Music> list = musicMapper.getMusicByNameOrAll(null);
ret.put("musicTotal",list.size());
return ret;
}
return obj;
}
// 批量音乐的删除
public Object deleteMusicList(List<Integer> idList) {
int number = idList.size();
// 统计被影响的行数
int count = 0;
// 循环处理所有的 id
for(int i = 0; i < number; i++){
Integer id = idList.get(i);
Object o = musicAssistTools.deleteSingleMusic(id);
if(o instanceof String){
if(count != 0){
HashMap<String,Object> map = new HashMap<>();
map.put("result","error");
map.put("message","成功删除部分音乐");
map.put("delete_total",count);
return map;
}
}else{
// 累计被影响的行数
count++;
}
}
// 总共被影响的行数 == id 数,说明批量删除成功
if(count == idList.size()){
HashMap<String,Object> map = new HashMap<>();
map.put("result","success");
map.put("message","批量删除成功!");
map.put("delete_total",count);
return map;
}
// 一条都没删除成功就走这里
return "批量删除失败!";
}
// 模糊查询音乐 或 查询所有音乐
public Object getMusicByNameOrAll(int pageNum,int pageSize, String musicName){
List<Music> ret = musicMapper.getMusicByNameOrAll(musicName);
HashMap<String,Object> map = new HashMap<>();
if(ret == null || ret.size() == 0){
return "查询结果为空!";
}
map.put("num",ret.size());
PageHelper.startPage(pageNum,pageSize);
List<Music> musicList = musicMapper.getMusicByNameOrAll(musicName);
PageInfo<Music> pageInfo = new PageInfo<>(musicList);
map.put("musicList",pageInfo.getList());
// 返回查询的结果集
return map;
}
}
//UserService类
package com.example.demo.service;
import com.example.demo.mapper.UserMapper;
import com.example.demo.model.User;
import com.example.demo.tools.Constant;
import com.example.demo.tools.EncryptionTool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
@Service
@Slf4j
public class UserService {
@Resource
private UserMapper userMapper;
@Autowired
private EncryptionTool encryptionTool;
// 调用用户登录所需要的接口
public Object login(HttpServletRequest request, User user){
// 调用 mybatis 中的用户查找接口
User userTest = userMapper.getUserByName(user.getUsername());
// 判断一下查到的数据是否为null
if(userTest != null){
// 判断密码是不是md5+加盐产生的(数据库是从空表开始插入数据的话,应该不用判)
if(userTest.getPassword().charAt(0) != '$' && user.getPassword().equals(userTest.getPassword())){
userTest.setPassword(""); //密码隐藏
//将用户信息添加到 session 中
HttpSession session = request.getSession(true);
session.setAttribute(Constant.USER_INFO_SESSION_KEY,userTest);
//返回查询出来的 user 对象信息
return userTest;
}
}
// 返回 msg 信息
return "用户名或密码有误";
}
// 用户注册
public Object register(User user){
//查询该用户名是否被注册
User userByName = userMapper.getUserByName(user.getUsername());
if(userByName != null){
// 该用户已被注册
return "该账号已被注册!";
}
// 获取加密密码
String encryptPassword = encryptionTool.encrypt(user.getPassword());
user.setPassword(encryptPassword);
int register = userMapper.register(user);
if(register == 1){
HashMap<String,Object> map = new HashMap<>();
map.put("result","success");
map.put("redirect","/login.html");
return map;
}else{
return "注册失败!";
}
}
}
//CheckTypeMP3类
package com.example.demo.tools;
import java.io.*;
public class CheckTypeMP3 {
public boolean checkTypeMP3(File path){
byte[] bytes = new byte[128];
try(RandomAccessFile randomAccessFile = new RandomAccessFile(path,"r");
){
// 长度不够不可能是 正常的mp3 文件
if(randomAccessFile.length() <= 128){
return false;
}
// 将指针指向 ID3V1 中 128 个字节的 第一个字节处
randomAccessFile.seek(randomAccessFile.length()-128);
// 读取
randomAccessFile.read(bytes,0,3);
if("TAG".equalsIgnoreCase(new String(bytes,0,3))){
return true;
}
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
}
//Constant类
package com.example.demo.tools;
// 存放一些使用的常量
public class Constant {
// session 中的 key 值
public static final String USER_INFO_SESSION_KEY = "USER_INFO_SESSION_KEY";
public static final String MUSIC_PATH = "http://localhost:8080/music/";
// Linux 下访问 tomcat 的路径
// public static final String MUSIC_PATH = "http://43.140.251.201:8888/music/";
}
//EncryptionTool类
package com.example.demo.tools;
import cn.hutool.core.codec.Base64;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component;
import java.io.*;
@Component
@Slf4j
public class EncryptionTool {
@Value("${private.key.url}")
private String privateKeyUrl;
@Value("${public.key.url}")
private String publicKeyUrl;
@Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
private RSA rsa;
// 字符流读取 密钥
public String[] getKey(){
String[] strings = new String[2];
try(
BufferedReader readerPri = new BufferedReader(new FileReader(privateKeyUrl));
BufferedReader readerPub = new BufferedReader(new FileReader(publicKeyUrl))
){
String readLine = null;
StringBuilder sb = new StringBuilder();
// 每次读取一行
while ((readLine = readerPri.readLine()) != null) {
sb.append(readLine);
}
// 将读取的第一个 钥匙 放到 数组 中
strings[0] = sb.toString();
// 将临时变量 sb 清空,用来存储 另一把钥匙
sb.delete(0,sb.length());
// 每次读取一行
while ((readLine = readerPub.readLine()) != null) {
sb.append(readLine);
}
// 将读取的第一个 钥匙 放到 数组 中
strings[1] = sb.toString();
} catch (IOException e) {
e.printStackTrace();
}
return strings;
}
// 加密
public String encrypt(String password){
// 获取 公钥和私钥
String[] key = getKey();
rsa = new RSA(key[0],key[1]);
// 通过 BCrypt (md5 + 随机加盐) 进行加密
String encode = bCryptPasswordEncoder.encode(password);
// 通过 非对称加密 再次包裹一层
byte[] decrypt = rsa.encrypt(encode, KeyType.PublicKey);
// 返回 密文
return Base64.encode(decrypt);
}
// 解密
public boolean decrypt(String nowPassword,String oldPassword){
// 获取 公钥和私钥
String[] key = getKey();
rsa = new RSA(key[0],key[1]);
// 通过非对称加密进行解密
String result = rsa.decryptStr(oldPassword, KeyType.PrivateKey);
// 通过 matches 方法来判断 输入的密码是否 就是 BCrypt 加密之前的密码
return bCryptPasswordEncoder.matches(nowPassword, result);
}
}
//Result类
package com.example.demo.tools;
import lombok.Data;
// 自定义响应数据类型
@Data
public class Result{
private int status; // 表示通讯是否成功
private String msg; // 响应信息
private Object data; // 响应数据
private Result(){
}
// 响应成功的数据模板
public static Result success(Object data){
Result result = new Result();
result.setStatus(1);
result.setMsg("");
result.setData(data);
return result;
}
// 响应失败的数据模板
public static Result fail(Object msg){
String str = msg.toString();
Result result = new Result();
result.setStatus(0);
result.setMsg(str);
result.setData("");
return result;
}
}
//Write类
package com.example.demo.tools;
import cn.hutool.core.codec.Base64;
import cn.hutool.crypto.SecureUtil;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
public class Write {
public void write(){
KeyPair pair = SecureUtil.generateKeyPair("RSA");
PrivateKey aPrivate = pair.getPrivate();
PublicKey aPublic = pair.getPublic();
writeDetails(Base64.encode(aPrivate.getEncoded()),Base64.encode(aPublic.getEncoded()));
}
public void writeDetails(String pri,String pub){
System.out.println(pri);
System.out.println(pub);
try(
Writer writerPri = new FileWriter("d:/private.txt");
Writer writerPub = new FileWriter("d:/public.txt");
){
writerPri.write(pri);
writerPub.write(pub)
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Write write = new Write();
write.write();
}
}
//DemoApplication类
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
// 过滤掉 security 的接口保护
@SpringBootApplication(exclude = {org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class })
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}