一、前情提要
上一次我们完成了角色权限的服务开发,这里我们先不进行Controller层的开发,先谈一下一写开发前的准备工作和相关介绍。
二、Q&A
注意:在这里我会在这里介绍如何生成接口文档以及相关注解的使用,一些自己编写的工具类使用方法,常见问题的答疑,下面的实践操作环节中就不会再提及。
1.为什么需要Controller层?
答: 在我们实现完Service层后,前端是不能调用这些服务的,因为没有相应的接口进行调用。所以我们需要写一些接口,当前端调用接口方法的时候,执行相关的Service服务(业务逻辑),最后以JSON的形式返回相应的数据,也就是说Controller层是业务逻辑实现的一层。
2.如何才能生成JSON格式的数据?
答: 你只需要做到这几部:
- 在controller类的开头添加注解
@RestController
- 返回一个自定义的JSON类
@RestController
这个注解是@ResponseBody
+@Controller
功能合在一起,是SpringBoot独有的注解。而自定义JSON类你可以查看前面的文章《【机房报修管理系统】后端篇(七) 配置自定义JSON类及解决JSON的值空时不出现Null》。
3.如何做到返回JSON的时候屏蔽一些不需要的字段?
答: 在返回JSON信息的时候,有一些字段是我们不像返回的,例如管理员类中,我们有管理员密码这个字段,但是我们不能够将密码这个字段返回给前端,那样就会暴露我们的管理员密码。如果想解决这个问题有两种方法,一个就是:
- 在数据库取出所有字段的数据
- 通过对象把不想暴露的字段设置为空
- 返回给JsonResult(自定义JSON类)
示例代码:
//在数据库取出所有字段的数据
List<Administrator> list = adminService.searchAllAdministrator();
//遍历列表
for(Administrator admin : list){
//通过对象把不想暴露的字段设置为空
admin.password = ""
}
//返回给JsonResult(自定义JSON类)
return JsonResult.ok(list);
这样做就意味着我们需要手动地去对每个对象设置屏蔽的关键字为NULL,做起来比较麻烦,因为我们之后还有许多的接口都需要屏蔽一些关键字,手动费时费力,所以我们得做一个“轮子”,也就是工具类,每次遇到需要屏蔽相关字段的时候调用这个工具类即可,这就是第二种方法:POJO类转为VO类。
4.什么是VO类,它和实体类(POJO)有什么不一样?
答: 在制作这个工具类之前我们需要了解什么是VO类。VO类通常用于业务层之间的数据传递,就是负责给前端看的,在上面我们曾经提到过有一些字段是不能够展示的,如果改动实体类,那样实体类和数据库的字段不一致,导致不能正常对数据库进行查询,所以我们需要创建一个VO类,VO类的要求:
- VO类只能等于或少于实体类的字段
- VO类和实体类的字段名称必须相同
- VO类需要像POJO类那样成员变量需要为私有,提供Getter/Setter方法。
5.实体类(POJO)如何转变为VO类?
答: 当我们做好了VO类,过滤了不需要的字段,现在我们需要制作一个转换器,将实体类转为VO类,这里就需要了解一些反射的知识了。
工具类需要有两个方法:
- 实体类列表转为VO类列表:
entityList2VOList
- 实体类转为VO类:
entity2VO
实现过程:
- 遍历实体类List,获得实体类对象
- vo对象初始化
- 使用Spring自带的
BeanUtils.copyProperties()
将实体类的属性复制到VO类中 - 添加到VOList中即可
相关代码:
在com.repairsystem.utils
创建工具类Entity2VO
注意BeanUtils
是属于org.springframework.beans.BeanUtils
的,不是Apache那个BeanUtils
package com.repairsystem.utils;
import org.springframework.beans.BeanUtils;
import java.util.LinkedList;
import java.util.List;
/**
* @author CheungChingYin
* @date 2018/11/7
* @time 10:17
*/
public class Entity2VO {
/**
* 实体类列表转换为 VO类列表
* @param entityList
* @param voClass
* @return
*/
public static List entityList2VOList(List<? extends Object> entityList, Class voClass){
List voList = new LinkedList();
Object voObj = null;
for(Object entityObj:entityList){
try {
voObj = voClass.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
BeanUtils.copyProperties(entityObj,voObj);
voList.add(voObj);
}
return voList;
}
/**
* 实体类转换为 VO类
* @param entity
* @param voClass
* @param <T>
* @return
*/
public static <T> T entity2VO(Object entity,Class<T> voClass){
T vo = null;
try {
vo = voClass.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
BeanUtils.copyProperties(entity,vo);
return vo;
}
}
转换的时候您只需要这样调用:
//向数据库查询信息
Administrator admin = adminService.searchAdministratorByPhoneNum(adminPhoneNum);
List<Administrator> list = adminService.searchAllAdministrator();
//使用工具类进行转换(实体类转为VO类)
AdministratorVO adminVO = Entity2VO.entity2VO(admin,AdministratorVO.class);
//实体列表转为VO列表
List<AdministratorVO> listVO = Entity2VO.entityList2VOList(list, AdministratorVO.class);
//返回给JsonResult(自定义JSON类)
return JsonResult.ok(resultMap);
6.Swagger2中如何显示接口信息和参数?
答: 需要实现显示接口地址和功能信息,接口分类其实很简单,只需要在Controller类中写好以下注解即可:
- 接口分类:
@Api
- 接口功能信息:
@ApiOperation
- 接口参数(拥有多个参数时使用):
@ApiImplicitParams
- 接口参数(单个参数):
@ApiImplicitParam
- POST方法请求:
@PostMapping
- Get方法请求:
@GetMapping
在类的开头使用@Api
进行接口分类,@RequestMapping("/admin")
如果在类上面声明,就意味着下面方法需要通过访问/admin
才能请求类下面的方法,关于@RequestMapping
的使用方法可以查看我博客以往的文章:
《【SpringMVC】4. 获取Http的请求信息或请求头》。
@PostMapping
和@GetMapping
的使用方法很简单,您只需要按照接口的请求方法在接口方法上面填上相应的注解即可,Get请求使用@GetMapping
,POST请求使用@PostMapping
,除此之外还有PUT请求和DELETE请求等等的RESTful相关的请求注解,在此不在介绍,请自行查找,一旦指定了注解,在Swagger2文档中就会将接口显示为相应的请求方法,如下图
@ApiOperation
注解的使用方法很简单,只需要在接口方法上添加注解,写上这个接口实现了什么功能即可。
@ApiImplicitParam
和@ApiImplicitParams
注解是用于对接口记录需要什么参数,当只有一个参数的时候可以直接使用@ApiImplicitParam
,而拥有兑个参数的时候需要使用@ApiImplicitParams
注解包裹全部的@ApiImplicitParam
注解即可
到这里,Controller层开发——相关介绍Q&A已经结束了。如果您对次篇文章有疑问,可以在文章下方留言,谢谢您的阅读。如对【机房报修管理系统】系列文章有兴趣,可以关注或收藏我的文章,您的支持是我最大的动力,我会尽快推出下一期内容,敬请期待。