[Java]SpringBoot接口开发
准备工作
1.效果展示
该项目的最终实现效果
2.环境搭建
完成项目环境的搭建
- 新建数据库和数据表 (tlias数据库/dept部门表/emp员工表)
- 创建springboot工程, 引入起步依赖 (wbe依赖/mybatis依赖/mysql驱动依赖/lombok依赖)
- 在配置文件application.properties中配置mybatis的连接信息, 准备需要的实体类
- 准备基础结构Controller / Service(接口/实现类) / Mapper
- 引入同意结果封装类
- 也可以使用现成的项目环境
4.开发规范
开发模式: 本项目采用前后端分离的开发模式
前后端需要严格遵守接口文档, 通过接口文档完成项目的协作开发
软件风格: 采用REST风格, 译为表述性状态转换, 是一种软件架构风格
- REST风格的特点
- 通过URL定位资源
- 通过HTTP动词描述操作
- REST是风格, 不是规定, 可以打破
- 描述模块的功能通常使用复数, 也就是加s的格式描述, 表示此类资源, 而非单个资源, 如users, emps......
响应结果: 后端响应给前端的数据要有统一的格式
开发流程
部门管理
1.查询部门接口
1.1页面原型
1.2接口文档
1.3思路分析
1.4controller
/**
* 部门管理Controller
*/
@Slf4j
@RestController
public class DeptController {
@Autowired
private DeptService deptService;
/**
* 查询全部部门信息
*
* @return
*/
@GetMapping("/depts")
public Result list() {
log.info("查询全部部门数据");
List<Dept> deptList = deptService.list();
return Result.success(deptList);
}
}
- 在项目中不建议使用sout记录日志
- 通过lombok提供的 @Slf4j 注解, 可以自动生成日志记录对象log
- 通过调用日志记录对象的方法, 记录日志非常方便和专业
1.5server
/**
* 部门管理
*/
public interface DeptService {
/**
* 查询全部部门数据
* @return
*/
List<Dept> list();
}
@Service
public class DeptServiceImpl implements DeptService {
@Autowired
private DeptMapper deptMapper;
@Override
public List<Dept> list() {
return deptMapper.list();
}
}
- @Override注解是java提供的, 用于标明方法重写,提高代码可读性, 是非必须的
1.6mapper
/**
* 部门管理
*/
@Mapper
public interface DeptMapper {
/**
* 查询全部部门
*
* @return
*/
@Select("select * from dept")
List<Dept> list();
}
1.7接口测试
通过possmain工具完成接口的测试工作
1.8联调测试
前后端联调: 启动前后端程序, 通过前端工程访问后端工程, 进行功能调试
- 前端程序一般部署在nginx服务器
- 资料中提供了前端工程代码, 解压即可
- 启动: 双击nginx.exe文件
- 访问: http://localhost:90/
- 部署: 把资源放到html文件中
记录程序日志
使用lombok提供的注解
@Slf4j: 把该注解添加到类上面
使用: log.info()
指定请求方式
完整写法 @RequestMapping(value = "/depts",method = RequestMethod.GET)
简写形式@GetMapping("/depts")
2.删除部门接口
1.查看原型
2.查看接口
3.controller
/**
* 部门管理Controller
*/
@Slf4j
@RestController
public class DeptController {
@Autowired
private DeptService deptService;
/**
* 根据id删除部门信息
*/
@DeleteMapping("/depts/{id}")
public Result delete(@PathVariable Integer id) {
log.info("删除部门的id:{}", id);
deptService.delete(id);
return Result.success();
}
}
4.service
/**
* 部门管理
*/
public interface DeptService {
/**
* 根据id删除部门
* @param id
*/
void delete(Integer id);
}
@Service
public class DeptServiceImpl implements DeptService {
@Autowired
private DeptMapper deptMapper;
@Override
public void delete(Integer id) {
//根据id删除部门数据
deptMapper.deleteById(id);
}
}
5.mapper
/**
* 部门管理
*/
@Mapper
public interface DeptMapper {
/**
* 根据id删除部门信息
*/
@Delete("delete from dept where id = #{id}")
void deleteById(Integer id);
}
6.接口测试
3.新增部门接口
1.查看原型
2.查看接口
3.controller
/**
* 部门管理Controller
*/
@Slf4j
@RestController
@RequestMapping("/depts")
public class DeptController {
@Autowired
private DeptService deptService;
/**
* 添加部门信息
*/
@PostMapping
public Result add(@RequestBody Dept dept) {
log.info("添加部门信息:{}", dept);
deptService.add(dept);
return Result.success();
}
}
- 通过Mybatis 提供的 @ReqiestBody 注解, 把前端传递的JSON数据封装道实体类中
- 抽取公共路径: 为了简化请求路径的定义, 可以在类上, 通过 @RequestMapping() 抽取公共路径
- 完整的请求路径 = 类上的@RequestMapping 的value 属性 + 方法上的@RequestMapping 的value属性
4.service
/**
* 部门管理
*/
public interface DeptService {
/**
* 添加部门信息
* @param dept
*/
void add(Dept dept);
}
@Service
public class DeptServiceImpl implements DeptService {
@Autowired
private DeptMapper deptMapper;
@Override
public void add(Dept dept) {
dept.setCreateTime(LocalDateTime.now());
dept.setUpdateTime(LocalDateTime.now());
deptMapper.insert(dept);
}
}
- 补充基础属性: 需要补充创建时间和更新时间两个字段信息
- 获取系统当前时间: LocalDateTime.now()
5.mapper
/**
* 部门管理
*/
@Mapper
public interface DeptMapper {
/**
* 添加部门信息
*
* @param dept
*/
@Insert("insert into dept(name,create_time,update_time) values(#{name},#{createTime},#{updateTime})")
void insert(Dept dept);
}
6.接口测试
员工管理
1.分页查询接口
1.1查看原型
先完成分页查询, 之后在改造接口, 加上条件查询
- 分页查询语法: select * from emp limit 0,5;
- 计算起始索引: 起始索引(0开始) = (页码-1)*每页条数
- 查询返回记录数: 等于每页展示记录数
1.2实现思路
- 前端给后端传递参数: 当前页码值(page) / 每页展示记录数(pageSize)
- 后端给前端返回数据: 数据列表list + 总记录数total => 把返回的数据封装在 PageBean 实体类中
- 准备分页数据实体类PageBean
/**
* 分页查询结果封装类
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PageBean {
public Long total; //总记录数
public List rows; //数据列表
}
1.3查看接口
1.4Mapper
/**
* 员工管理
*/
@Mapper
public interface EmpMapper {
/**
* 查询总记录数
*/
@Select("select count(*) from emp")
public Long count();
/**
* 分页查询,获取列表数据
*/
@Select("select * from emp limit #{start},#{pageSize}")
public List<Emp> page(Integer start, Integer pageSize);
}
1.5Controller
/**
* 员工管理Controller
*/
@Slf4j
@RestController
@RequestMapping("/emps")
public class EmpController {
@Autowired
private EmpService empService;
/**
* 分页查询员工数据
*
* @return
*/
@GetMapping
public Result page(@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer pageSize,
) {
log.info("分页查询参数:{},{}", page, pageSize);
PageBean pageBean = empService.page(page, pageSize);
return Result.success(pageBean);
}
}
- 通过 @RequestParam(defaultValue = "1") 注解指定参数的默认值
1.6Server
/**
* 员工管理
*/
public interface EmpService {
/**
* 分页查询员工数据
* @param page
* @param pageSize
* @return
*/
PageBean page(Integer page, Integer pageSize, String name, Short gender, LocalDate begin,LocalDate end);
}
@Service
public class EmpServiceImpl implements EmpService {
@Autowired
private EmpMapper empMapper;
@Override
public PageBean page(Integer page, Integer pageSize) {
//获取总记录数
Long count = empMapper.count();
//获取分页查询结果
Integer start = (page - 1) * pageSize;
List<Emp> empList = empMapper.page(start, pageSize);
//封装PageBean对象
PageBean pageBean = new PageBean(count, empList);
return pageBean;
}
}
1.7PageHelper插件
使用插件帮助我们简化分页查询的代码
引入依赖
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.4.2</version>
</dependency>
改造Mapper
只需要执行普通的查询语句即可, 分页操作插件帮我们自动完成
/**
* 员工管理
*/
@Mapper
public interface EmpMapper {
/**
* 分页查询,获取列表数据
*/
@Select("select * from emp")
public List<Emp> list();
}
改造Server
@Service
public class EmpServiceImpl implements EmpService {
@Autowired
private EmpMapper empMapper;
@Override
public PageBean page(Integer page, Integer pageSize) {
//1. 设置分页参数
PageHelper.startPage(page, pageSize);
//2. 执行普通查询
List<Emp> empList = empMapper.list();
//3. 强制转换查询类型
// Page是插件提供的分页结果封装类
Page<Emp> p = (Page<Emp>) empList;
//4. 在分页结果中拿到需要的数据
PageBean pageBean = new PageBean(p.getTotal(), p.getResult());
return pageBean;
}
}
- 注意: 强转类型报错切换插件版本到1.4.6即可
1.8接口测试
2.分页条件查询
在完成分页查询的基础上, 增加条件查询
/**
* 员工管理Controller
*/
@Slf4j
@RestController
@RequestMapping("/emps")
public class EmpController {
@Autowired
private EmpService empService;
/**
* 分页查询员工数据
*
* @return
*/
@GetMapping
public Result page(@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer pageSize,
String name, Short gender,
@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin,
@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end) {
log.info("分页查询参数:{},{},{},{},{},{}", page, pageSize, name, gender, begin, end);
PageBean pageBean = empService.page(page, pageSize, name, gender, begin, end);
return Result.success(pageBean);
}
}
@Service
public class EmpServiceImpl implements EmpService {
@Autowired
private EmpMapper empMapper;
@Override
public PageBean page(Integer page, Integer pageSize, String name, Short gender, LocalDate begin, LocalDate end) {
PageHelper.startPage(page, pageSize);
//执行查询
List<Emp> empList = empMapper.list(name, gender, begin, end);
Page<Emp> p = (Page<Emp>) empList;
//封装PageBean对象
PageBean pageBean = new PageBean(p.getTotal(), p.getResult());
return pageBean;
}
}
/**
* 员工管理
*/
@Mapper
public interface EmpMapper {
/**
* 分页查询,获取列表数据 (xml文件)
*/
public List<Emp> list(String name, Short gender, LocalDate begin, LocalDate end);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mapper.EmpMapper">
<!-- 分页条件查询 -->
<select id="list" resultType="com.itheima.pojo.Emp">
select * from emp
<where>
<if test="name!=null and name!='' ">
name like concat('%',#{name},'%')
</if>
<if test="gender!=null">
and gender = #{gender}
</if>
<if test="begin!=null and end!=null">
and entrydate between #{begin} and #{end}
</if>
</where>
order by update_time desc
</select>
</mapper>
- 在Controller层接收条件参数, 把参数逐级传递到Mapper层
- 使用动态SQL-XML映射文件完成条件查询
- 对于字符串类型的数据, 如果前端不传递, 后端会默认接收空字符串, 所以在动态sql中要多一步判断
接口测试
3.删除接口
1.查看原型
单个删除和批量删除用一个接口就可以
2.查看接口
3.实现思路
4.controller
/**
* 员工管理Controller
*/
@Slf4j
@RestController
@RequestMapping("/emps")
public class EmpController {
@Autowired
private EmpService empService;
/**
* 删除员工
*/
@Log
@DeleteMapping("/{ids}")
public Result delete(@PathVariable List<Integer> ids) {
log.info("批量删除员工:", ids);
empService.delete(ids);
return Result.success();
}
}
5.server
/**
* 员工管理
*/
public interface EmpService {
/**
* 删除员工
* @param ids
*/
void delete(List<Integer> ids);
}
@Service
public class EmpServiceImpl implements EmpService {
@Autowired
private EmpMapper empMapper;
/**
* 批量删除员工
*
* @param ids
*/
@Override
public void delete(List<Integer> ids) {
empMapper.delete(ids);
}
}
6.mapper
/**
* 员工管理
*/
@Mapper
public interface EmpMapper {
/**
* 批量删除员工
*
* @param ids
*/
void delete(List<Integer> ids);
/**
* 新增员工
*
* @param emp
*/
@Insert("insert into emp(username,name,gender,image,job,entrydate,dept_id,create_time,update_time)" +
" values(#{username},#{name},#{gender},#{image},#{job},#{entrydate},#{deptId},#{createTime},#{updateTime})")
void insert(Emp emp);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mapper.EmpMapper">
<!-- 批量删除员工 -->
<delete id="delete">
delete
from emp
where id in
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</delete>
</mapper>
7.接口测试
4.新增接口
1.查看原型
2.查看接口
3.实现思路
4.contoller
/**
* 员工管理Controller
*/
@Slf4j
@RestController
@RequestMapping("/emps")
public class EmpController {
@Autowired
private EmpService empService;
/**
* 新增员工
*/
@Log
@PostMapping
public Result save(@RequestBody Emp emp) {
log.info("新增员工:{}", emp);
empService.save(emp);
return Result.success();
}
}
5.server
/**
* 员工管理
*/
public interface EmpService {
/**
* 新增员工
* @param emp
*/
void save(Emp emp);
}
@Service
public class EmpServiceImpl implements EmpService {
@Autowired
private EmpMapper empMapper;
/**
* 新增员工
*
* @param emp
*/
@Override
public void save(Emp emp) {
emp.setCreateTime(LocalDateTime.now());
emp.setUpdateTime(LocalDateTime.now());
empMapper.insert(emp);
}
}
6.mapper
/**
* 员工管理
*/
@Mapper
public interface EmpMapper {
/**
* 新增员工
*
* @param emp
*/
@Insert("insert into emp(username,name,gender,image,job,entrydate,dept_id,create_time,update_time)" +
" values(#{username},#{name},#{gender},#{image},#{job},#{entrydate},#{deptId},#{createTime},#{updateTime})")
void insert(Emp emp);
}
7.接口测试
基础功能
在Controller层接收数据,
使用@RequestBody注解把JSON参数封装到实体类中
在Service层补充基础字段
在Mapper层插入数据
5.文件上传
把本地图片,视频, 音频等文件上传到服务器, 供其他用户浏览或下载
前端文件上传三要素
- 表单项 type="file"
- 表单提交方式必须post
- 表单的enctype属性默认值是x-www-urlencoded, 用于提交普通数据
- 如果需要提交文件数据, 必须设置为 multipart/from-data
文件提交测试
- 把前端页面引入到工程中, 放到resources/static目录下
- 查看前端代码,: 通过修改表单数据类型进行测试, action="/upload" 是指定提交路径
- 编写后端代码:
- 对于普通字段, 后端按正常方式接收数据
- 对于文件字段. 后端通过springboot提供的 MultipartFile方法 接收文件
- 要保证前后端字段名一致才能成功接收文件 如果不一致, 可以通过@RequestParam("前端字段")完成映射
- 把页面运行到火狐浏览器, 谷歌的数据做了封装, 看起来不直观
- 通过通过抓包对比数据提交
默认的提交格式, 只是提交了文件名
文件提交格式, 用boundary属性的值分隔每项表单数据, 真正提交文件的内容
- 后端接收到文件是临时文件, 存储在电脑磁盘中, 请求响应结束后, 临时文件就自动删除了
6.本地存储
在服务端, 接收到上传的文件之后, 把文件存储到本地磁盘中
@RestController
public class UploadController {
@PostMapping("/upload")
public Result upload(String username, Integer age, MultipartFile image) throws IOException {
log.info("文件上传:{},{},{}", username, age, image);
//获取原始文件名
//文件名不能固定死,用上传文件名命名即可
String originalFilename = image.getOriginalFilename();
//文件名不能重复 ->uuid
int index = originalFilename.lastIndexOf("."); //拿到文件名字最后一个.的位置
String extname = originalFilename.substring(index); //从最后一个.的位置截取(拿到文件类型)
String newFileName = UUID.randomUUID().toString() + extname; //拼接成唯一的文件名
log.info("新的唯一文件名: {}",newFileName);
// 将文件存储到服务器的磁盘目录中
//D:\UserDatas\Work\Text\Note\16,JavaWeb\code\image
image.transferTo(new File("D:\\UserDatas\\Work\\Text\\Note\\16,JavaWeb\\code\\image\\" + newFileName));
return Result.success();
}
}
- 通过MultipartFile类提供的方法, 获取原始文件名, 作为文件名
- 通过MultipartFile类提供的方法, 把接收到的文件存储到服务器磁盘中
- 通过原始文件名保存文件存在重名风险, 一旦文件重名会发生覆盖
- 所以使用UUID+文件后缀, 作为唯一的文件名
- 在sringboot中, 默认单个文件最大上传1M, 如果需要上传大文件,需要进一步配置
#限制单个文件大小为10MB
spring.servlet.multipart.max-file-size=10MB
#限制单个请求的大小为100MB (一次请求可以上传多个文件)
spring.servlet.multipart.max-request-size=100MB
- MultipartFile类提供的常用方法
在实际业务中, 把文件直接储存在服务器本地, 是比较少见的, 主流是使用文件服务器或者云储存服务
- 磁盘储存的文件, 无法被前端直接访问
- 电脑磁盘有限, 无法承载大量数据文件
- 无法避免磁盘损坏的风险
- 自己搭建文件服务器, 设计相关技术 FastDFS / MinIO
- 购买云厂商的文件服务器, 比如阿里云 / 腾讯云 / 华为云
7.阿里云oss
介绍
阿里云是阿里巴巴集团旗下全球领先的云计算公司, 也是国内最大的云服务提供商
阿里云对象储存OSS, 是一款海量, 安全, 低成本, 高可靠的云储存服务, 使用oss, 可以通过网络随时存储和调用包括文本, 图片, 音频, 视频等各种文件
流程: 浏览器提交文件到服务器, 通过阿里云oss服务, 把文件上传至云端
使用思路
- 官方文档: 安装OSS Java SDK_对象存储(OSS)-阿里云帮助中心
- 注册阿里云 -> 充值(学习阶段可以使用免费的空间)
- 开通对象储存服务(OSS) -> 创建bucket -> 按照day11的资料创建即可, 很简单
- Bucket: 储存空间是用户用于储存文件的容器, 所有的文件都必须隶属于某个储存空间
- 主要的选项:
- 储存空间名称: 自定义
- 地域: 就近原则
- 储存类型: 标准储存
- 读写权限: 公共读
- 获取AccessKey(秘钥)
- 在个人中心可以查看Secret
入门程序
查看文档: SDK下载 -> 查看SDK示例 -> 文档中心打开
引入依赖
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.15.1</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>
入门代码
public class ALiYunOss {
public static void main(String[] args) throws Exception {
// Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
String endpoint = "https://oss-cn-beijing.aliyuncs.com";
// 身份信息
String accessKeyId = "LTAI5tFE6zMbdaLyhSvNM9J1";
String accessKeySecret = "jeHMl9EBnCOErmomdgKrZrmCKMcKTt";
// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
// EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// 填写Bucket名称,例如examplebucket。
String bucketName = "tlias-web-practice";
// 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。
String objectName = "iphone15pro.png";
// 填写本地文件的完整路径,例如D:\\localpath\\examplefile.txt。
// 如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件流。
String filePath = "D:\\UserDatas\\Work\\Text\\Note\\16,JavaWeb\\code\\image\\iphone15pro.png";
// 创建OSSClient实例。
// OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);
OSS ossClient = new OSSClientBuilder().build(endpoint,accessKeyId, accessKeySecret);
try {
InputStream inputStream = new FileInputStream(filePath);
// 创建PutObjectRequest对象。
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, inputStream);
// 创建PutObject请求。
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();
}
}
}
}
- 查看地域节点: wen-tilas -> 概览 -> 访问端口 -> 外网访问(地域节点)
- 查看资源: web-tlias -> 文件列表
8.文件上传接口
工作流程
查看接口
准备工作
引入阿里云文件上传需要使用的依赖
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.15.1</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>
引入阿里云 OSS 工具类, 是由官方的示例代码改造而来, 并且把工具类交给IOC容器管理
/**
* 阿里云 OSS 工具类
*/
@Component
public class AliOSSUtils {
//手动指定
// 域名信息
@Value("${aliyun.oss.endpoint}")
private String endpoint;
// 身份信息
@Value("${aliyun.oss.accessKeyId}")
private String accessKeyId;
// 身份信息
@Value("${aliyun.oss.accessKeySecret}")
private String accessKeySecret;
// 填写Bucket名称
@Value("${aliyun.oss.bucketName}")
private String bucketName;
/**
* 实现上传图片到OSS
*/
public String upload(MultipartFile file) throws IOException {
// 获取阿里云oss参数
String endpoint = aliOSSProperties.getEndpoint();
String accessKeyId = aliOSSProperties.getAccessKeyId();
String accessKeySecret = aliOSSProperties.getAccessKeySecret();
String bucketName = aliOSSProperties.getBucketName();
// 获取上传的文件的输入流
InputStream inputStream = file.getInputStream();
// 避免文件覆盖
String originalFilename = file.getOriginalFilename();
String fileName = UUID.randomUUID().toString() + originalFilename.substring(originalFilename.lastIndexOf("."));
//上传文件到 OSS
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
ossClient.putObject(bucketName, fileName, inputStream);
//文件访问路径
String url = endpoint.split("//")[0] + "//" + bucketName + "." + endpoint.split("//")[1] + "/" + fileName;
// 关闭ossClient
ossClient.shutdown();
return url;// 把上传到oss的路径返回
}
}
controller
@RestController
public class UploadController {
// 注入阿里云OSS对象
@Autowired
private AliOSSUtils aliOSSUtils;
@PostMapping("/upload")
public Result upload(MultipartFile image) throws IOException {
log.info("文件上传,文件名:{}", image.getOriginalFilename());
// 使用阿里云对象的方法进行文件上传
String url = aliOSSUtils.upload(image);
log.info("文件上传完成,文件的URL:{}", url);
return Result.success(url);
}
}
接口测试
9.详情接口
1.查看原型
2.查看接口
3.实现思路
4.controller
/**
* 员工管理Controller
*/
@Slf4j
@RestController
@RequestMapping("/emps")
public class EmpController {
@Autowired
private EmpService empService;
/**
* 查询员工信息
*/
@GetMapping("/{id}")
public Result getById(@PathVariable Integer id) {
log.info("根据id查询员工信息:{}", id);
Emp emp = empService.getByID(id);
return Result.success(emp);
}
}
5.server
/**
* 员工管理
*/
public interface EmpService {
/**
* 查询员工
* @param id
* @return
*/
Emp getByID(Integer id);
}
@Service
public class EmpServiceImpl implements EmpService {
@Autowired
private EmpMapper empMapper;
/**
* 查询员工
*
* @param id
* @return
*/
@Override
public Emp getByID(Integer id) {
return empMapper.getById(id);
}
}
6.mapper
/**
* 员工管理
*/
@Mapper
public interface EmpMapper {
/**
* 查询员工
* @param id
* @return
*/
@Select("select * from emp where id = #{id}")
Emp getById(Integer id);
}
7.接口测试
10.编辑接口
1.查看原型
2.查看接口
3.实现思路
4.controller
/**
* 员工管理Controller
*/
@Slf4j
@RestController
@RequestMapping("/emps")
public class EmpController {
@Autowired
private EmpService empService;
/**
* 更新员工信息
*/
@Log
@PutMapping
public Result updata(@RequestBody Emp emp) {
log.info("更新的员工信息:{}", emp);
empService.updata(emp);
return Result.success();
}
}
5.server
/**
* 员工管理
*/
public interface EmpService {
/**
* 更新员工信息
* @param emp
*/
void updata(Emp emp);
}
@Service
public class EmpServiceImpl implements EmpService {
@Autowired
private EmpMapper empMapper;
/**
* 更新员工信息
* @param emp
*/
@Override
public void updata(Emp emp) {
emp.setUpdateTime(LocalDateTime.now());
empMapper.updata(emp);
}
}
6.mapper
/**
* 员工管理
*/
@Mapper
public interface EmpMapper {
/**
* 更新员工数据
* @param emp
*/
void updata(Emp emp);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mapper.EmpMapper">
<!-- 更新员工 -->
<update id="updata">
update emp
<set>
<if test="username!=null and username!=''">
username = #{username},
</if>
<if test="password!=null and password!=''">
password = #{password},
</if>
<if test="name!=null and name!=''">
name = #{name},
</if>
<if test="gender!=null">
gender = #{gender},
</if>
<if test="image!=null and image!=''">
image = #{image},
</if>
<if test="job!=null">
job = #{job},
</if>
<if test="entrydate!=null">
entrydate = #{entrydate},
</if>
<if test="deptId!=null">
dept_id = #{deptId},
</if>
<if test="updateTime!=null">
update_time = #{updateTime},
</if>
</set>
where id = #{id}
</update>
</mapper>
7.接口测试
原文地址:https://blog.csdn.net/CSDN20221005/article/details/141804677
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!