【软构件】实验1 Spring Boot微服务

一、目的

实验目的:

  • 掌握Spring Boot搭建微服务的一般步骤,理解微服务体系架构。

实验要求:

  • 独立完成实验操作,并撰写实验报告(实验报告模板见附件)。

实验内容:

  • Spring Boot微服务框架搭建
    • (1)设计项目框架,并确定微服务的划分逻辑,如api、model和server,或者api、service和server,或者其他的(不限微服务个数,但要合理)。
    • (2)搭建实际项目(建议使用maven),并添加常用dependencies,如mysql、mybatis、log4j、lombok、jackson、redis等。
    • (3)编写应用程序入口,测试并运行。
    • (4)添加若干控制器,服务之间的调用遵循Restful风格,功能及入口地址自定,并测试所编写的功能。
    • (5)注意:本实验搭建的Spring Boot框架将用于后续实验扩展,因此请认真完成!

二、实验内容与设计思想

2.1 设计思路
  1. 新建项目

  2. 构建api模块

  3. 构建service模块

  4. 构建server模块

  5. 引入各个依赖:dependencies,如mysql、mybatis、log4j、lombok、jackson、redis

  6. 在api中编写实体类

  7. 编写redisConfig和resConfig

  8. 在service和server中编写controller进行测试

2.2 主要数据结构
public class Course implements Serializable
{
private Integer id;
private String name;
private Date startTime;
private Date endTime;
private Double price;
private String introduction;
private String personId;
}
public class Diary implements Serializable
{
private Integer id;
private Integer courseId;
private Date startTime;
private String content;
private String title;
private String personId;
}
public class Order implements Serializable
{
private Integer id;
private Date startTime;
private String coupon;
private Double price;
private String evaluate;
private Integer evaluateStart;
private Integer courseId;
private Integer status;
private String personId;
}
public class Person implements Serializable
{
private String id;
private String nickname;
private String introduction;
private Integer age;
private String weight;
private Date joinTime;
private String email;
private String password;
private String image;
private Integer height;
private String sex;
private Integer role;
}
public class Revert implements Serializable
{
private Integer id;
private String content;
private Date startTime;
private Integer diaryId;
private String personId;
}
2.3 主要代码结构
└── api/
    ├── pom.xml
    └── src/main/java/
                └── domain/
                    ├── Course.java
                    ├── Diary.java
                    ├── Order.java
                    ├── Person.java
                    ├── Revert.java
└── server/src/main/
        └── java/com/example/server/
                            └── controller/
                                ├── MyCourseController.java
                                ├── MyDiaryController.java
                                ├── MyOrderController.java
                                ├── MyPersonController.java
                                ├── MyRedisController.java
                                ├── MyRevertController.java
                            └── demos/
                                └── web/
                                    ├── BasicController.java
                                    ├── PathVariableController.java
                                    ├── User.java
                            ├── ServerApplication.java
                            └── util/
                                ├── Config.java
                                ├── RedisConfig.java
            └── resources/
                ├── application.properties
└── service/src/main/
            └── java/com/example/service/
                            └── controller/
                                ├── CourseController.java
                                ├── DiaryController.java
                                ├── OrderController.java
                                ├── PersonController.java
                                ├── RevertController.java
                            └── mapper/
                                ├── CourseMapper.java
                                ├── DiaryMapper.java
                                ├── OrderMapper.java
                                ├── PersonMapper.java
                                ├── RevertMapper.java
                            └── service/
                                ├── CourseService.java
                                ├── DiaryService.java
                                └── impl/
                                    ├── CourseServiceImpl.java
                                    ├── DiaryServiceImpl.java
                                    ├── OrderServiceImpl.java
                                    ├── PersonServiceImpl.java
                                    ├── RevertServiceImpl.java
                                ├── OrderService.java
                                ├── PersonService.java
                                ├── RevertService.java
                            ├── ServiceApplication.java
                            └── util/
                                ├── CORSFilter.java
                                ├── R.java
            └── resources/
                ├── application.properties
                └── mapper/
                    ├── CourseMapper.xml
                    ├── DiaryMapper.xml
                    ├── OrderMapper.xml
                    ├── PersonMapper.xml
                    ├── RevertMapper.xml
└── src/
    └── main/
2.4 主要代码段分析

service模块的controller示例:

@RestController
@RequestMapping("/course")
public class CourseController
{
        @Resource
    private CourseService courseService;

    /**
     * 全查询
     *
     * @param course 筛选条件
     * @return 查询结果
     */
    @GetMapping
    public R queryAll(Course course)
    {
        return this.courseService.queryAll(course);
    }

    /**
     * 新增数据
     *
     * @param course 实体
     * @return 新增结果
     */
    @PostMapping
    public R add(@RequestBody Course course)
    {
        return this.courseService.insert(course);
    }

