黑马程序员大事件后端概览(表现效果升级版)

目录

example

anno

state

config

WebConfig

controller

ArticleController

CategoryController

FileUploadController

UserController

exception

GlobalExceptionHander

interceptors

LoginInterceptor

mapper

ArticleMapper

CatogoryMapper

UserMapper

pojo

Article

Category

PageBean

Result

User

service

ArticleService

CategoryService

UserService

serviceImpl

ArticleServiceImpl

CategoryServiceImpl

UserServiceImpl

utils

AliOssUtil

JwtUtil

Md5Util

ThreadLocalUtil

Validation

StateValidation

resource

mapper

ArticleMapper.XML

application.yml


注:代码仅供交流学习

example

anno

state

java 复制代码
package org.example.anno;

import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import org.example.Validation.StateValidation;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

@Documented//元注解
@Target({FIELD})//元注解
@Retention(RUNTIME)//元注解
@Constraint(validatedBy = {StateValidation.class})//指定提供校验规则的类
public @interface State {
    //提供校验失败信息
    String message() default "state参数的值只能是已发布或者是草稿";
    //指定分组
    Class<?>[] groups() default {};
    //负载   获取到State注解的附加信息
    Class<? extends Payload>[] payload() default {};
}

config

WebConfig

java 复制代码
package org.example.config;

import org.example.interceptors.LoginInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Autowired
    private LoginInterceptor loginInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //登录接口和注册接口不拦截
        registry.addInterceptor(loginInterceptor)
        .excludePathPatterns("/user/login","/user/register");
    }
}

controller

ArticleController

java 复制代码
package org.example.controller;


import org.example.pojo.Article;
import org.example.pojo.PageBean;
import org.example.pojo.Result;
import org.example.service.impl.ArticleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/article")
public class ArticleController {
    @Autowired
    private ArticleService articleService;
    @PostMapping
    public Result add(@RequestBody @Validated Article article){
        articleService.add(article);
        return Result.success();
    }
public Result<PageBean<Article>> list(
        Integer pageNum,
        Integer pageSize,
        @RequestParam(required = false) Integer categoryId,
        @RequestParam(required = false)String state
){
    PageBean<Article>pb=articleService.list(pageNum,pageSize,categoryId,state);
    return Result.success(pb);
}
@PutMapping("/article")
public Result updateArticle(@RequestBody@Validated Article article){
        return articleService.updateArticle(article);
}
    @GetMapping("/article/detail")
    public Result getArticleDetail(@RequestParam Integer id) {
        return articleService.getArticleDetail(id);
    }
    //删除文章
    @DeleteMapping("/article")
    public Result deleteArticle(@RequestParam Integer id) {
        return articleService.deleteArticle(id);
    }
}

CategoryController

java 复制代码
package org.example.controller;

import org.example.pojo.Category;
import org.example.pojo.Result;
import org.example.service.impl.CategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/category")
public class CategoryController {
    @Autowired
    private CategoryService categoryService;
    @PostMapping
    public Result add(@RequestBody @Validated(Category.Add.class) Category category){
        categoryService.add(category);
        return Result.success();
    }
    @GetMapping
    public Result<List<Category>> List(){
        List<Category>cs=categoryService.list();
        return Result.success(cs);
    }
    @GetMapping("/detail")
    public Result<Category> detail(Integer id){
        Category c=categoryService.findById(id);
        return Result.success(c);
    }
    @PutMapping
    public Result update(@RequestBody @Validated Category category){
        categoryService.update(category);
        return Result.success();
    }
    @DeleteMapping
    public Result delete(@RequestParam @Validated(Category.Update.class) Integer id){
        boolean success=categoryService.delete(id);
        if(success){
            return Result.success("删除成功");
        }else {
            return Result.error("操作失败,删除异常");
        }
    }
}

FileUploadController

java 复制代码
package org.example.controller;

import org.example.pojo.Result;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.UUID;

@RestController
public class FileUploadController {
    @PostMapping("/upload")
    public Result<String> upload(MultipartFile file) throws IOException {
        //把文件的内容存储到本地磁盘上
        String originalFilename=file.getOriginalFilename();
        //保证文件的名字是唯一的,从而防止文件覆盖
        String fileName= UUID.randomUUID().toString()+"."+originalFilename.substring(originalFilename.lastIndexOf("."));
        file.transferTo(new File("D:\\rush\\files\\"+originalFilename));
        return Result.success("");
    }
}

