Java 小项目开发日记 03(文章分类接口的开发)
项目目录
配置文件(pom.xml)
<project xmlns="http: //maven.apache.org/POM/4.0.0" xmlns: xsi="http: //www.w3.org/2001/XMLSchema- instance"
xsi: schemaLocation="http: //maven.apache.org/POM/4.0.0 http: //maven.apache.org/xsd/maven- 4.0.0.xsd">
<modelVersion> 4.0.0</modelVersion>
<!-- 继承父工程- - >
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.6</version>
</parent>
<groupId>com.zhong</groupId>
<artifactId>big-event</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name> big- event</name>
<url> http: //maven.apache.org</url>
<properties>
<project.build.sourceEncoding> UTF- 8</project.build.sourceEncoding>
</properties>
<dependencies>
<!--web 依赖- - >
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--MyBatis 依赖-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
<!--MySQL 依赖- - >
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.29</version>
</dependency>
<!--lombok 依赖-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- 参数校验依赖- - >
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!--jwt 令牌验证- - >
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>4.4.0</version>
</dependency>
<!-- 单元测试依赖- - >
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
</project>
resources 配置
spring :
datasource :
driver-class-name : com.mysql.cj.jdbc.Driver
url : jdbc: mysql: //localhost: 3306/big_event
username : root
password : 123456
mybatis :
configuration :
map-underscore-to-camel-case : true
config
package com. zhong. config ;
import com. zhong. 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
package com. zhong. controller ;
import com. zhong. pojo. Category ;
import com. zhong. pojo. Result ;
import com. zhong. service. 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 > > findAll ( ) {
List < Category > category = categoryService. findAll ( ) ;
return Result . success ( category) ;
}
@GetMapping ( "/detail" )
public Result < Category > findCategoryById ( @RequestHeader @Validated ( Category. Update . class ) Integer id) {
return Result . success ( categoryService. findCategoryById ( id) ) ;
}
@PutMapping
public Result updateCategory ( @RequestBody @Validated ( Category. Update . class ) Category category) {
categoryService. updateCategory ( category) ;
return Result . success ( ) ;
}
@DeleteMapping
public Result deleteCategory ( @RequestHeader @Validated ( Category. Update . class ) Integer id) {
categoryService. deleteCategory ( id) ;
return Result . success ( ) ;
}
}
package com. zhong. controller ;
import com. zhong. pojo. Result ;
import com. zhong. pojo. User ;
import com. zhong. service. UserService ;
import com. zhong. utils. JwtUtil ;
import com. zhong. utils. Md5Util ;
import com. zhong. utils. ThreadLocalUtil ;
import jakarta. validation. constraints. Pattern ;
import org. springframework. beans. factory. annotation. Autowired ;
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 ;
@RestController
@RequestMapping ( "/user" )
@Validated
public class UserController {
@Autowired
private UserService userService;
@PostMapping ( "/register" )
public Result register ( @Pattern ( regexp = "^\\S{6,16}$" ) String username, @Pattern ( regexp = "^\\S{6,16}$" ) String password) {
User user = userService. findByUserName ( username) ;
if ( user == null ) {
userService. registerUser ( username, password) ;
return Result . success ( ) ;
} else {
return Result . error ( "用户名已被占用......" ) ;
}
}
@PostMapping ( "/login" )
public Result < String > login ( @Pattern ( regexp = "^\\S{2,10}$" ) String username, @Pattern ( regexp = "^\\S{6,16}$" ) String password) {
User user = userService. findByUserName ( username) ;
if ( user == null ) {
return Result . error ( "用户不存在......" ) ;
}
if ( Md5Util . checkPassword ( password, user. getPassword ( ) ) ) {
HashMap < String , Object > claims = new HashMap < > ( ) ;
claims. put ( "id" , user. getId ( ) ) ;
claims. put ( "username" , user. getUsername ( ) ) ;
return Result . success ( JwtUtil . genToken ( claims) ) ;
}
return Result . error ( "密码错误......" ) ;
}
@GetMapping ( "/userinfo" )
public Result < User > getUserInfo ( ) {
Map < String , Object > user = ThreadLocalUtil . get ( ) ;
User userInfo = userService. getUserInfo ( ( Integer ) user. get ( "id" ) ) ;
return Result . success ( userInfo) ;
}
@PutMapping ( "/update" )
public Result update ( @RequestBody @Validated User user) {
if ( ! userService. update ( user) ) {
return Result . error ( "修改失败......" ) ;
}
return Result . success ( "修改成功!" ) ;
}
@PatchMapping ( "/updatepwd" )
public Result updatePassWord ( @RequestBody Map < String , String > params) {
String oldPwd = params. get ( "old_pwd" ) ;
String newPwd = params. get ( "new_pwd" ) ;
String rePwd = params. get ( "re_pwd" ) ;
if ( oldPwd. equals ( newPwd) || oldPwd. equals ( rePwd) ) {
return Result . error ( "修改密码与原密码相同......" ) ;
}
if ( ! StringUtils . hasLength ( oldPwd) || ! StringUtils . hasLength ( newPwd) || ! StringUtils . hasLength ( rePwd) ) {
return Result . error ( "密码不能为空......" ) ;
}
if ( ! newPwd. equals ( rePwd) ) {
return Result . error ( "新密码不一致......" ) ;
}
if ( ! userService. updatePassWord ( oldPwd, newPwd) ) {
return Result . error ( "原密码不匹配......" ) ;
}
return Result . success ( "修改密码成功!" ) ;
}
}
exception
package com. zhong. exception ;
import com. zhong. pojo. Result ;
import org. springframework. util. StringUtils ;
import org. springframework. web. bind. annotation. ExceptionHandler ;
import org. springframework. web. bind. annotation. RestControllerAdvice ;
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler ( Exception . class )
public Result handlerException ( Exception e) {
e. printStackTrace ( ) ;
return Result . error ( StringUtils . hasLength ( e. getMessage ( ) ) ? e. getMessage ( ) : "操作失败" ) ;
}
}
interceptors
package com. zhong. interceptors ;
import com. zhong. utils. JwtUtil ;
import com. zhong. utils. ThreadLocalUtil ;
import jakarta. servlet. http. HttpServletRequest ;
import jakarta. servlet. http. HttpServletResponse ;
import org. springframework. stereotype. Component ;
import org. springframework. web. servlet. HandlerInterceptor ;
import java. util. Map ;
@Component
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle ( HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String token = request. getHeader ( "Authorization" ) ;
try {
Map < String , Object > claims = JwtUtil . parseToken ( token) ;
ThreadLocalUtil . set ( claims) ;
return true ;
} catch ( Exception e) {
response. setStatus ( 401 ) ;
return false ;
}
}
@Override
public void afterCompletion ( HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
ThreadLocalUtil . remove ( ) ;
}
}
mapper
package com. zhong. mapper ;
import com. zhong. pojo. Category ;
import org. apache. ibatis. annotations. * ;
import java. util. List ;
@Mapper
public interface CategoryMapper {
@Insert ( "insert into category(category_name, category_alias, create_user, create_time, update_time) values (#{categoryName}, #{categoryAlias}, #{createUser} , now(), now())" )
void add ( Category category) ;
@Select ( "select * from category where create_user = #{userId}" )
List < Category > findAll ( Integer userId) ;
@Select ( "select * from category where id = #{id}" )
Category findCategoryById ( Integer id) ;
@Update ( "update category set category_name = #{categoryName}, category_alias = #{categoryAlias}, update_time = now() where id = #{id}" )
void updateCategory ( Category category) ;
@Delete ( "delete from category where id = #{id}" )
void deleteCategory ( Integer id) ;
}
package com. zhong. mapper ;
import com. zhong. pojo. User ;
import org. apache. ibatis. annotations. Insert ;
import org. apache. ibatis. annotations. Mapper ;
import org. apache. ibatis. annotations. Select ;
import org. apache. ibatis. annotations. Update ;
@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 registerUser ( String username, String password) ;
@Select ( "select * from user where id = #{id}" )
User getUserInfo ( Integer id) ;
@Update ( "update user set username = #{user.username}, nickname = #{user.nickname}, email = #{user.email}, user_pic=#{user.userPic}, update_time = now() where id = #{myId};" )
Boolean update ( User user, Integer myId) ;
@Update ( "update user set password = #{newP}, update_time = now() where id= #{id} AND password = #{oldP}" )
boolean updatePassWord ( Integer id, String oldP, String newP) ;
}
pojo
package com. zhong. pojo ;
import com. fasterxml. jackson. annotation. JsonFormat ;
import com. fasterxml. jackson. annotation. JsonIgnore ;
import jakarta. validation. constraints. NotEmpty ;
import jakarta. validation. constraints. NotNull ;
import jakarta. validation. groups. Default ;
import lombok. Builder ;
import lombok. Data ;
import java. time. LocalDateTime ;
@Data
public class Category {
@NotNull ( groups = Update . class )
private Integer id;
@NotEmpty
private String categoryName;
@NotEmpty
private String categoryAlias;
@JsonIgnore
private Integer createUser;
@JsonFormat ( pattern = "yyyy-MM-dd HH:mm:ss" )
private LocalDateTime createTime;
@JsonFormat ( pattern = "yyyy-MM-dd HH:mm:ss" )
private LocalDateTime updateTime;
public interface Add extends Default {
}
public interface Update extends Default {
}
}
package com. zhong. pojo ;
import lombok. AllArgsConstructor ;
import lombok. Data ;
import lombok. NoArgsConstructor ;
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Result < T > {
private Integer code;
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 ) ;
}
}
package com. zhong. pojo ;
import com. fasterxml. jackson. annotation. JsonFormat ;
import com. fasterxml. jackson. annotation. JsonIgnore ;
import jakarta. validation. constraints. Email ;
import jakarta. validation. constraints. NotEmpty ;
import jakarta. validation. constraints. Pattern ;
import lombok. Data ;
import lombok. NoArgsConstructor ;
import lombok. NonNull ;
import org. hibernate. validator. constraints. URL ;
import java. time. LocalDateTime ;
@Data
@NoArgsConstructor
public class User {
@NonNull
private Integer id;
@NotEmpty
@Pattern ( regexp = "^\\S{2,10}$" )
private String username;
@JsonIgnore
private String password;
@NotEmpty
@Pattern ( regexp = "\\S{1,12}$" )
private String nickname;
@NotEmpty
@Email
private String email;
@URL
private String userPic;
@JsonFormat ( pattern = "yyyy-MM-dd HH:mm:ss" )
private LocalDateTime createTime;
@JsonFormat ( pattern = "yyyy-MM-dd HH:mm:ss" )
private LocalDateTime updateTime;
}
service
package com. zhong. service. impl ;
import com. zhong. mapper. CategoryMapper ;
import com. zhong. pojo. Category ;
import com. zhong. service. CategoryService ;
import com. zhong. utils. GetNowLoginIdUtil ;
import org. springframework. beans. factory. annotation. Autowired ;
import org. springframework. stereotype. Service ;
import java. util. List ;
@Service
public class CategoryServiceImpl implements CategoryService {
@Autowired
private CategoryMapper categoryMapper;
@Override
public void add ( Category category) {
Integer id = GetNowLoginIdUtil . getID ( ) ;
category. setCreateUser ( id) ;
categoryMapper. add ( category) ;
}
@Override
public List < Category > findAll ( ) {
Integer id = GetNowLoginIdUtil . getID ( ) ;
return categoryMapper. findAll ( id) ;
}
@Override
public Category findCategoryById ( Integer id) {
return categoryMapper. findCategoryById ( id) ;
}
@Override
public void updateCategory ( Category category) {
categoryMapper. updateCategory ( category) ;
}
@Override
public void deleteCategory ( Integer id) {
categoryMapper. deleteCategory ( id) ;
}
}
package com. zhong. service. impl ;
import com. auth0. jwt. JWT ;
import com. auth0. jwt. JWTVerifier ;
import com. auth0. jwt. algorithms. Algorithm ;
import com. auth0. jwt. interfaces. Claim ;
import com. auth0. jwt. interfaces. DecodedJWT ;
import com. zhong. mapper. UserMapper ;
import com. zhong. pojo. User ;
import com. zhong. service. UserService ;
import com. zhong. utils. JwtUtil ;
import com. zhong. utils. Md5Util ;
import org. springframework. beans. factory. annotation. Autowired ;
import org. springframework. stereotype. Service ;
import java. util. Map ;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public User findByUserName ( String username) {
return userMapper. findByUserName ( username) ;
}
@Override
public void registerUser ( String username, String password) {
String md5String = Md5Util . getMD5String ( password) ;
userMapper. registerUser ( username, md5String) ;
}
@Override
public User getUserInfo ( Integer id) {
return userMapper. getUserInfo ( id) ;
}
@Override
public Boolean update ( User user) {
return userMapper. update ( user) ;
}
}
package com. zhong. service ;
import com. zhong. pojo. Category ;
import java. util. List ;
public interface CategoryService {
void add ( Category category) ;
List < Category > findAll ( ) ;
Category findCategoryById ( Integer id) ;
void updateCategory ( Category category) ;
void deleteCategory ( Integer id) ;
}
package com. zhong. service ;
import com. zhong. pojo. User ;
public interface UserService {
User findByUserName ( String username) ;
void registerUser ( String username, String password) ;
User getUserInfo ( Integer id) ;
Boolean update ( User user) ;
}
utils
package com. zhong. utils ;
import java. util. Map ;
public class GetNowLoginIdUtil {
public static Integer getID ( ) {
Map < String , Object > claims = ThreadLocalUtil . get ( ) ;
return ( Integer ) claims. get ( "id" ) ;
}
}
package com. zhong. 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 = "zhong" ;
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 ) ) ;
}
public static Map < String , Object > parseToken ( String token) {
return JWT . require ( Algorithm . HMAC256 ( KEY ) )
. build ( )
. verify ( token)
. getClaim ( "claims" )
. asMap ( ) ;
}
}
package com. zhong. utils ;
import java. security. MessageDigest ;
import java. security. NoSuchAlgorithmException ;
public class Md5Util {
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 ( ) ;
}
}
public static String getMD5String ( String s) {
return getMD5String ( s. getBytes ( ) ) ;
}
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 ] ;
char c1 = hexDigits[ bt & 0xf ] ;
stringbuffer. append ( c0) ;
stringbuffer. append ( c1) ;
}
}
package com. zhong. utils ;
@SuppressWarnings ( "all" )
public class ThreadLocalUtil {
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) ;
}
public static void remove ( ) {
THREAD_LOCAL . remove ( ) ;
}
}
BigEventApplication
package com. zhong ;
import org. springframework. boot. SpringApplication ;
import org. springframework. boot. autoconfigure. SpringBootApplication ;
@SpringBootApplication
public class BigEventApplication {
public static void main ( String [ ] args) {
SpringApplication . run ( BigEventApplication . class , args) ;
}
}