營(yíng)銷型網(wǎng)站建設(shè)菲凡網(wǎng)藝人百度指數(shù)排行榜
1.概要
前一章節(jié)完成了用戶信息的注冊(cè)、登錄、詳細(xì)信息查詢,以及線程池與攔截器技術(shù)。
這一章完善了用戶信息更新/更改功能,包括昵稱、郵箱、頭像、密碼等...
而后接觸到了本地上傳和云上傳,其二者區(qū)別:
選擇本地上傳還是云上傳取決于具體的業(yè)務(wù)需求、預(yù)算、數(shù)據(jù)量、以及對(duì)速度和可靠性的要求。對(duì)于需要高可靠性和可擴(kuò)展性的大規(guī)模數(shù)據(jù)存儲(chǔ),云上傳通常是更好的選擇。而對(duì)于小型項(xiàng)目或?qū)Τ杀久舾械膱?chǎng)景,本地上傳可能更加合適。
借助阿里云的OSS對(duì)象存儲(chǔ)服務(wù),更方便的使網(wǎng)站,去進(jìn)行靜態(tài)內(nèi)容托管、備份和歸檔。
2.更新用戶信息
2.1 映射類UserMapper
文件地址:org/example/mapper/UserMapper.java
now():獲得數(shù)據(jù)庫(kù)的系統(tǒng)時(shí)間
package org.example.mapper;
import ...
@Mapper
public interface UserMapper {......//更新用戶表,設(shè)計(jì)昵稱郵箱等數(shù)值@Update("update user set nickname=#{nickname},email=#{email},update_time=#{updateTime} where id=#{id}")void update(User user);//更新用戶頭像@Update("update user set user_pic=#{avatarUrl},update_time=now() where id=#{id}")//創(chuàng)建updateAvatar接口,Integer規(guī)范數(shù)據(jù)為整型void updateAvatar(String avatarUrl,Integer id);//更新用戶密碼@Update("update user set password=#{rePassword},update_time=now() where id=#{id}")void updatePassword(String rePassword,Integer id);
}
2.2 業(yè)務(wù)層UserService
2.2.1 創(chuàng)建接口
文件地址:org/example/service/UserService.java
//更新用戶信息
void update(User user);
//更新用戶頭像
void updateAvatar(String avatarUrl);
//更新用戶密碼
void updatePassword(String rePassword);
2.2.2 實(shí)現(xiàn)接口
文件地址:org/example/service/impl/UserServiceImpl.java
package org.example.service.impl;
import ...
@Service
public class UserServiceImpl implements UserService {............//實(shí)現(xiàn)用戶信息更新@Overridepublic void update(User user) {//設(shè)置用戶更新時(shí)間為當(dāng)前系統(tǒng)時(shí)間//LocalDateTime.now()獲得系統(tǒng)時(shí)間user.setUpdateTime(LocalDateTime.now());userMapper.update(user);}//實(shí)現(xiàn)用戶頭像更新@Overridepublic void updateAvatar(String avatarUrl) {//由于請(qǐng)求后,線程池中將會(huì)存放該用戶的信息,包含ID值Map<String,Object> map = ThreadLocalUtil.get();Integer id = (Integer) map.get("id");userMapper.updateAvatar(avatarUrl, id);}//實(shí)現(xiàn)用戶密碼更新@Overridepublic void updatePassword(String rePassword) {Map<String,Object> map = ThreadLocalUtil.get();Integer id = (Integer) map.get("id");String md5String = Md5Util.getMD5String(rePassword);userMapper.updatePassword(md5String, id);}
}
2.3 控制層UserController
文件地址:org/example/controller/UserController.java
@RequestBody:將前端傳來(lái)的數(shù)據(jù)自動(dòng)轉(zhuǎn)換成JSON格式的字符串,并且為對(duì)象User賦值
@Validate:開(kāi)啟參數(shù)校驗(yàn)
//更新用戶信息@PutMapping("/update")public Result update(@RequestBody @Validated User user){//調(diào)用業(yè)務(wù)層的更新用戶方法userService.update(user);return Result.success();}@PutMapping("/updateavatar")//更新用戶頭像信息public Result updateAvatar(@RequestParam String avatarUrl){userService.updateAvatar(avatarUrl);return Result.success();}//更新用戶密碼信息@PostMapping("/updatePwd")public Result updatePwd(@RequestBody Map<String,String> params){// 獲得前端傳來(lái)的舊密碼,新密碼,確認(rèn)密碼// 校驗(yàn)數(shù)據(jù)String oldPwd = params.get("old_Pwd");String newPwd = params.get("new_Pwd");String rePwd = params.get("re_Pwd");// 各密碼不能為null// StringUtils.hasLength(oldPwd)判斷字符中的個(gè)數(shù),返回Boolean,// 如果變量中沒(méi)有值則返回falseif (!StringUtils.hasLength(oldPwd)||!StringUtils.hasLength(newPwd)||!StringUtils.hasLength(rePwd)){return Result.error("缺少必要の參數(shù)");}//驗(yàn)證原密碼是否正確Map<String,Object> map = ThreadLocalUtil.get();String username = (String)map.get("username");User user = userService.findUserByUsername(username);//判斷輸入的舊密碼,與數(shù)據(jù)庫(kù)的密碼是否一致if (!user.getPassword().equals(Md5Util.getMD5String(oldPwd))){return Result.error("舊密碼輸入錯(cuò)誤");}//判斷新密碼和確認(rèn)密碼是否一致if (!rePwd.equals(newPwd)){return Result.error("新密碼和確認(rèn)密碼不一致");}//更新數(shù)據(jù)中的密碼userService.updatePassword(newPwd);return Result.success();}
2.4 校檢數(shù)據(jù)格式
@JsonIgnore:配置springmvc把當(dāng)前對(duì)象轉(zhuǎn)換成json字符串的時(shí)候忽略password
@Email:校驗(yàn)數(shù)據(jù)為郵箱格式
@NotEmpty:校驗(yàn)不能為空
@Pattern(regexp = "^\\S{1,10}$"):校驗(yàn)內(nèi)容為字符型,且在1-10位之間
package org.example.entity;
import ...
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {private Integer id;private String username;@JsonIgnoreprivate String password;@NotEmpty@Emailprivate String email;@NotEmpty@Pattern(regexp = "^\\S{1,10}$")private String nickname;private String userPic;private LocalDateTime createTime;private LocalDateTime updateTime;
}
2.5 實(shí)驗(yàn)效果
2.5.1 更新用戶信息
2.5.2 更新用戶頭像
2.5.3 更改用戶密碼
3.文件上傳&本地儲(chǔ)存FileUploadController
文件地址:org/example/controller/FileUploadController.java
使用 @PostMapping
注解來(lái)映射 POST 請(qǐng)求到 /upload
路徑。
這個(gè)方法接收一個(gè) MultipartFile
類型的參數(shù) file
,用于處理上傳的文件。
MultipartFile:用于傳輸二進(jìn)制文件,如圖片、視頻等
originalFilename.lastIndexOf("."):獲取上傳文件的擴(kuò)展名,如jpg、png
UUID.randomUUID().toString():隨機(jī)獲得一個(gè)唯一id值作為名字
package org.example.controller;
import org.example.entity.Result;
import org.example.utils.AliOssUtils;
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 {//把文件內(nèi)容存儲(chǔ)到本地磁盤上String originalFilename = file.getOriginalFilename();System.out.println(originalFilename);//保證文件名唯一性String filename = UUID.randomUUID().toString()+originalFilename.substring(originalFilename.lastIndexOf("."));//向目標(biāo)傳遞圖片的二進(jìn)制值file.transferTo(new File("D:\\workspace\\images\\"+filename));return Result.success("url訪問(wèn)地址");}
}
4.文件上傳&阿里云OSS
步驟:
注冊(cè)登錄-開(kāi)通對(duì)象儲(chǔ)存服務(wù)-創(chuàng)建bucket-獲取AccessKey-參照SDK編寫(xiě)程序-集成OSS
Bucket:是一種用于存儲(chǔ)數(shù)據(jù)的基本容器
AccessKey:用于身份驗(yàn)證和訪問(wèn)控制的一種機(jī)制
SDK(Software Development Kit,軟件開(kāi)發(fā)工具包):是一套工具、庫(kù)、文檔和代碼樣本的集合,用于幫助開(kāi)發(fā)者為特定的軟件包、軟件框架、硬件平臺(tái)、操作系統(tǒng)等創(chuàng)建應(yīng)用程序或庫(kù)。
4.1 注冊(cè)登錄
略
4.2 開(kāi)通對(duì)象儲(chǔ)存服務(wù)
釋放數(shù)據(jù)激情,云存儲(chǔ)新紀(jì)元!極速、安全、經(jīng)濟(jì),一切盡在掌控!
立即加入,快來(lái)領(lǐng)取吧!讓數(shù)據(jù)飛起來(lái)!
4.3?創(chuàng)建bucket
開(kāi)通過(guò)后,回到主頁(yè),拉至最下方。有權(quán)益中心-免費(fèi)試用按鍵。
進(jìn)入免費(fèi)試用后,可查看我的試用。
在費(fèi)用與成本中進(jìn)入管理關(guān)聯(lián)實(shí)例,抵達(dá)OSS管理控制臺(tái)。
其中可查看與創(chuàng)建自己的"bucket"
自定義創(chuàng)建-填寫(xiě)bucket名稱-其余默認(rèn)(所屬資源組:空)-完成創(chuàng)建
設(shè)置bucket使用權(quán)限:
1.進(jìn)入bucket? ? 2.權(quán)限控制-阻止公共訪問(wèn):關(guān)閉? ? 3.權(quán)限控制-讀寫(xiě)權(quán)限:公共讀寫(xiě)
4.4?獲取AccessKey?
在此地可創(chuàng)建屬于自己的密鑰
4.5?參照SDK編寫(xiě)程序pom.xml
安裝SDK:在MAVEN項(xiàng)目pom.xml中加入SDK依賴
<!--阿里云OSS服務(wù)-->
<dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>3.17.4</version>
</dependency>
<dependency><groupId>javax.xml.bind</groupId><artifactId>jaxb-api</artifactId><version>2.3.1</version>
</dependency>
<dependency><groupId>javax.activation</groupId><artifactId>activation</artifactId><version>1.1.1</version>
</dependency>
<!-- no more than 2.3.3-->
<dependency><groupId>org.glassfish.jaxb</groupId><artifactId>jaxb-runtime</artifactId><version>2.3.3</version>
</dependency>
4.6 測(cè)試OSS-uploadTest
文件地址:src/test/java/uploadTest.java
執(zhí)行文件測(cè)試文件后,可在阿里云bucket列表中,
訪問(wèn)到個(gè)人電腦中D:\\workspace\\images\\1.jpg(為例)地址上的圖片。
云上的圖片名為:"wagaga.jpg"(String objectName的值)。
點(diǎn)擊wagaga.jpg處可復(fù)制到圖片的下載地址,在瀏覽器中打開(kāi)可直接下載到本地。
import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
public class uploadTest {//測(cè)試上傳文件至阿里云的OSSpublic static void main(String[] args) throws Exception {// Endpoint以華東1(杭州)為例,其它Region請(qǐng)按實(shí)際情況填寫(xiě)。String endpoint = "https://oss-cn-beijing.aliyuncs.com";// 從環(huán)境變量中獲取訪問(wèn)憑證。運(yùn)行本代碼示例之前,請(qǐng)確保已設(shè)置環(huán)境變量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。// EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();// 填寫(xiě)B(tài)ucket名稱,例如examplebucket。String bucketName = "new-system-622";// 填寫(xiě)Object完整路徑,完整路徑中不能包含Bucket名稱,例如exampledir/exampleobject.txt。String objectName = "wagaga.jpg";// 填寫(xiě)B(tài)ucket所在地域。以華東1(杭州)為例,Region填寫(xiě)為cn-hangzhou。String region = "cn-beijing";//填寫(xiě)AccesskeyString ACCESS_KEY_ID="LTAI5t798Q7kyDGjn3emtKUy";String ACCESS_KEY_SECRET="Pn4LIt2AQw04jIvorcdF62dJSVqO67";// 創(chuàng)建OSSClient實(shí)例。ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);OSS ossClient = new OSSClientBuilder().build(endpoint,ACCESS_KEY_ID,ACCESS_KEY_SECRET);try {// 填寫(xiě)字符串。String content = "Hello OSS,你好世界";// 創(chuàng)建PutObjectRequest對(duì)象。PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, new FileInputStream("D:\\workspace\\images\\1.jpg"));// 如果需要上傳時(shí)設(shè)置存儲(chǔ)類型和訪問(wèn)權(quán)限,請(qǐng)參考以下示例代碼。// ObjectMetadata metadata = new ObjectMetadata();// metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());// metadata.setObjectAcl(CannedAccessControlList.Private);// putObjectRequest.setMetadata(metadata);// 上傳字符串。PutObjectResult result = ossClient.putObject(putObjectRequest);} catch (OSSException oe) {System.out.println("Caught an OSSException, which means your request made it to OSS, "+ "but was rejected with an error response for some reason.");System.out.println("Error Message:" + oe.getErrorMessage());System.out.println("Error Code:" + oe.getErrorCode());System.out.println("Request ID:" + oe.getRequestId());System.out.println("Host ID:" + oe.getHostId());} catch (ClientException ce) {System.out.println("Caught an ClientException, which means the client encountered "+ "a serious internal problem while trying to communicate with OSS, "+ "such as not being able to access the network.");System.out.println("Error Message:" + ce.getMessage());} finally {if (ossClient != null) {ossClient.shutdown();}}}
}
4.7 聯(lián)系自身代碼集成OSS-AliOssUtils
新建文件:org/example/utils/AliOssUtils.java
private static final String ENDPOINT = "https://oss-cn-beijing.aliyuncs.com":
- private 私有的
- static 靜態(tài)的,只加載一次
- final 不允許被修改
- String 聲明數(shù)據(jù)類型
- ENDPOINT 常量名,通常大寫(xiě)
package org.example.utils;
import com.aliyun.oss.*;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import java.io.FileInputStream;
import java.io.InputStream;
public class AliOssUtils {//常量是在程序中固定不會(huì)變的數(shù)據(jù)private static final String ENDPOINT = "https://oss-cn-beijing.aliyuncs.com";private static final String ACCESS_KEY_ID="LTAI5t798Q7kyDGjn3emtKUy";private static final String ACCESS_KEY_SECRET="Pn4LIt2AQw04jIvorcdF62dJSVqO67";private static final String BUCKET_NAME = "new-system-622";private static final String REGION = "cn-beijing";public static String uploadFile(String objectName, InputStream in){// 創(chuàng)建OSSClient實(shí)例。ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);OSS ossClient = new OSSClientBuilder().build(ENDPOINT,ACCESS_KEY_ID,ACCESS_KEY_SECRET);String url = ""; //創(chuàng)建變量作用域在try體外try {// 填寫(xiě)字符串。String content = "Hello OSS,你好世界";// 創(chuàng)建PutObjectRequest對(duì)象。PutObjectRequest putObjectRequest = new PutObjectRequest(BUCKET_NAME, objectName, in);// 上傳字符串。PutObjectResult result = ossClient.putObject(putObjectRequest);//獲得上傳文件的地址url = "http://"+BUCKET_NAME+"."+ENDPOINT.substring(ENDPOINT.lastIndexOf("/")+1)+"/"+objectName;} catch (OSSException oe) {System.out.println("Caught an OSSException, which means your request made it to OSS, "+ "but was rejected with an error response for some reason.");System.out.println("Error Message:" + oe.getErrorMessage());System.out.println("Error Code:" + oe.getErrorCode());System.out.println("Request ID:" + oe.getRequestId());System.out.println("Host ID:" + oe.getHostId());} catch (ClientException ce) {System.out.println("Caught an ClientException, which means the client encountered "+ "a serious internal problem while trying to communicate with OSS, "+ "such as not being able to access the network.");System.out.println("Error Message:" + ce.getMessage());} finally {if (ossClient != null) {ossClient.shutdown();}}return url;}
}
4.8 返回FileUploadController
文件地址:org/example/controller/FileUploadController.java
更改當(dāng)初自定義的固態(tài)圖片地址,換成云上的鏈接:
package org.example.controller;
import org.example.entity.Result;
import org.example.utils.AliOssUtils;
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();System.out.println(originalFilename);String filename = UUID.randomUUID().toString()+originalFilename.substring(originalFilename.lastIndexOf("."));//向目標(biāo)傳遞圖片的二進(jìn)制值👇// file.transferTo(new File("D:\\workspace\\images\\"+filename));👆String url = AliOssUtils.uploadFile(filename, file.getInputStream());👇return Result.success(url);👆}
}