UserController

java 复制代码
package org.example.controller;

import jakarta.validation.constraints.Pattern;
import org.example.pojo.Result;
import org.example.pojo.User;
import org.example.service.impl.UserService;
import org.example.utils.JwtUtil;
import org.example.utils.Md5Util;
import org.example.utils.ThreadLocalUtil;
import org.hibernate.validator.constraints.URL;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/user")
@Validated
public class UserController {
    @Autowired
    private UserService userService;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @PostMapping("/register")
    public Result register(@Pattern(regexp = "^\\S{5,16}$") String username, @Pattern(regexp = "^\\S{5,16}$")String password){//查询用户
            User u = userService.findByUserName(username);
            if (u == null) {
                //没有占用
                // 注册
                userService.register(username, password);
                return Result.success();
            } else {
                //占用
                return Result.error("用户名已被占用");
            }
        }
        @PostMapping("/login")
        public Result<String> login(@Pattern(regexp = "^\\S{5,16}$") String username, @Pattern(regexp = "^\\S{5,16}$")String password){
        //根据用户名查询用户
        User loginUser = userService.findByUserName(username);
        //判断用户是否存在
            if (loginUser == null) {
                return Result.error("用户名不存在");
            }
        //判断密码是否正确  loginUser对象的password是密文的
        if(Md5Util.getMD5String(password).equals(loginUser.getPassword())){
            //登录成功
            Map<String,Object> claims = new HashMap<>();
            claims.put("id",loginUser.getId());
            claims.put("username",loginUser.getUsername());
            String token=JwtUtil.genToken(claims);
            //把token存储到redis里
            ValueOperations<String,String>operations=stringRedisTemplate.opsForValue();
            operations.set("token",token,12, TimeUnit.HOURS);
            return Result.success(token);
        }
        return Result.error("用户名与密码不符");
        }
        @GetMapping("/userInfo")
        public Result<User> userInfo(/*@RequestHeader(name="Authorization") String token*/){
            //根据用户名查询用户
//            JwtUtil.parseToken(token);
//            Map<String,Object> map = JwtUtil.parseToken(token);
//            String username = (String) map.get("username");
            Map<String,Object> map=ThreadLocalUtil.get();
            String username = (String) map.get("username");
            User user=userService.findByUserName(username);
            return Result.success(user);
        }
        @PutMapping("/update")
    public Result update(@RequestBody@Validated User user){
        userService.update(user);
        return Result.success();
        }
        @PatchMapping("updateAvatar")
        public Result updateAvatar(@RequestParam @URL String avatarUrl){
            userService.updateAvatar(avatarUrl);
            return Result.success();
        }
        @PatchMapping("/updatePwd")
    public Result updatePwd(@RequestBody Map<String,String> params,@RequestHeader("Authorization") String token){
        //1.校验参数
        String oldPwd = params.get("old_pwd");
        String newPwd = params.get("new_pwd");
        String rePwd = params.get("re_pwd");
        if(StringUtils.hasLength(oldPwd)||StringUtils.hasLength(newPwd)||StringUtils.hasLength(rePwd)){
            return Result.error("缺少必要的参数");
        }
        //原密码是否正确
        //调用UserService根据用户名拿到原密码,再和old_pwd比对
        Map<String,Object> map=ThreadLocalUtil.get();
        String username = (String) map.get("username");
        User loginUser=userService.findByUserName(username);
        if (!loginUser.getPassword().equals((Md5Util.getMD5String(oldPwd)))) {
            return Result.error("原密码填写不正确");
        }
        //newPwd和rePwd是否一样
        if(!rePwd.equals(newPwd)){
            return Result.error("两次新密码不相同");
        }
        //oldPwd和newPwd是否一样
        if(!oldPwd.equals(newPwd)){
         return Result.error("新密码与原密码相同");
         }
        //2.调用Service完成密码更新
        userService.updatePwd(newPwd);
        //删除redis中对应的token
            ValueOperations<String,String>operations=stringRedisTemplate.opsForValue();
            operations.getOperations().delete(token);
        return Result.success();
        }
    }

exception

GlobalExceptionHander

java 复制代码
package org.example.exception;

import org.springframework.util.StringUtils;
import org.example.pojo.Result;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

@ControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(Exception.class)
    public Result handleException(Exception e) {
        e.printStackTrace();
        return Result.error(StringUtils.hasLength(e.getMessage())? e.getMessage() : "操作失败");
    }
}

interceptors

LoginInterceptor

java 复制代码
package org.example.interceptors;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.example.utils.JwtUtil;
import org.example.utils.ThreadLocalUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import java.util.Map;

@Component
public class LoginInterceptor implements HandlerInterceptor {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //令牌验证
        String token=request.getHeader("Authorization");
        //验证token
        try {
            //从redis中获取相同的token
            ValueOperations<String,String> operations=stringRedisTemplate.opsForValue();
            String redisToken=operations.get(token);
            if(redisToken==null){
                //失效
                throw new RuntimeException();
            }
            Map<String,Object> claims= JwtUtil.parseToken(token);
            //把业务数据存储到ThreadLocal中
            ThreadLocalUtil.set(claims);
            //验证通过
            return true;
        } catch (Exception e) {
            //http响应状态码为401
            response.setStatus(401); //
            //验证失败
            return false;
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        //清空ThreadLocal中的数据
        ThreadLocalUtil.remove();
    }
}

mapper

ArticleMapper

java 复制代码
package org.example.mapper;

import org.apache.ibatis.annotations.*;
import org.example.pojo.Article;

import java.util.List;

@Mapper

public interface ArticleMapper {
    //新增
    @Insert("insert into article(title,context,cover_img,state,category_id,create_time,update_time" +
            "values(#{title},#{content},#{coverImg},#{state},#{categoryId},#{createUser},#{createTime},#{updateTime}))")
    void add(Article article);
    //更新文章信息
    @Update("UPDATE article SET title = #{title}, content = #{content}, " +
            "covering = #{covering}, state = #{state}, category_id = #{categoryId}, " +
            "update_time = NOW() WHERE id = #{id}")
    int updateArticle(Article article);
    //检查文章是否存在
    @Select("SELECT COUNT(*) FROM article WHERE id = #{id}")
    int existsById(Integer id);
    //检查分类是否存在
    @Select("SELECT COUNT(*) FROM category WHERE id = #{categoryId}")
    int existsCategoryById(Integer categoryId);
    List<Article> list(Integer userId, Integer categoryId, String state);
    //检查对应文章
    @Select("SELECT id, title, content, covering as coverImg, state, " +
            "category_id as categoryId, create_time as createTime, " +
            "update_time as updateTime FROM article WHERE id = #{id}")
    Article
    selectArticleDetailById(Integer id);
    //删除文章
    @Delete("DELETE FROM article WHERE id = #{id}")
    int deleteArticleById(@Param("id") Integer id);
}

CatogoryMapper

java 复制代码
package org.example.mapper;

import org.apache.ibatis.annotations.*;
import org.example.pojo.Category;

import java.util.List;

@Mapper
public interface CategoryMapper {
    //新增
    @Insert("insert into category(category_name,category_alias,category.create_user,create_time,update_time)"+
    "values(#{categoryName},#{categoryAlias},#{createUser},#{createTime},#{updateTime})")
    void add(Category category);

    //查询所有
    @Select("select * from category where create_user=#{userId}")
    List<Category> list(Integer userId);

    //根据id查询
    @Select("select * from category where id=#{id}")
    Category findById(Integer id);

    //更新
    @Update("update category set category_name=#{categoryName},category_alias=#{categoryAlias},update_time=#{updateTime} where id=#{id}")
    void update(Category category);

    //删除
    @Delete("delete from category where id=#{id}")
    void delete(Integer id);
}

UserMapper

java 复制代码
package org.example.mapper;

import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.example.pojo.User;
@Mapper
public interface UserMapper {
    //根据用户名查询用户
    @Select("select * from user where username=#{username}")
    User findByUserName(String username);
    //添加
    @Insert("insert into user(username,password,create_time,update_time)"+
    " values(#{username},#{password},now(),now())")
    void add(String username, String password);

    @Update("update user set nickname=#{nickname},email=#{email},update_time=#{updateTime} where id=#{id}")
    void update(User user);

    @Update("update user set user_pic=#{avaterUrl},update_time=now() where id=#{id}")
    void updateAvatar(String avatarUrl,Integer id);