    /**
     * 更新数据
     *
     * @param course 实体
     * @return 更新结果
     */
    @PutMapping
    public R update(@RequestBody Course course)
    {
        return this.courseService.update(course);
    }

    /**
     * 删除数据
     *
     * @param id 主键
     * @return 删除是否成功
     */
    @DeleteMapping
    public R deleteById(Integer id)
    {
        return this.courseService.deleteById(id);
    }
}

server的controller示例:

@RestController
@RequestMapping
public class MyCourseController
{
    private final String URL_PREFIX = "http://localhost:8081";
    @Resource
    private RestTemplate restTemplate;

    @GetMapping("/my/course")
    public R testQueryAllCourse() {
        return restTemplate.getForObject(URL_PREFIX + "/course", R.class);
    }

    @PostMapping("/my/course")
    public R testAddCourse(@RequestBody Course course) {
        return restTemplate.postForObject(URL_PREFIX + "/course", course, R.class);
    }

    @PutMapping("/my/course")
    public R testUpdateCourse(@RequestBody Course course) {
        return restTemplate.exchange(URL_PREFIX + "/course", HttpMethod.PUT, new HttpEntity<>(course), R.class).getBody();
    }

    @DeleteMapping("/my/course/{id}")
    public R testDeleteCourse(@PathVariable Integer id) {
        return restTemplate.exchange(URL_PREFIX + "/course?id=" + id, HttpMethod.DELETE, null, R.class).getBody();
    }
}

三、实验使用环境

平台:win10

软件:idea

四、实验步骤和调试过程

4.1 实验步骤
  1. 新建项目,构建api模块,service模块,server模块

  2. 引入各个依赖:dependencies,如mysql、mybatis、log4j、lombok、jackson、redis

  3. 在api中编写实体类

public class Course implements Serializable
{
    private Integer id;
    private String name;
    private Date startTime;
    private Date endTime;
    private Double price;
    private String introduction;
    private String personId;
}

public class Diary implements Serializable
{
    private Integer id;
    private Integer courseId;
    private Date startTime;
    private String content;
    private String title;
    private String personId;
}

public class Order implements Serializable
{
    private Integer id;
    private Date startTime;
    private String coupon;
    private Double price;
    private String evaluate;
    private Integer evaluateStart;
    private Integer courseId;
    private Integer status;
    private String personId;
}

public class Person implements Serializable
{
    private String id;
    private String nickname;
    private String introduction;
    private Integer age;
    private String weight;
    private Date joinTime;
    private String email;
    private String password;
    private String image;
    private Integer height;
    private String sex;
    private Integer role;
}

public class Revert implements Serializable
{
    private Integer id;
    private String content;
    private Date startTime;
    private Integer diaryId;
    private String personId;
}
  1. 编写redisConfig和resConfig
@Configuration
public class Config {
   @Bean
   public RestTemplate restTemplate()
   {
      return new RestTemplate();
   }
}
@Configuration
public class RedisConfig
{
    @Autowired(required = false)
    private RedisConnectionFactory redisConnectionFactory;//Redis连接工厂(相当于redis-cli的窗口)

    @Bean
    public RedisTemplate<String, Object> redisTemplate()//相当于redis-cli的命令行
    {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        redisTemplate.setKeySerializer(new StringRedisSerializer());
//        redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());//JSON泛型
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        return redisTemplate;
    }
    @Bean
    public StringRedisTemplate stringRedisTemplate()
    {
        StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
        stringRedisTemplate.setConnectionFactory(redisConnectionFactory);
        return stringRedisTemplate;
    }
}
  1. 在service和server中编写controller进行测试

service模块的controller示例(代码太多,只放其中一个controller示例):

@RestController
@RequestMapping("/course")
public class CourseController
{
        @Resource
    private CourseService courseService;

    /**
     * 全查询
     *
     * @param course 筛选条件
     * @return 查询结果
     */
    @GetMapping
    public R queryAll(Course course)
    {
        return this.courseService.queryAll(course);
    }

    /**
     * 新增数据
     *
     * @param course 实体
     * @return 新增结果
     */
    @PostMapping
    public R add(@RequestBody Course course)
    {
        return this.courseService.insert(course);
    }

    /**
     * 更新数据
     *
     * @param course 实体
     * @return 更新结果
     */
    @PutMapping
    public R update(@RequestBody Course course)
    {
        return this.courseService.update(course);
    }

    /**
     * 删除数据
     *
     * @param id 主键
     * @return 删除是否成功
     */
    @DeleteMapping
    public R deleteById(Integer id)
    {
        return this.courseService.deleteById(id);
    }
}

server的controller示例(代码太多,只放其中一个controller示例):

@RestController
@RequestMapping
public class MyCourseController
{
    private final String URL_PREFIX = "http://localhost:8081";
    @Resource
    private RestTemplate restTemplate;

