springboot实战篇2
1.更新用户基本信息
controller类:
@PutMapping("/update")//@RequestBody 把前端传递的json字符串转换成User对象public Result update(@RequestBody @Validated User user){//获取当前登录用户id");userService.update(user);return Result.success();}
ServiceImpl:
@Overridepublic void update(User user) {user.setUpdateTime(LocalDateTime.now());userMapper.update(user);}
@RequestBody 是 Spring 框架中用于接收 HTTP 请求体(Request Body) 的注解,通常用于处理 POST、PUT 等请求方式,将请求体中的 JSON/XML 数据反序列化为 Java 对象。
参数校验:
如果要对实体参数进行校验
1.在实体类中添加注解:
package com.itheima.pojo;import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.time.LocalDateTime;@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {@NotNull //让springmvc在接收请求参数的时候,对id这个属性进行非空校验private Integer id;//主键IDprivate String username;//用户名@JsonIgnore//让springmvc把当前对象转换成json字符串的时候,忽略password,最终的json字符串中就没有password这个属性private String password;//密码@NotEmpty@Pattern(regexp = "^\\S{1,10}$")private String nickname;//昵称@NotEmpty@Emailprivate String email;//邮箱private String userPic;//用户头像地址private LocalDateTime createTime;//创建时间private LocalDateTime updateTime;//更新时间}
2在controller类中实体类参数前面添加@Validated
@PutMapping("/update")//@RequestBody 把前端传递的json字符串转换成User对象更新public Result update(@RequestBody @Validated User user){//获取当前登录用户id");userService.update(user);return Result.success();}
2.更新用户头像
此时用patch的请求方式;
PATCH:适用于只需要更新资源的部分字段的场景。比如,用户只想修改自己的邮箱地址,而不希望修改其他信息,此时使用 PATCH 方法就非常合适。
Controller类:
@PatchMapping("updateAvatar")public Result updateAvatar(@RequestParam @URL String avatarUrl){userService.updateAvatar(avatarUrl);return Result.success();}
@RequestParam 是 Spring MVC/Spring Boot 里用来接收 URL 查询参数 或 表单字段 的核心注解。
一句话:它把 ?key=value 里的 value 注入到方法参数中。
ServiceImpl:
@Overridepublic void updateAvatar(String avatarUrl) {//获取当前登录用户的idMap<String,Object> map= ThreadLocalUtil.get();Integer id = (Integer) map.get("id");userMapper.updateAvatar(avatarUrl,id);}
更新时间
如果是实体类对象那么就可以在ServiceImpl里面编写如下代码:
user.setUpdateTime(LocalDateTime.now());
因为可以通过修改user里面的updateTime来更新创建时间:
如果不是那么就可以直接在mapper里面的sql语句中直接调用now()
update_time = now()
参数校验:@URL来检验是否为url
3.更新密码的操作:
controller:
@PatchMapping("/updatePwd")public Result updatePwd(@RequestBody Map<String,String> params){//1.校验参数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("缺少必要参数");}//原密码是否正确//调用UserService根据用户名得到原密码在和oldPwd进行比对Map<String,Object> map = ThreadLocalUtil.get();String username = (String) map.get("username");User loginUser = userService.findByUsername(username);if(!loginUser.getPassword().equals(Md5Util.getMD5String(oldPwd))) {return Result.error("原密码错误");}//newPwd和rePwd是否一致if(!rePwd.equals(newPwd)){return Result.error("两次密码不一致");}//2.调用service完成 密码更新userService.updatePwd(newPwd);return Result.success();}
@Overridepublic void updatePwd(String newPwd) {Map<String,Object> map= ThreadLocalUtil.get();Integer id = (Integer) map.get("id");userMapper.updatePwd(Md5Util.getMD5String(newPwd),id);}
- 让密码加密的操作:
- Md5Util.getMD5String(newPwd)
新增文章分类
@PostMappingpublic Result add(@RequestBody @Validated(Category.Add.class) Category category){categoryService.add(category);return Result.success();}
@Overridepublic void add(Category category) {//补充属性category.setCreateTime(LocalDateTime.now());category.setUpdateTime(LocalDateTime.now());Map<String, Object> map = ThreadLocalUtil.get();Integer userId = (Integer) map.get("id");category.setCreateUser(userId);categoryMapper.add(category);}
文章分类列表:
@GetMappingpublic Result<List<Category>> list(){List<Category> cs= categoryService.list();return Result.success(cs);}
@Overridepublic List<Category> list() {Map<String,Object> map = ThreadLocalUtil.get();Integer userid = (Integer) map.get("id");return categoryMapper.list(userid);}
指定日期的格式:
获取文章分类详情:
@GetMapping("/detail")public Result detail(Integer id){Category c = categoryService.findById(id);return Result.success(c);}
@Overridepublic Category findById(Integer id) {Category c = categoryMapper.findById(id);return c;}
更新文章分类:
@PutMappingpublic Result update(@RequestBody @Validated(Category.Update.class) Category category){categoryService.update(category);return Result.success();}
@Overridepublic void update(Category category) {category.setUpdateTime(LocalDateTime.now());categoryMapper.update(category);}
*分组校验:
1定义分组:
public interface Add extends Default {}public interface Update extends Default{}
2.
public class Category {@NotNull(groups = Update.class)private Integer id;//主键ID@NotEmpty private String categoryName;//分类名称@NotEmptyprivate String categoryAlias;//分类别名private Integer createUser;//创建人ID@JsonFormat(pattern = "yyyy-HH-dd HH:mm:ss")private LocalDateTime createTime;//创建时间@JsonFormat(pattern = "yyyy-HH-dd HH:mm:ss")private LocalDateTime updateTime;//更新时间//如果说某个某个校验项没有指定分组,默认属于Default分组//相当于就是如果继承了Default 那么就应该遵循所有的限制 除非有个限制被指定为某一组//分组之间可以继承,A extend B 那么A分组就拥有B分组的校验项public interface Add extends Default {}public interface Update extends Default{}
新增文章
@PostMappingpublic Result add(@RequestBody @Validated Article article){articleService.add(article);return Result.success();}
@Overridepublic void add(Article article) {//补充属性article.setCreateTime(LocalDateTime.now());article.setUpdateTime(LocalDateTime.now());Map<String,Object> map = ThreadLocalUtil.get();Integer userId = (Integer) map.get("id");article.setCreateUser(userId);articleMapper.add(article);}
参数校验:
public class Article {@NotNullprivate Integer id;//主键ID@NotEmpty@Pattern(regexp = "^\\S{1,10}$")private String title;//文章标题@NotEmptyprivate String content;//文章内容@NotEmpty@URLprivate String coverImg;//封面图像@Stateprivate String state;//发布状态 已发布|草稿@NotNullprivate Integer categoryId;//文章分类idprivate Integer createUser;//创建人IDprivate LocalDateTime createTime;//创建时间private LocalDateTime updateTime;//更新时间
}
自定义校验:
1.创建anno包 创建自定义State接口
@Documented//元注解
@Target({ElementType.FIELD})//元注解 State注解适用的地方 Field属性,
@Retention(RetentionPolicy.RUNTIME)//元注解 会保留到哪个阶段 runtime:运行阶段
@Constraint(validatedBy = {StateValidation.class})//指定提供校验规则的类public @interface State {//提供校验失败后的提示信息String message() default "state参数值只能是已发布或草稿";//指定分组Class<?>[] groups() default {};//负载 获取到State注解的附加信息Class<? extends Payload>[] payload() default {};
}
2.创建validation包 StateValidation类
package com.itheima.validation;import com.itheima.anno.State;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;//ConstraintValidator<给哪个注解提供校验规则,校验的数据类型>
public class StateValidation implements ConstraintValidator<State,String> {/**** @param s 将来要检验的数据* @param constraintValidatorContext* @return 结果如果是true 校验通过* 结果如果是false 校验失败*/@Overridepublic boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {//提供校验规则if(s == null){return false;}if(s.equals("已发布") || s.equals("草稿")){return true;}return false;}
}
3.在要校验的地方写上注解
@Stateprivate String state;//发布状态 已发布|草稿
文章列表查询(条件分页)
1.先在pojo导入写好的PageBean类:
package com.itheima.pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.util.List;//分页返回结果对象
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PageBean <T>{private Long total;//总条数private List<T> items;//当前页数据集合
}
@GetMappingpublic Result<PageBean<Article>> list(Integer pageNum,Integer pageSize,@RequestParam(required = false)Integer categoryId,@RequestParam(required = false)String state){PageBean<Article> pb=articleService.list(pageNum,pageSize,categoryId,state);return Result.success(pb);}
PageHelper依赖:
<!-- PageHelper分页插件--><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>1.4.6</version></dependency>
@Overridepublic PageBean<Article> list (Integer pageNum, Integer pageSize, Integer categoryId, String state) {//1.创建PageBean对象PageBean<Article> pb = new PageBean<>();//2.开启分页查询 借助于PageHelperPageHelper.startPage(pageNum,pageSize);//3.调用mapper查询文章列表Map<String,Object> map = ThreadLocalUtil.get();Integer userId = (Integer) map.get("id");List<Article> as = articleMapper.list(userId,categoryId,state);//Page中提供了方法,可以获取PageHelper分页查询后,得到的总记录条数和当前页数据Page<Article> p = (Page<Article>) as;//把数据填充到PageBean中pb.setTotal(p.getTotal());pb.setItems(p.getResult());return pb;}
通过映射配置文件编写动态sql
mapper namespace里面编写的是ArticleMapper的位置
select id里面写的是方法名字 resultType写的是多条数据对应的数据类型
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.itheima.mapper.ArticleMapper"><!--动态sql--><select id = "list" resultType="com.itheima.pojo.Article">select * from article<where><if test = "categoryId!=null" >category_id =#{categoryId}</if><if test = "state!=null" >and state =#{state}</if>and create_user= #{userId}</where></select>
</mapper>
文件上传
package com.itheima.controller;import com.itheima.pojo.Result;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;import java.awt.*;
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();//保证文件名唯一 防止文件覆盖String filename = UUID.randomUUID().toString()+originalFilename.substring(originalFilename.lastIndexOf("."));file.transferTo(new File("C:\\Users\\蛋堡\\Desktop\\file\\"+filename));return Result.success("url访问地址");}
}