    @Update("update user set password=#{md5Sring},update_time=now() where id=#{id}")
    void updatePwd(String md5String, Integer id);
}

pojo

Article

java 复制代码
package org.example.pojo;


import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import lombok.Data;
import org.example.anno.State;
import org.hibernate.validator.constraints.URL;

import java.time.LocalDateTime;
@Data
public class Article {
    private Integer id;//主键ID
    @NotEmpty
    @Pattern(regexp = "^\\S{1,10}$")
    private String title;//文章标题
    @NotEmpty
    private String content;//文章内容
    @NotEmpty
    @URL
    private String coverImg;//封面图像
    @State
    private String state;//发布状态 已发布|草稿
    @NotNull
    private Integer categoryId;//文章分类id
    private Integer createUser;//创建人ID
    private LocalDateTime createTime;//创建时间
    private LocalDateTime updateTime;//更新时间
}

Category

java 复制代码
package org.example.pojo;

import com.fasterxml.jackson.annotation.JsonFormat;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.groups.Default;
import lombok.Data;

import java.time.LocalDateTime;
@Data
public class Category {
    @NotNull(groups = Update.class)
    private Integer id;//主键ID
    @NotEmpty
    private String categoryName;//分类名称
    @NotEmpty
    private String categoryAlias;//分类别名
    private Integer createUser;//创建人ID
    @JsonFormat(pattern =  "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;//创建时间
    @JsonFormat(pattern =  "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updateTime;//更新时间

    //如果说某个校验没有指定分组,默认属于Default分组
    //分组之间可以继承,A extend B 那么A中拥有B中所有的校验项

    public interface Add extends Default {
    }
    public interface Update extends Default {
    }
}

PageBean

java 复制代码
package org.example.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

//分页返回结果对象
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PageBean <T>{
    private Long total;//总条数
    private List<T> items;//当前页数据集合
}

Result

java 复制代码
package org.example.pojo;


import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

//统一响应结果
@NoArgsConstructor
@AllArgsConstructor
@Data
public class Result<T> {
    private Integer code;//业务状态码  0-成功  1-失败
    private String message;//提示信息
    private T data;//响应数据

    //快速返回操作成功响应结果(带响应数据)
    public static <E> Result<E> success(E data) {
        return new Result<>(0, "操作成功", data);
    }

    //快速返回操作成功响应结果
    public static Result success() {
        return new Result(0, "操作成功", null);
    }

    public static Result error(String message) {
        return new Result(1, message, null);
    }
}

User

java 复制代码
package org.example.pojo;

import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import lombok.Data;

import java.time.LocalDateTime;
@Data
public class User {
    @NotNull
    private Integer id;//主键ID
    private String username;//用户名
    @JsonIgnore//让springmvc把当前对象转换成json字符串的时候,忽略password,最终的json字符串中就没有password这个属性了
    private String password;//密码
    @NotEmpty
    @Pattern(regexp ="^\\S{1,10}$")
    private String nickname;//昵称
    @NotEmpty
    @Email
    private String email;//邮箱
    private String userPic;//用户头像地址
    private LocalDateTime createTime;//创建时间
    private LocalDateTime updateTime;//更新时间
}

service

ArticleService

java 复制代码
package org.example.service.impl;

import org.example.pojo.Article;
import org.example.pojo.PageBean;
import org.example.pojo.Result;

public interface ArticleService {
    //新增文章
    void add(Article article);

    //条件分页列表查询
    PageBean<Article> list(Integer pageNum, Integer pageSize, Integer categoryId, String state);

    //更新文章
    Result updateArticle(Article article);

    //获取文章
    Result getArticleDetail(Integer id);

    //删除文章
    Result deleteArticle(Integer id);
}

CategoryService

java 复制代码
package org.example.service.impl;

import org.example.pojo.Category;

import java.util.List;

public interface CategoryService {
    //新增分类
    void add(Category category);

    //列表查询
    List<Category> list();

    //根据id查询分类信息
    Category findById(Integer id);

    //更新分类
    void update(Category category);

    //删除分类
    boolean delete(Integer id);
}

UserService

java 复制代码
package org.example.service.impl;

import org.example.pojo.User;

public interface UserService {
    //根据用户名查询用户
    User findByUserName(String username);

    //注册
    void register(String username, String password);

    //更新
    void update(User user);
    //更新头像
    void updateAvatar(String avatarUrl);

    //更新密码
    void updatePwd(String newPwd);
}

serviceImpl

ArticleServiceImpl

java 复制代码
package org.example.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.example.mapper.ArticleMapper;
import org.example.pojo.Article;
import org.example.pojo.PageBean;
import org.example.pojo.Result;
import org.example.utils.ThreadLocalUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

@Service
public class ArticleServiceImpl implements ArticleService {
    @Autowired
    private ArticleMapper articleMapper;
    @Override
    public void add(Article article) {
    //补充属性值
        article.setCreateTime(LocalDateTime.now());
        article.setUpdateTime(LocalDateTime.now());
        Map<String,Object> map= ThreadLocalUtil.get();
        Integer userId=(Integer)map.get("id");
        article.setCreateUser(userId);
        articleMapper.add(article);
    }

    @Override
    public PageBean<Article> list(Integer pageNum, Integer pageSize, Integer categoryId, String state) {
        //1.创建PageBean对象
        PageBean<Article> pb=new PageBean<>();
        //2.开启分页查询 pageHelper
        PageHelper.startPage(pageNum,pageSize);
        //3.调用mapper
        Map<String,Object> map= ThreadLocalUtil.get();
        Integer userId=(Integer)map.get("id");
        List<Article> as=articleMapper.list(userId,categoryId,state);
        //Page中提供了方法,可以获取PageHelper分页查询后 得到的总记录条数和当前页数据
        Page<Article> p=(Page<Article>)as;
        //把数据填充到PageBean对象中
        pb.setTotal(p.getTotal());
        pb.setItems(p.getResult());
        return pb;
    }

    @Override
    public Result updateArticle(Article article) {
        //验证文章是否存在
        if(articleMapper.existsById(article.getId())==0){
            return Result.error("文章不存在");
        }
        // 验证分类是否存在
        if (articleMapper.existsCategoryById(article.getCategoryId()) == 0) {
            return Result.error("分类不存在");
        }
        // 验证状态值
        if (!"已发布".equals(article.getState()) && !"草稿".equals(article.getState())) {
            return Result.error("状态值必须是'已发布'或'草稿'");
        }
        // 执行更新
        int rows = articleMapper.updateArticle(article);
        if (rows > 0) {
            return Result.success();
        } else {
            return Result.error("更新文章失败");
        }
    }

    @Override
    public Result<Article> getArticleDetail(Integer id) {
        // 参数验证
        if (id == null || id <= 0) {
            return Result.error("文章ID不能为空");
        }
        // 查询文章详情
        Article articleDetail = articleMapper.selectArticleDetailById(id);
        if (articleDetail == null) {
            return Result.error("文章不存在");
        }
        return Result.success(articleDetail);
    }

    @Override
    @Transactional  // 添加事务注解,确保删除操作的原子性
    public Result deleteArticle(Integer id) {
        // 1. 参数验证
        if (id == null || id <= 0) {
            return Result.error("文章ID不能为空");
        }
        // 2. 检查文章是否存在
        if (articleMapper.existsById(id) == 0) {
            return Result.error("文章不存在");
        }
        // 3. 执行删除操作
        int affectedRows = articleMapper.deleteArticleById(id);
        // 4. 检查删除结果
        if (affectedRows > 0) {
            return Result.success(null);
        } else {
            return Result.error("删除文章失败");
        }
    }
}

CategoryServiceImpl

java 复制代码
package org.example.service.impl;

import org.example.mapper.CategoryMapper;
import org.example.pojo.Category;
import org.example.utils.ThreadLocalUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class CategoryServiceImpl implements  CategoryService {
    @Autowired
    private CategoryMapper categoryMapper;
    @Override
    public void add(Category category) {
        //补充属性值
        category.setCreateTime(LocalDateTime.now());
        category.setUpdateTime(LocalDateTime.now());
        Map<String,Object> map = ThreadLocalUtil.get();
        Integer userId = (Integer)map.get("id");
        category.setCreateUser(userId);
        categoryMapper.add(category);
    }

    @Override
    public List<Category> list() {
        //和获取用户id
        Map<String,Object> map=ThreadLocalUtil.get();
        Integer userId = (Integer)map.get("id");
        return categoryMapper.list(userId);  //当前用户id
    }

    @Override
    public Category findById(Integer id) {
        Category c=categoryMapper.findById(id);
        return c;
    }

    @Override
    public void update(Category category) {
        categoryMapper.update(category);
    }

    @Override
    public boolean delete(Integer id) {
        categoryMapper.delete(id);
        if(categoryMapper.findById(id) == null){
            return false;
        }
        categoryMapper.delete(id);
        return true;
    }
}

UserServiceImpl

java 复制代码
package org.example.service.impl;

import org.example.mapper.UserMapper;
import org.example.pojo.User;
import org.example.utils.Md5Util;
import org.example.utils.ThreadLocalUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Map;

@Service
public class UserServiceImpl implements UserService{
    @Autowired
    private UserMapper userMapper;
    @Override
    public User findByUserName(String username) {
        User u=userMapper.findByUserName(username);
        return u;
    }

    @Override
    public void register(String username, String password) {
        //加密
        String Md5string=Md5Util.getMD5String(password);
        //添加
        userMapper.add(username,Md5string);
    }

    @Override
    public void update(User user) {
        user.setUpdateTime(LocalDateTime.now());
        userMapper.update(user);
    }

    @Override
    public void updateAvatar(String avatarUrl) {
        Map<String,Object> map=ThreadLocalUtil.get();
        Integer id= (Integer) map.get("id");
        userMapper.updateAvatar(avatarUrl,id);
    }

    @Override
    public void updatePwd(String newPwd) {
        Map<String,Object> map=ThreadLocalUtil.get();
        Integer id= (Integer) map.get("id");
        userMapper.updatePwd(Md5Util.getMD5String(newPwd),id);
    }
}

utils

AliOssUtil

java 复制代码
package org.example.utils;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.ClientException;

import java.io.File;

public class AliOssUtil {
    private static final String ENDPOINT = "https://oss-cn-beijing.aliyuncs.com";
    private static final String ACCESS_KEY_ID = "LTAI5tLzrKe4J2THBjTNEt9T";
    private static final String ACCESS_KEY_SECRET = "8mfOMVxLo85VnH4pyddw43uxDIDwxu";
    private static final String BUCKET_NAME = "bigeventxy";

    public static void main(String[] args) {
        // 最简单的方式创建OSS客户端
        OSS ossClient = new OSSClientBuilder().build(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);

        try {
            File file = new File("D:\\rush\\files\\001.png");
            if (!file.exists()) {
                System.out.println("文件不存在: " + file.getAbsolutePath());
                return;
            }

            PutObjectRequest putObjectRequest = new PutObjectRequest(BUCKET_NAME, "001.png", file);
            PutObjectResult result = ossClient.putObject(putObjectRequest);

            String fileUrl = "https://" + BUCKET_NAME + "." + ENDPOINT.replace("https://", "") + "/001.png";
            System.out.println("文件上传成功!");
            System.out.println("文件URL: " + fileUrl);

        } catch (OSSException oe) {
            System.out.println("OSS错误: " + oe.getErrorMessage());
            System.out.println("错误代码: " + oe.getErrorCode());
        } catch (ClientException ce) {
            System.out.println("客户端错误: " + ce.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
}

JwtUtil

java 复制代码
package org.example.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;

import java.util.Date;
import java.util.Map;

public class JwtUtil {

    private static final String KEY = "itheima";
	
	//接收业务数据,生成token并返回
    public static String genToken(Map<String, Object> claims) {
        return JWT.create()
                .withClaim("claims", claims)
                .withExpiresAt(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 12))
                .sign(Algorithm.HMAC256(KEY));
    }

	//接收token,验证token,并返回业务数据
    public static Map<String, Object> parseToken(String token) {
        return JWT.require(Algorithm.HMAC256(KEY))
                .build()
                .verify(token)
                .getClaim("claims")
                .asMap();
    }

}

Md5Util

java 复制代码
package org.example.utils;


import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class Md5Util {
    /**
     * 默认的密码字符串组合,用来将字节转换成 16 进制表示的字符,apache校验下载的文件的正确性用的就是默认的这个组合
     */
    protected static char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    protected static MessageDigest messagedigest = null;

    static {
        try {
            messagedigest = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException nsaex) {
            System.err.println(Md5Util.class.getName() + "初始化失败,MessageDigest不支持MD5Util。");
            nsaex.printStackTrace();
        }
    }

    /**
     * 生成字符串的md5校验值
     *
     * @param s
     * @return
     */
    public static String getMD5String(String s) {
        return getMD5String(s.getBytes());
    }

    /**
     * 判断字符串的md5校验码是否与一个已知的md5码相匹配
     *
     * @param password  要校验的字符串
     * @param md5PwdStr 已知的md5校验码
     * @return
     */
    public static boolean checkPassword(String password, String md5PwdStr) {
        String s = getMD5String(password);
        return s.equals(md5PwdStr);
    }


    public static String getMD5String(byte[] bytes) {
        messagedigest.update(bytes);
        return bufferToHex(messagedigest.digest());
    }

    private static String bufferToHex(byte bytes[]) {
        return bufferToHex(bytes, 0, bytes.length);
    }

    private static String bufferToHex(byte bytes[], int m, int n) {
        StringBuffer stringbuffer = new StringBuffer(2 * n);
        int k = m + n;
        for (int l = m; l < k; l++) {
            appendHexPair(bytes[l], stringbuffer);
        }
        return stringbuffer.toString();
    }

    private static void appendHexPair(byte bt, StringBuffer stringbuffer) {
        char c0 = hexDigits[(bt & 0xf0) >> 4];// 取字节中高 4 位的数字转换, >>>
        // 为逻辑右移,将符号位一起右移,此处未发现两种符号有何不同
        char c1 = hexDigits[bt & 0xf];// 取字节中低 4 位的数字转换
        stringbuffer.append(c0);
        stringbuffer.append(c1);
    }

}

ThreadLocalUtil

java 复制代码
package org.example.utils;

import java.util.HashMap;
import java.util.Map;

/**
 * ThreadLocal 工具类
 */
@SuppressWarnings("all")
public class ThreadLocalUtil {
    //提供ThreadLocal对象,
    private static final ThreadLocal THREAD_LOCAL = new ThreadLocal();

    //根据键获取值
    public static <T> T get(){
        return (T) THREAD_LOCAL.get();
    }
	
    //存储键值对
    public static void set(Object value){
        THREAD_LOCAL.set(value);
    }


    //清除ThreadLocal 防止内存泄漏
    public static void remove(){
        THREAD_LOCAL.remove();
    }
}

Validation

StateValidation

java 复制代码
package org.example.Validation;

import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import org.example.anno.State;

public class StateValidation implements ConstraintValidator<State, String> {
    /**
     * @param value 将来要校验的数据
     * @param context context in which the constraint is evaluated
     *
     * @return 如果返回false则校验不通过,如果返回true,则校验不通过
     */
    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        //提供校验规则
        if (value == null ) {
            return false;
        }
        if(value.equals("已发布")||value.equals("草稿")){
           return true;
        }
        return false;
    }
}

resource

mapper

ArticleMapper.XML

java 复制代码
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.example.mapper.ArticleMapper">
    <!--动态sql-->
    <select id="list" resultType="org.example.pojo.Article">
        select * from article
        <where>
            <if test="categoryId!=null">
                category_id=#{categoryId}
            </if>

        <if test="state!=null">
            and state=#{state}
        </if>
        and create_user=#{userId}
        </where>
    </select>
</mapper>

application.yml

java 复制代码
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/big_event
    username: root
    password:
  data:
    redis:
      host: localhost
      port: 6379

mybatis:
  configuration:
    map-underscore-to-camel-case: true #开启驼峰命名和下划线命名的自动转化
相关推荐
q***965836 分钟前
Spring总结(上)
java·spring·rpc
思密吗喽38 分钟前
宠物商城系统
java·开发语言·vue·毕业设计·springboot·课程设计·宠物
csbysj202041 分钟前
Lua 函数
开发语言
头发还在的女程序员42 分钟前
三天搞定招聘系统!附完整源码
开发语言·python
温轻舟1 小时前
Python自动办公工具06-设置Word文档中表格的格式
开发语言·python·word·自动化工具·温轻舟
p***c9491 小时前
PHP在电商中的电商系统
开发语言·php
Z***25801 小时前
JavaScript在Node.js中的Deno
开发语言·javascript·node.js
ss2731 小时前
019:深入解析可重入互斥锁:原理、实现与线程安全实践
java·数据库·redis
luyun0202021 小时前
牛批了,某音录播神器
java·windows·figma