做移門圖的 網(wǎng)站有哪些最近一周的重大熱點(diǎn)新聞
目錄
環(huán)境準(zhǔn)備
用戶模塊
注冊
注冊接口文檔?
?編輯?實(shí)現(xiàn)結(jié)構(gòu)
Spring Validation
?登錄
登錄的接口文檔
實(shí)現(xiàn)登錄邏輯?
JWT令牌
完善登錄認(rèn)證?
?攔截器
獲取用戶詳細(xì)信息?
接口文檔
?Usercontroller類中編寫方法接口
忽略屬性返回
?優(yōu)化代碼ThreadLocal
?更新用戶基本信息
接口文檔
完善代碼?
對實(shí)體對象參數(shù)完成校驗(yàn)
更新用戶頭像?
接口文檔?
?完善代碼?
對傳入地址完成參數(shù)校驗(yàn)?
更改用戶密碼?
?接口文檔
?完善代碼?
后端開發(fā)流程思想
項(xiàng)目后端整體需要完成的內(nèi)容:?
用戶模塊:
注冊、登錄、獲取用戶詳細(xì)信息、更新用戶基本信息、更新用戶頭像、更新用戶密碼
文章分類:
文章分類列表、新增文章分類、更新文章分類、獲取文章分類詳情、刪除文章分類?
文章管理:
新增文章、更新文章、獲取文章詳情、刪除文章、文章列表(條件分頁)文件上傳
環(huán)境準(zhǔn)備
創(chuàng)建數(shù)據(jù)庫和表結(jié)構(gòu)
-- 創(chuàng)建數(shù)據(jù)庫
create database springboots;-- 使用數(shù)據(jù)庫
use springboots;-- 用戶表
create table user (id int unsigned primary key auto_increment comment 'ID',username varchar(20) not null unique comment '用戶名',password varchar(32) comment '密碼',nickname varchar(10) default '' comment '昵稱',email varchar(128) default '' comment '郵箱',user_pic varchar(128) default '' comment '頭像',create_time datetime not null comment '創(chuàng)建時(shí)間',update_time datetime not null comment '修改時(shí)間'
) comment '用戶表';-- 分類表
create table category(id int unsigned primary key auto_increment comment 'ID',category_name varchar(32) not null comment '分類名稱',category_alias varchar(32) not null comment '分類別名',create_user int unsigned not null comment '創(chuàng)建人ID',create_time datetime not null comment '創(chuàng)建時(shí)間',update_time datetime not null comment '修改時(shí)間',constraint fk_category_user foreign key (create_user) references user(id) -- 外鍵約束
);-- 文章表
create table article(id int unsigned primary key auto_increment comment 'ID',title varchar(30) not null comment '文章標(biāo)題',content varchar(10000) not null comment '文章內(nèi)容',cover_img varchar(128) not null comment '文章封面',state varchar(3) default '草稿' comment '文章狀態(tài): 只能是[已發(fā)布] 或者 [草稿]',category_id int unsigned comment '文章分類ID',create_user int unsigned not null comment '創(chuàng)建人ID',create_time datetime not null comment '創(chuàng)建時(shí)間',update_time datetime not null comment '修改時(shí)間',constraint fk_article_category foreign key (category_id) references category(id),-- 外鍵約束constraint fk_article_user foreign key (create_user) references user(id) -- 外鍵約束
)
創(chuàng)建springboot工程引入對應(yīng)的依賴?
<!--web 起步依賴--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!--mybatis 起步依賴--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>3.0.3</version></dependency><!--mysql 驅(qū)動--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.26</version></dependency><!--單元測試依賴--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>
?配置文件application.yml中引入mybatis的配置信息
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql:///springboots?useSSL=falseusername: rootpassword: root
?創(chuàng)建包結(jié)構(gòu)
pojo目錄下創(chuàng)建實(shí)體類
import java.time.LocalDateTime;@Data
public class Article {private Integer id;//主鍵IDprivate String title;//文章標(biāo)題private String content;//文章內(nèi)容private String coverImg;//封面圖像private String state;//發(fā)布狀態(tài) 已發(fā)布|草稿private Integer categoryId;//文章分類idprivate Integer createUser;//創(chuàng)建人IDprivate LocalDateTime createTime;//創(chuàng)建時(shí)間private LocalDateTime updateTime;//更新時(shí)間
}
import java.time.LocalDateTime;@Data
public class Category {private Integer id;//主鍵IDprivate String categoryName;//分類名稱private String categoryAlias;//分類別名private Integer createUser;//創(chuàng)建人IDprivate LocalDateTime createTime;//創(chuàng)建時(shí)間private LocalDateTime updateTime;//更新時(shí)間
}
import java.time.LocalDateTime;@Data
public class User {private Integer id;//主鍵IDprivate String username;//用戶名private String password;//密碼private String nickname;//昵稱private String email;//郵箱private String userPic;//用戶頭像地址private LocalDateTime createTime;//創(chuàng)建時(shí)間private LocalDateTime updateTime;//更新時(shí)間
}
//統(tǒng)一響應(yīng)結(jié)果import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@NoArgsConstructor //生成無參構(gòu)造器
@AllArgsConstructor //生成全參構(gòu)造器
public class Result<T> {private Integer code;//業(yè)務(wù)狀態(tài)碼 0-成功 1-失敗private String message;//提示信息private T data;//響應(yīng)數(shù)據(jù)//快速返回操作成功響應(yīng)結(jié)果(帶響應(yīng)數(shù)據(jù))public static <E> Result<E> success(E data) {return new Result<>(0, "操作成功", data);}//快速返回操作成功響應(yīng)結(jié)果public static Result success() {return new Result(0, "操作成功", null);}public static Result error(String message) {return new Result(1, message, null);}
}
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.util.List;//分頁返回結(jié)果對象
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PageBean <T>{private Long total;//總條數(shù)private List<T> items;//當(dāng)前頁數(shù)據(jù)集合
}
使用lombok在編譯階段,為實(shí)體類自動生成setter getter toString
pom文件中引入依賴
<!-- lombok依賴--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency>
在Article、Category、User、實(shí)體類上都添加@Data注解
?
編譯后編譯目錄實(shí)體類自動生成setter getter toString
用戶模塊
用戶表結(jié)構(gòu)
??
注冊
注冊接口文檔?
?
?實(shí)現(xiàn)結(jié)構(gòu)
UserController?
@PostMapping(“/register”)
public 返回值類型 register(String username, String password){//用戶名是否已被占用//注冊
}
UserService
//根據(jù)用戶名查詢用戶public User findByUsername(String username) {}//注冊public void register(String username,String password) {}
UserMapper?
-- 查詢
select * from user where username=?;
-- 插入
insert into user(username,password,create_time,update_time) values (?,?,?,?);
創(chuàng)建好接口文件和類文件
?編寫Usercontroller類的內(nèi)容
@RestController //控制器
@RequestMapping("/user") //請求映射路徑
public class Usercontroller {@Autowiredprivate UserService userService; //注入U(xiǎn)serService接口@PostMapping("/register")public Result register(String username,String password){//查詢用戶User u = userService.findByUserName(username);if (u == null){//沒有占用//注冊userService.register(username,password);return Result.success();} else{//已占用return Result.error("用戶名已被占用");}}
}
報(bào)紅是因?yàn)閁serService接口中的方法還沒創(chuàng)建,代碼中點(diǎn)中紅色的方法按住alt+回車自動跳到UserService創(chuàng)建方法
編寫UserService接口的內(nèi)容
public interface UserService {User findByUserName(String username);void register(String username,String password);
}
創(chuàng)建工具類Md5Util,加密算法用于對密碼加密后存入到數(shù)據(jù)庫中
package com.springboot.springboot_test.utils;import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;public class Md5Util {/*** 默認(rèn)的密碼字符串組合,用來將字節(jié)轉(zhuǎn)換成 16 進(jìn)制表示的字符,apache校驗(yàn)下載的文件的正確性用的就是默認(rèn)的這個(gè)組合*/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校驗(yàn)值** @param s* @return*/public static String getMD5String(String s) {return getMD5String(s.getBytes());}/*** 判斷字符串的md5校驗(yàn)碼是否與一個(gè)已知的md5碼相匹配** @param password 要校驗(yàn)的字符串* @param md5PwdStr 已知的md5校驗(yàn)碼* @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];// 取字節(jié)中高 4 位的數(shù)字轉(zhuǎn)換, >>>// 為邏輯右移,將符號位一起右移,此處未發(fā)現(xiàn)兩種符號有何不同char c1 = hexDigits[bt & 0xf];// 取字節(jié)中低 4 位的數(shù)字轉(zhuǎn)換stringbuffer.append(c0);stringbuffer.append(c1);}}
?完成?UserServiceimpl實(shí)體類中實(shí)現(xiàn)接口的方法
@Service
public class UserServiceimpl implements UserService {@Autowiredprivate UserMapper userMapper; //注入U(xiǎn)serMapper接口@Overridepublic User findByUserName(String username) {User u = userMapper.findByUserName(username);return u;}@Overridepublic void register(String username, String password) { //注冊//加密存儲到數(shù)據(jù)庫中String md5String = Md5Util.getMD5String(password); //使用加密方法//添加userMapper.add(username,md5String);}
}
完成UserMapper 接口中的方法
@Mapper
public interface UserMapper {//根據(jù)用戶名查詢用戶@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);
}
運(yùn)行項(xiàng)目使用接口測試工具查看
?數(shù)據(jù)庫添加成功
?對請求參數(shù)進(jìn)行校驗(yàn)
Spring Validation
是Spring 提供的一個(gè)參數(shù)校驗(yàn)框架,使用預(yù)定義的注解完成參數(shù)校驗(yàn)?
引入Spring Validation 起步依賴
<!--validation 起步依賴--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency>
定義全局處理器對不符合正則的參數(shù)校驗(yàn)失敗進(jìn)行異常處理?
import com.springboot.springboot_test.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 handleException(Exception e){e.printStackTrace();return Result.error(StringUtils.hasLength(e.getMessage()) ? e.getMessage() : "操作失敗");}
}
?在Controller類上添加@Validated注解 ,在參數(shù)前面添加@Pattern注解 寫上正則表達(dá)式
@RestController //控制器
@RequestMapping("/user") //請求映射路徑
@Validated
public class Usercontroller {@Autowiredprivate UserService userService; //注入U(xiǎn)serService接口@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("用戶名已被占用");}}
}
運(yùn)行項(xiàng)目使用接口測試工具查看,當(dāng)輸入?yún)?shù)不滿足要求時(shí)返回異常信息
參數(shù)滿足時(shí)返回成功并將數(shù)據(jù)添加到數(shù)據(jù)庫中
?登錄
登錄的接口文檔
實(shí)現(xiàn)登錄邏輯?
在Usercontroller類中編寫方法實(shí)現(xiàn)登錄邏輯
@PostMapping("login")public Result<String> login(@Pattern(regexp = "^\\S{5,16}$") String username, @Pattern(regexp = "^\\S{5,16}$") String password){//根據(jù)用戶名查詢用戶User loginUser = userService.findByUserName(username); //定義實(shí)例對象//判斷用戶是否存在if(loginUser == null){return Result.error("用戶名錯(cuò)誤");}//判斷密碼是否正確,將傳入的password參數(shù)轉(zhuǎn)成密文,再和數(shù)據(jù)庫中的密文進(jìn)行判斷是否相同if(Md5Util.getMD5String(password).equals(loginUser.getPassword())){//登錄成功return Result.success("jwt token 令牌……");}return Result.error("密碼錯(cuò)誤");}
運(yùn)行項(xiàng)目使用接口測試工具查看,數(shù)據(jù)庫中存在該用戶且用戶名密碼正確就登錄成功
?輸入不正確就返回錯(cuò)誤信息
JWT令牌
他定義了一種簡潔的、自包含的格式,用于通信雙方以json數(shù)據(jù)格式安全的傳輸信息。
通過Base64編碼完成:是一種基于64個(gè)可打印字符(A-Z ?a-z ?0-9 ?+ ?/)來表示二進(jìn)制數(shù)據(jù)的編碼方式。?
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.JTdCJTIybmFtZSUyMiUzQSUyMlRvbSUyMiUyQyUyMmlhdCUyMiUzQTE1MTYyMzkwMjIlN0Q=.SflKxwRJSMeKKF2QT4fwpMeJf...
jwt令牌的生成
?引入依賴
<!-- jwt --><dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>4.4.0</version></dependency>
新建測試類編寫生成密鑰測試示例
@Testpublic void testGen(){Map<String,Object> claims = new HashMap<>(); //定義map集合對象claims.put("id",1);claims.put("username","小王");//生成jwtString token = JWT.create().withClaim("user",claims).withExpiresAt(new Date(System.currentTimeMillis() + 1000*60*60*12)) //設(shè)置過期時(shí)間為12小時(shí).sign(Algorithm.HMAC256("miyao")); //指定算法,配置密鑰System.out.println(token); //輸出生成的jwt}
運(yùn)行查看生成好的jwt
?jwt令牌的驗(yàn)證
@Testpublic void testParse(){//定義字符串,模擬用戶傳遞過來的tokenString token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9" +".eyJ1c2VyIjp7ImlkIjoxLCJ1c2VybmFtZSI6IuWwj-eOiyJ9LCJleHAiOjE3MTQ1MDc2Mjh9" +".ey-mnHD2UDg5_ioGtjcLweBwkCnxERSKi_F_xw8G2-U";JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256("miyao")).build();DecodedJWT decodedJWT = jwtVerifier.verify(token); //驗(yàn)證token,生成一個(gè)解析后的JWT對象Map<String, Claim> claims = decodedJWT.getClaims();System.out.println(claims.get("user"));}
?運(yùn)行查看驗(yàn)證返回的信息
完善登錄認(rèn)證?
添加jwt工具類
public class JwtUtil {private static final String KEY = "miyao";//接收業(yè)務(wù)數(shù)據(jù),生成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,驗(yàn)證token,并返回業(yè)務(wù)數(shù)據(jù)public static Map<String, Object> parseToken(String token) {return JWT.require(Algorithm.HMAC256(KEY)).build().verify(token).getClaim("claims").asMap();}}
?在Usercontroller類中完成token生成與驗(yàn)證
@PostMapping("login")public Result<String> login(@Pattern(regexp = "^\\S{5,16}$") String username, @Pattern(regexp = "^\\S{5,16}$") String password){//根據(jù)用戶名查詢用戶User loginUser = userService.findByUserName(username); //定義實(shí)例對象//判斷用戶是否存在if(loginUser == null){return Result.error("用戶名錯(cuò)誤");}//判斷密碼是否正確,將傳入的password參數(shù)轉(zhuǎn)成密文,再和數(shù)據(jù)庫中的密文進(jìn)行判斷是否相同if(Md5Util.getMD5String(password).equals(loginUser.getPassword())){//登錄成功Map<String,Object> claims = new HashMap<>(); //定義map集合對象claims.put("id",loginUser.getId()); //添加idclaims.put("username",loginUser.getUsername()); //添加用戶名//生成jwtString token = JwtUtil.genToken(claims);return Result.success(token);}return Result.error("密碼錯(cuò)誤");}
?運(yùn)行測試,請求成功并返回生成的jwt
?訪問其他請求時(shí)的驗(yàn)證token示例,但是這種寫法如果接口太多就會寫很多重復(fù)的代碼,所以推薦使用攔截器來完成驗(yàn)證
?攔截器
?使用攔截器統(tǒng)一驗(yàn)證令牌,登錄和注冊接口需要放行
創(chuàng)建攔截器類
@Component
public class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception{//令牌驗(yàn)證String token = request.getHeader("Authorization");//驗(yàn)證tokentry{Map<String,Object> claims = JwtUtil.parseToken(token);return true; //放行} catch (Exception e){//http響應(yīng)碼為401response.setStatus(401);return false; //不放行}}
}
創(chuàng)建配置類 將該攔截器對象注冊到ioc容器中??
@Configuration
public class webConfig implements WebMvcConfigurer {@Autowiredprivate LoginInterceptor loginInterceptor; //注入LoginInterceptor類@Overridepublic void addInterceptors(InterceptorRegistry registry) {//登錄接口和注冊接口不攔截registry.addInterceptor(loginInterceptor).excludePathPatterns("/user/login","/user/register");}
}
獲取用戶詳細(xì)信息?
接口文檔
?Usercontroller類中編寫方法接口
@GetMapping("/userInfo")public Result<User> userInfo(@RequestHeader(name = "Authorization") String token){ //@RequestHeader設(shè)置請求頭//System.out.println(token);//從token中獲取用戶名Map<String,Object> map = JwtUtil.parseToken(token);String username = (String) map.get("username");User user = userService.findByUserName(username); //通過用戶名使用方法查詢r(jià)eturn Result.success(user); //返回對象}
啟動項(xiàng)目使用接口工具請求查看
請求頭:Authorization ,請求參數(shù):登錄的token
忽略屬性返回
查看返回結(jié)果發(fā)現(xiàn)把用戶的加密的密碼給返回出來了,這里需要屏蔽掉。
在pojo包下的Bean對象User類的成員變量中添加@JsonIgnore注解
@JsonIgnore //把當(dāng)前對象轉(zhuǎn)為json字符串的時(shí)候忽略掉這個(gè)屬性,最終返回結(jié)果就不包含這個(gè)private String password;//密碼
再重新運(yùn)行請求一下,password屬性已經(jīng)不會返回了
????????數(shù)據(jù)庫中的兩個(gè)時(shí)間字段有數(shù)據(jù)但是請求結(jié)果返回是空,原因是數(shù)據(jù)庫字段名和成員變量名命名方式不一樣導(dǎo)致的
?在yml配置文件中配置mybatis對駝峰命名和下劃線命名的自動轉(zhuǎn)換
mybatis:configuration:map-underscore-to-camel-case: true
然后再重新運(yùn)行請求字段數(shù)據(jù)已請求成功
?優(yōu)化代碼ThreadLocal
- 提供線程局部變量?
- 用來存取數(shù)據(jù): set()/get()
- 使用ThreadLocal存儲的數(shù)據(jù), 線程安全?
- 用完記得調(diào)用remove方法釋放
添加工具類
public class ThreadLocalUtil {//提供ThreadLocal對象,private static final ThreadLocal THREAD_LOCAL = new ThreadLocal();//根據(jù)鍵獲取值public static <T> T get(){return (T) THREAD_LOCAL.get();}//存儲鍵值對public static void set(Object value){THREAD_LOCAL.set(value);}//清除ThreadLocal 防止內(nèi)存泄漏public static void remove(){THREAD_LOCAL.remove();}
}
?在LoginInterceptor類中把業(yè)務(wù)數(shù)據(jù)存入線程局部變量
//把業(yè)務(wù)數(shù)據(jù)存到ThreadLocalUtil中ThreadLocalUtil.set(claims);
再回到Usercontroller類中修改代碼
參數(shù)可以不再傳入,用戶名可以在線程局部變量中獲取
@GetMapping("/userInfo")public Result<User> userInfo(){ //@RequestHeader設(shè)置請求頭//從ThreadLocalUtil中獲取用戶名Map<String,Object> map = ThreadLocalUtil.get();String username = (String) map.get("username");User user = userService.findByUserName(username); //通過用戶名使用方法查詢r(jià)eturn Result.success(user); //返回對象}
}
重新運(yùn)行請求查看獲取成功
?為了防止占用內(nèi)存資源,要在請求結(jié)束后對數(shù)據(jù)清除
????????在LoginInterceptor類中重寫afterCompletion方法調(diào)傭ThreadLocalUtil工具類的remove();方法即可實(shí)現(xiàn)請求結(jié)束后對數(shù)據(jù)清除
@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {ThreadLocalUtil.remove();}
?更新用戶基本信息
接口文檔
完善代碼?
?Usercontroller類中編寫方法實(shí)現(xiàn)
@PutMapping("/update")public Result update(@RequestBody User user){userService.update(user);return Result.success();}
? UserService接口中編寫方法
//更新void update(User user);
?在UserServiceimpl實(shí)現(xiàn)類中實(shí)現(xiàn)方法
@Overridepublic void update(User user) {user.setUpdateTime(LocalDateTime.now()); //設(shè)置update_time字段為當(dāng)前更新時(shí)間userMapper.update(user);}
?在UserMapper接口中實(shí)現(xiàn)更新方法
//更新@Update("update user set nickname=#{nickname},email=#{email},update_time=#{updateTime} where id = #{id}")void update(User user);
?啟動項(xiàng)目請求
?請求參數(shù):請求頭為當(dāng)前token,請求參數(shù)為json對象
查看請求成功?
?
對實(shí)體對象參數(shù)完成校驗(yàn)
第1步:先在bean對象實(shí)體屬性變量上添加如下注解,注解參數(shù)為正則表達(dá)式?
?
@NotNullprivate Integer id;//主鍵IDprivate String username;//用戶名@JsonIgnore //把當(dāng)前對象轉(zhuǎn)為json字符串的時(shí)候忽略掉這個(gè)屬性,最終返回結(jié)果就不包含這個(gè)private String password;//密碼@NotEmpty@Pattern(regexp = "^\\S{1,10}$")private String nickname;//昵稱@NotEmpty@Emailprivate String email;//郵箱private String userPic;//用戶頭像地址private LocalDateTime createTime;//創(chuàng)建時(shí)間private LocalDateTime updateTime;//更新時(shí)間
第2步:.在方法傳參時(shí)使用@Validated注解
更新用戶頭像?
接口文檔?
?完善代碼?
??Usercontroller類中編寫方法實(shí)現(xiàn)
@PatchMapping("/updateAvatar")public Result updateAvatar(@RequestParam String avatarUrl){ //@RequestParam用于獲取參數(shù)userService.updateAvatar(avatarUrl);return Result.success();}
? UserService接口中編寫方法
//更新頭像void updateAvatar(String avatarUrl);
?在UserServiceimpl實(shí)現(xiàn)類中實(shí)現(xiàn)方法
@Overridepublic void updateAvatar(String avatarUrl) {Map<String,Object> map = ThreadLocalUtil.get(); //從線程局部變量中獲取id參數(shù)Integer id = (Integer) map.get("id");userMapper.updateAvatar(avatarUrl,id);}
?在UserMapper接口中實(shí)現(xiàn)方法
@Update("update user set user_pic=#{avatarUrl},update_time= now() where id = #{id}")void updateAvatar(String avatarUrl,Integer id);
運(yùn)行請求查看
對傳入地址完成參數(shù)校驗(yàn)?
?在地址字符串參數(shù)前加上@URL注解,即可使傳入?yún)?shù)為URL校驗(yàn)的格式
更改用戶密碼?
?接口文檔
?完善代碼?
Usercontroller類中編寫方法實(shí)現(xiàn)
@PatchMapping("/updatePwd")public Result updatePwd(@RequestBody Map<String,String> params){//1.校驗(yàn)參數(shù)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("缺少必要參數(shù)");}//判斷原密碼是否正確Map<String,Object> map = ThreadLocalUtil.get();String username = (String) map.get("username"); //獲取username參數(shù)User user = userService.findByUserName(username); //獲取user對象if(!user.getPassword().equals(Md5Util.getMD5String(oldPwd))){ //判斷對比原密碼return Result.error("原密碼錯(cuò)誤");}//判斷新密碼和二次確認(rèn)密碼是否一致if (! rePwd.equals(newPwd)){return Result.error("兩次輸入的密碼不一致");}//調(diào)用userService實(shí)現(xiàn)密碼更新userService.updatePwd(newPwd);return Result.success();}
UserService接口中編寫方法
//更改密碼void updatePwd(String newPwd);
在UserServiceimpl實(shí)現(xiàn)類中實(shí)現(xiàn)方法
@Overridepublic void updatePwd(String newPwd) {Map<String,Object> map = ThreadLocalUtil.get(); //從線程局部變量中獲取id參數(shù)Integer id = (Integer) map.get("id");userMapper.updatePwd(Md5Util.getMD5String(newPwd),id); //將密碼加密后再傳入}
在UserMapper接口中實(shí)現(xiàn)方法
@Update("update user set password=#{newPwd},update_time= now() where id =#{id};")void updatePwd(String newPwd, Integer id);
?運(yùn)行請求查看
?密碼已修改成功