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.Driverurl : jdbc: mysql: //localhost: 3306/big_eventusername : rootpassword : 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) ; }
}