Controller层:
通过PageBean的实体对象将对应的分页信息作为Result结果展示出来
@RequestParam(required = false) Integer categoryId
说明的是这个参数不是必须的
//TODO:文章条件分页查询
@GetMapping
public Result<PageBean<Article>> list(
Integer pageNum,
Integer pageSize,
@RequestParam(required = false) Integer categoryId,
@RequestParam(required = false) String state
){
PageBean<Article> pageBean=articleService.list(pageNum,pageSize,categoryId,state);
return Result.success(pageBean);
}
引入实体PageBean的创建
//分页返回结果对象
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PageBean <T>{
private Long total;//总条数
private List<T> items;//当前页数据集合
}
Service层:
1、创建PageBean对象用于返回结果
2、使用PageHelper插件开启分页查询并且导入对应的依赖
PageHelper.startPage(pageNum,pageSize);
参数一为需要查询的页码,参数二为查询的条数
<!--分页的插件-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.4.7</version>
</dependency>
3、调用mapper查询分页数据(UserId从ThredLocal中获取)返回为一个List
List
4、通过Page中的方法获取PageHelper分页查询之后的总记录数和当前页的数据
Page
@Override
public PageBean<Article> list(Integer pageNum, Integer pageSize, Integer categoryId, String state) {
//TODO:创建pageBean对象
PageBean<Article> pageBean=new PageBean<>();
//TODO:开启分页查询
PageHelper.startPage(pageNum,pageSize);
//TODO:调用mapper查询分页数据
Map<String, Object> map = ThreadLocalUtil.get();
Integer userId= (Integer) map.get("id");
List<Article> articles =articleMapper.list(userId,categoryId,state);
//TODO:通过Page中的方法获取PageHelper分页查询之后的总记录数和当前页的数据
Page<Article> page= (Page<Article>) articles;
//TODO:设置pageBean的属性,将数据封装到pageBean中
pageBean.setTotal(page.getTotal());
pageBean.setItems(page.getResult());
return pageBean;
}
Mapper层:由于参数categoryId,参数state可以写也可以不写,那么可以使用动态SQL的形式进行查询操作—》书写对应的Mapper映射文件
List<Article> list(Integer userId, Integer categoryId, String state);
com/example/mapper/ArticleMapper.xml
Controller层:
//TODO:获取文章详情
@GetMapping("/detail")
public Result<Article> detail(@RequestParam Integer id){
Article article=articleService.detail(id);
return Result.success(article);
}
Service层:
@Override
public Article detail(Integer id) {
return articleMapper.detail(id);
}
Mapper层:
@Select("select * from article where id=#{id}")
Article detail(Integer id);
Controller层:对于传入的实体对象参数进行参数校验通过分组校验
的形式进行
//TODO:修改文章
@PutMapping
public Result update(@RequestBody @Validated(Article.Update.class) Article article){
articleService.update(article);
return Result.success();
}
定义分组校验的实现–》在article中
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Article {
@NotNull(groups = {Update.class})
private Integer id;//主键ID
@NotEmpty
//1~10个非空字符
@Pattern(regexp = "^\\S{1,10}$",groups = {Add.class})
private String title;//文章标题
@NotEmpty
private String content;//文章内容
@NotEmpty
@URL(groups = {Add.class})
private String coverImg;//封面图像
@NotEmpty
//状态只能为已发布或者草稿
//@Pattern(regexp = "^(已发布|草稿)$")
@State
private String state;//发布状态 已发布|草稿
@NotNull
private Integer categoryId;//文章分类id
private Integer createUser;//创建人ID
private LocalDateTime createTime;//创建时间
private LocalDateTime updateTime;//更新时间
public interface Add extends Default{}
public interface Update extends Default{}
}
Service层:
@Override
public void update(Article article) {
//更新文章时间
article.setUpdateTime(LocalDateTime.now());
articleMapper.update(article);
}
Mapper层:
@Update("update article set title=#{title},content=#{content},cover_img=#{coverImg},state=#{state},category_id=#{categoryId},update_time=#{updateTime} where id=#{id}")
void update(Article article);
Controller层:
//TODO:删除文章
@DeleteMapping
public Result delete(@RequestParam Integer id){
articleService.delete(id);
return Result.success();
}
Service层
@Override
public void delete(Integer id) {
articleMapper.delete(id);
}
Mapper层:
@Delete("delete from article where id=#{id}")
void delete(Integer id);
关于文件上传的操作前端需要实现的部分是
1、提交方式为**Post
**
2、提交的表单类型为**multipart/form-data
**
3、表单项的类型为**file
**
后端通过**MultipartFile
类作为请求的参数**来实现文件上传操作
FileUploadController:将图片上传到本地transferTo(转存为一个新的图片文件)
@RestController
public class FIleUploadController {
@PostMapping("/upload")
public Result<String> upload(MultipartFile file) throws IOException {
//TODO:将文件内容存储到本地磁盘上
// TODO:获取文件名
String originalFilename=file.getOriginalFilename();
// TODO:需要保证文件名不重复--》防止文件因为重名而被覆盖
// TODO:获取文件后缀--截取点后面的文件类型
String endName=originalFilename.substring(originalFilename.lastIndexOf("."));
String fileName= UUID.randomUUID().toString()+endName;
file.transferTo(new File("D:\\桌面\\课程\\workspace\\big-event\\files\\"+fileName));
return Result.success("url访问地址");
}
}
将图片上传到阿里云–云端服务器,这样就能在网页直接访问图片了
云服务通用思路
一、准备工作
二、参照官方的SDK(软件开发工具包)编写入门程序
public class Demo {
public static void main(String[] args) throws Exception {
// Endpoint以华北2(北京)为例,其它Region请按实际情况填写。
String endpoint = "https://oss-cn-beijing.aliyuncs.com";
// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
//EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
String ACCESS_KEY_ID = "yourKeyId";
String ACCESS_KEY_SECRET = "yourKeySecret";
// 使用DefaultCredentialProvider方法直接设置AK和SK
CredentialsProvider credentialsProvider = new DefaultCredentialProvider(ACCESS_KEY_ID, ACCESS_KEY_SECRET);
// 填写Bucket名称,例如examplebucket。
String bucketName = "geishihua-big-event";
// 填写Object完整路径,完整路径中不能包含Bucket名称,例如001.png
String objectName = "001.png";
// 填写Bucket所在地域。以华北2(北京)为例,Region填写为cn-beijing。
String region = "cn-beijing";
// 创建OSSClient实例。
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
OSS ossClient = OSSClientBuilder.create()
.endpoint(endpoint)
.credentialsProvider(credentialsProvider)
.clientConfiguration(clientBuilderConfiguration)
.region(region)
.build();
try {
// 填写字符串。
String content = "Hello OSS,你好世界";
// 创建PutObjectRequest对象。
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, new FileInputStream("D:\\桌面\\课程\\springboot3+Vue3\\imgs\\4.png"));
// 如果需要上传时设置存储类型和访问权限,请参考以下示例代码。
// 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();
}
}
}
}
将这个OSS上传的功能集成为一个工具类AliOssUtil
public class AliOssUtil {
// Endpoint以华北2(北京)为例,其它Region请按实际情况填写。endpoint在这个bucket的概览处中的访问端口的外网访问一栏
private static final String ENDPOINT = "https://oss-cn-beijing.aliyuncs.com";
// 填写您的AccessKey ID和AccessKey Secret。
private static final String ACCESS_KEY_ID = "yourId";
private static final String ACCESS_KEY_SECRET = "yourSecret";
// 填写Bucket名称,例如examplebucket。
private static final String BUCKET_NAME = "yourbucketname";
// 填写Bucket所在地域。以华北2(北京)为例,Region填写为cn-beijing。
private static final String REGION = "cn-beijing";
public static String UploadFile(String objectName, InputStream in) throws Exception {
// 使用DefaultCredentialProvider方法直接设置AK和SK
CredentialsProvider credentialsProvider = new DefaultCredentialProvider(ACCESS_KEY_ID, ACCESS_KEY_SECRET);
// 创建OSSClient实例。
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
OSS ossClient = OSSClientBuilder.create()
.endpoint(ENDPOINT)
.credentialsProvider(credentialsProvider)
.clientConfiguration(clientBuilderConfiguration)
.region(REGION)
.build();
String url="";
try {
// 填写字符串。
String content = "Hello OSS,你好世界";
// 创建PutObjectRequest对象。
PutObjectRequest putObjectRequest = new PutObjectRequest(BUCKET_NAME, objectName, in);
// 上传字符串。
PutObjectResult result = ossClient.putObject(putObjectRequest);
// 获取上传文件的URL组成:http://BUCKET_NAME.oss-cn-beijing.aliyuncs.com/OBJECT_NAME
url = "http://" + BUCKET_NAME + ".oss-" + REGION+".aliyuncs.com" + "/" + 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;
}
}
改写将文件上传到本地
@RestController
public class FIleUploadController {
@PostMapping("/upload")
public Result<String> upload(MultipartFile file) throws Exception {
//TODO:将文件内容存储到本地磁盘上
// TODO:获取文件名
String originalFilename=file.getOriginalFilename();
// TODO:需要保证文件名不重复--》防止文件因为重名而被覆盖
// TODO:获取文件后缀--截取点后面的文件类型
String endName=originalFilename.substring(originalFilename.lastIndexOf("."));
String fileName= UUID.randomUUID().toString()+endName;
//file.transferTo(new File("D:\\桌面\\课程\\workspace\\big-event\\files\\"+fileName));
//TODO:通过MultipartFile获取文件流--file.getInputStream()
String url = AliOssUtil.UploadFile(fileName, file.getInputStream());
return Result.success(url);
}
}