23. 关于响应结果
目前,当成功的添加相册后,服务器端响应的结果是:
添加相册成功!
如果相册名称已经被占用,服务器端响应的结果是:
添加相册失败,相册名称已经被占用!
以上的响应结果是不合适的,因为客户端不便于通过以上结果判断本次请求是否被成功的处理了,或是处理结果是失败。
如果服务器端改为使用数字作为响应结果,与客户端协商不同的数字所表示的意义,例如使用1
表示成功,使用0
表示失败,这种做法更利于客户端判断操作成功与否,但是,却需要客户端自行组织后续的文本,以在界面上显示相关提示,而客户端自行组织文本也是不适合的,特别是操作失败时,仍应该是“谁抛出,谁描述”,客户端不一定能准确的、统一的组织这些文本,所以,仍应该是由服务器端响应操作失败的描述文本!
所以,服务器端响应的结果中应该既包含数字这类标志着成功与失败的数据,还应该包含描述文本!
由于服务器端响应的结果中包含多个部分(目前是2个部分:数字标志、描述文本),应该将这多个部分使用JSON格式组织起来,则客户端收到后,可以从中取出任何所需的部分的数据:
{
"state": "1",
"message": "添加相册成功!""
}
在Spring MVC框架中,当需要向客户端响应JSON格式的数据时,需要:
-
处理请求的方法必须是响应正文的
- 在方法上添加
@ResponseBody
/ 在控制器类上添加@ResponseBody
/ 在控制器类上添加@RestController
- 在方法上添加
-
开启注解驱动
- 如果是使用XML配置的Spring MVC项目,需要在XML配置文件中添加
<annotation-driven/>
- 如果是使用注解配置的Spring MVC项目,需要在配置类上添加
@EnableWebMvc
- 如果是Spring Boot项目,不需要添加任何配置
- 如果是使用XML配置的Spring MVC项目,需要在XML配置文件中添加
-
添加
jackson-databind
依赖项- 在
spring-boot-starter-web
依赖项中包含此依赖项:
- 在
- 使用自定义的数据类型作为处理请求的方法的返回值类型
则在项目的根包下创建web.JsonResult
类(类名是完全自定义的),并在类中声明需要响应到客户端的数据属性,也可以理解为声明期望响应的JSON数据中的属性:
@Data
public class JsonResult implements Serializable {
private Integer state;
private String message;
}
然后,将处理请求的方法的返回值类型改为JsonResult
,并调整内部实现,处理完请求后返回此类型的对象:
@PostMapping("/add-new")
public JsonResult addNew(AlbumAddNewDTO albumAddNewDTO) {
try {
albumService.addNew(albumAddNewDTO);
JsonResult jsonResult = new JsonResult();
jsonResult.setState(1);
jsonResult.setMessage("添加相册成功!");
return jsonResult;
} catch (ServiceException e) {
JsonResult jsonResult = new JsonResult();
jsonResult.setState(0);
jsonResult.setMessage(e.getMessage());
return jsonResult;
}
}
完成后,重启项目,再次通过API文档调试访问,当添加相册成功时,响应结果为:
{
"state": 1,
"message": "添加相册成功!"
}
当相册名称已经被占用,导致添加失败时,响应结果为:
{
"state": 0,
"message": "添加相册失败,相册名称已经被占用!"
}
24. 使用静态方法创建JsonResult对象
在处理响应时,每次都需要创建对象、为属性赋值、返回对象,使用了较多语句实现此效果,在语法上过于繁琐,应该简化此类代码!
可以在JsonResult
类中添加全参数构造方法(在类上添加@AllArgsConstructor
注解,出于规范性,也添加@NoArgsConstructor
),以简化相关代码,例如:
@Data
@NoArgsConstructor
@AllArgsConstructor
public class JsonResult implements Serializable {
private Integer state;
private String message;
}
则处理请求的响应代码可以简化:
@PostMapping("/add-new")
public JsonResult addNew(AlbumAddNewDTO albumAddNewDTO) {
try {
albumService.addNew(albumAddNewDTO);
return new JsonResult(1, "添加相册成功!");
} catch (ServiceException e) {
return new JsonResult(0, e.