    @GetMapping("/my/course")
    public R testQueryAllCourse() {
        return restTemplate.getForObject(URL_PREFIX + "/course", R.class);
    }

    @PostMapping("/my/course")
    public R testAddCourse(@RequestBody Course course) {
        return restTemplate.postForObject(URL_PREFIX + "/course", course, R.class);
    }

    @PutMapping("/my/course")
    public R testUpdateCourse(@RequestBody Course course) {
        return restTemplate.exchange(URL_PREFIX + "/course", HttpMethod.PUT, new HttpEntity<>(course), R.class).getBody();
    }

    @DeleteMapping("/my/course/{id}")
    public R testDeleteCourse(@PathVariable Integer id) {
        return restTemplate.exchange(URL_PREFIX + "/course?id=" + id, HttpMethod.DELETE, null, R.class).getBody();
    }
}

RedisController:

@RestController
@RequestMapping("/redis")
public class MyRedisController
{

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @GetMapping("/{key}")
    public R getValue(@PathVariable String key)
    {
        System.out.println("get:key:" + key);
        Object value = redisTemplate.opsForValue().get(key);
        return R.ok().setData(value);
    }

    @GetMapping
    public R getAllValue()
    {
        Set<String> keys = redisTemplate.keys("*");
        keys.remove("name");
        System.out.println("keys" + keys);
        Map<String, Object> data = new HashMap<>();
        if (keys != null)
        {
            for (String key : keys)
            {
                System.out.println(key);
                Object value = redisTemplate.opsForValue().get(key);
                data.put(key, value);
            }
        }
        return R.ok().setData(data);
    }

    @PostMapping("/{key}")
    public R addValue(@PathVariable String key, @RequestBody Object value)
    {
        try
        {
            System.out.println("post:key:" + key);
            redisTemplate.opsForValue().set(key, value);
            return R.ok().setData(true);
        } catch (Exception e)
        {
            e.printStackTrace();
            return R.exp().setData(e.getMessage());
        }

    }

    @PostMapping("/{key}/{expirationInSeconds}")
    public R setWithExpiration(@PathVariable String key, @PathVariable int expirationInSeconds, @RequestBody Object value)
    {
        try
        {
            System.out.println("post:key:" + key);
            ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();
            valueOperations.set(key, value);
            redisTemplate.expire(key, expirationInSeconds, TimeUnit.SECONDS);
            return R.ok().setData(true);
        } catch (Exception e)
        {
            e.printStackTrace();
            return R.exp().setData(e.getMessage());
        }
    }

    @DeleteMapping("/{key}")
    public ResponseEntity<Void> deleteValue(@PathVariable String key)
    {
        System.out.println("delete:key:" + key);
        redisTemplate.delete(key);
        return ResponseEntity.noContent().build();
    }

    @PutMapping("/{key}")
    public ResponseEntity<Void> updateValue(@PathVariable String key, @RequestBody Object value)
    {
        System.out.println("put:key:" + key);
        if (redisTemplate.opsForValue().get(key) != null)
        {
            redisTemplate.opsForValue().set(key, value);
            return ResponseEntity.noContent().build();
        } else
        {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
        }
    }
}
4.2 测试数据设计
  1. 测试service各个controller的get,put,post,delete

  2. 测试service各个controller的get,put,post,delete

  3. 测试redisController的get,put,post,delete

4.3 测试结果分析
service的无参数GET测试:
  1. course类
  1. order类
  1. person类
  1. diary类
  1. revert类

service的带参数GET测试:
  1. course类
  1. revert类

  2. order类

  3. diary类

  4. person类

service的PUT测试:
  1. course类

    修改前:

    修改后:

  2. person类

    修改前:

    修改后:

  3. diary类

    修改前:

    修改后:

  4. order类

    修改前:

    修改后:

  5. revert类

    修改前:

    修改后:

service的POST测试:
  1. course类

    错误测试:

    正确测试:

  2. person类

    错误测试:

    正确测试:

  3. diary类

    错误测试:

    正确测试:

  4. order类

    错误测试:

    正确测试:

  5. revert类

    错误测试:

    正确测试:

service的DELETE测试:
  1. course类

  2. person类

  3. diary类

    因为外键约束所以无法删除

  4. order类

  5. revert类

server的GET测试
server的PUT测试

更新前:

更新后:

server的POST测试
server的DELETE测试

删除成功

Redis的POST无时间测试

测试结果如下:

Redis的POST时间测试

加入了10秒的时间限制

post请求完毕后,进行get获取数据,可以看到testKey3出现了。

10秒后,可以看到testKey3又消失了。

Redis的GET测试
Redis的PUT测试

可以看到结果,已经更改了testKey2的键值:

Redis的DELETE测试

可以看到结果中testKey已经被删除:

五、实验小结

  1. 实验中遇到的问题及解决过程
  2. 实验中产生的错误及原因分析
  3. 实验体会和收获。
  • 23
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值