[Java]SpringBoot接口开发

准备工作

1.效果展示

该项目的最终实现效果

2.环境搭建

完成项目环境的搭建

  1. 新建数据库和数据表 (tlias数据库/dept部门表/emp员工表)

  1. 创建springboot工程, 引入起步依赖 (wbe依赖/mybatis依赖/mysql驱动依赖/lombok依赖)

  1. 在配置文件application.properties中配置mybatis的连接信息, 准备需要的实体类

  1. 准备基础结构Controller / Service(接口/实现类) / Mapper

  1. 引入同意结果封装类

  1. 也可以使用现成的项目环境

4.开发规范

开发模式: 本项目采用前后端分离的开发模式

前后端需要严格遵守接口文档, 通过接口文档完成项目的协作开发

软件风格: 采用REST风格, 译为表述性状态转换, 是一种软件架构风格

  1. REST风格的特点
  • 通过URL定位资源
  • 通过HTTP动词描述操作
  1. REST是风格, 不是规定, 可以打破
  2. 描述模块的功能通常使用复数, 也就是加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);
    } 
}
  1. 在项目中不建议使用sout记录日志
  2. 通过lombok提供的 @Slf4j 注解, 可以自动生成日志记录对象log
  3. 通过调用日志记录对象的方法, 记录日志非常方便和专业

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();
    }

}
  1. @Override注解是java提供的, 用于标明方法重写,提高代码可读性, 是非必须的

1.6mapper

/**
 * 部门管理
 */
@Mapper
public interface DeptMapper {

    /**
     * 查询全部部门
     *
     * @return
     */
    @Select("select * from dept")
    List<Dept> list();
}

1.7接口测试

通过possmain工具完成接口的测试工作

1.8联调测试

前后端联调: 启动前后端程序, 通过前端工程访问后端工程, 进行功能调试

  1. 前端程序一般部署在nginx服务器
  2. 资料中提供了前端工程代码, 解压即可
  3. 启动: 双击nginx.exe文件
  4. 访问: http://localhost:90/
  5. 部署: 把资源放到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();
    }
}
  1. 通过Mybatis 提供的 @ReqiestBody 注解, 把前端传递的JSON数据封装道实体类中
  2. 抽取公共路径: 为了简化请求路径的定义, 可以在类上, 通过 @RequestMapping() 抽取公共路径
  3. 完整的请求路径 = 类上的@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);
    }

}
  1. 补充基础属性: 需要补充创建时间和更新时间两个字段信息
  2. 获取系统当前时间: 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查看原型

先完成分页查询, 之后在改造接口, 加上条件查询

  1. 分页查询语法: select * from emp limit 0,5;
  2. 计算起始索引: 起始索引(0开始) = (页码-1)*每页条数
  3. 查询返回记录数: 等于每页展示记录数

1.2实现思路

  1. 前端给后端传递参数: 当前页码值(page) / 每页展示记录数(pageSize)
  2. 后端给前端返回数据: 数据列表list + 总记录数total => 把返回的数据封装在 PageBean 实体类中
  3. 准备分页数据实体类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);
    }
}
  1. 通过 @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. 注意: 强转类型报错切换插件版本到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>
  1. 在Controller层接收条件参数, 把参数逐级传递到Mapper层
  2. 使用动态SQL-XML映射文件完成条件查询
  3. 对于字符串类型的数据, 如果前端不传递, 后端会默认接收空字符串, 所以在动态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.文件上传

把本地图片,视频, 音频等文件上传到服务器, 供其他用户浏览或下载

前端文件上传三要素

  1. 表单项 type="file"
  2. 表单提交方式必须post
  3. 表单的enctype属性默认值是x-www-urlencoded, 用于提交普通数据
  4. 如果需要提交文件数据, 必须设置为 multipart/from-data

文件提交测试

  1. 把前端页面引入到工程中, 放到resources/static目录下

  1. 查看前端代码,: 通过修改表单数据类型进行测试, action="/upload" 是指定提交路径

  1. 编写后端代码:
  • 对于普通字段, 后端按正常方式接收数据
  • 对于文件字段. 后端通过springboot提供的 MultipartFile方法 接收文件
  • 要保证前后端字段名一致才能成功接收文件 如果不一致, 可以通过@RequestParam("前端字段")完成映射

  1. 把页面运行到火狐浏览器, 谷歌的数据做了封装, 看起来不直观
  2. 通过通过抓包对比数据提交

默认的提交格式, 只是提交了文件名

文件提交格式, 用boundary属性的值分隔每项表单数据, 真正提交文件的内容

  1. 后端接收到文件是临时文件, 存储在电脑磁盘中, 请求响应结束后, 临时文件就自动删除了

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();
    }
}
  1. 通过MultipartFile类提供的方法, 获取原始文件名, 作为文件名
  2. 通过MultipartFile类提供的方法, 把接收到的文件存储到服务器磁盘中
  3. 通过原始文件名保存文件存在重名风险, 一旦文件重名会发生覆盖
  4. 所以使用UUID+文件后缀, 作为唯一的文件名
  5. 在sringboot中, 默认单个文件最大上传1M, 如果需要上传大文件,需要进一步配置
#限制单个文件大小为10MB
spring.servlet.multipart.max-file-size=10MB  
#限制单个请求的大小为100MB (一次请求可以上传多个文件)
spring.servlet.multipart.max-request-size=100MB
  1. MultipartFile类提供的常用方法

在实际业务中, 把文件直接储存在服务器本地, 是比较少见的, 主流是使用文件服务器或者云储存服务

  1. 磁盘储存的文件, 无法被前端直接访问
  2. 电脑磁盘有限, 无法承载大量数据文件
  3. 无法避免磁盘损坏的风险
  4. 自己搭建文件服务器, 设计相关技术 FastDFS / MinIO

  1. 购买云厂商的文件服务器, 比如阿里云 / 腾讯云 / 华为云

7.阿里云oss

介绍

阿里云是阿里巴巴集团旗下全球领先的云计算公司, 也是国内最大的云服务提供商

阿里云对象储存OSS, 是一款海量, 安全, 低成本, 高可靠的云储存服务, 使用oss, 可以通过网络随时存储和调用包括文本, 图片, 音频, 视频等各种文件

流程: 浏览器提交文件到服务器, 通过阿里云oss服务, 把文件上传至云端

使用思路

  1. 官方文档: 安装OSS Java SDK_对象存储(OSS)-阿里云帮助中心
  2. 注册阿里云 -> 充值(学习阶段可以使用免费的空间)
  3. 开通对象储存服务(OSS) -> 创建bucket -> 按照day11的资料创建即可, 很简单
  4. Bucket: 储存空间是用户用于储存文件的容器, 所有的文件都必须隶属于某个储存空间
  5. 主要的选项:
  • 储存空间名称: 自定义
  • 地域: 就近原则
  • 储存类型: 标准储存
  • 读写权限: 公共读
  • 获取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();
            }
        }
    }
}
  1. 查看地域节点: wen-tilas -> 概览 -> 访问端口 -> 外网访问(地域节点)
  2. 查看资源: 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.接口测试

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值