软件工程应用与实践(15)——请求与响应
Posted 叶卡捷琳堡
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了软件工程应用与实践(15)——请求与响应相关的知识,希望对你有一定的参考价值。
2021SC@SDUSC
文章目录
一、概述
在老年健康知识图谱系统中,后端与前端的交互是很重要的,在前端向后端发送请求的过程中,后端需要向前端返回响应的数据,而本篇博客将重点针对本项目中关于请求与响应的部分做相关分析。
经过小组讨论,决定由我分析关于响应和请求的部分,关于这块内容,在项目中的源码主要涉及一下几个部分
在前端中,有封装好的,发送请求的js文件,这些js文件中封装了一个个请求的函数,在前端vue页面中可以调用。
而在后端,则对请求包装了相应的相应对象,这些相应对象发送到前端之后,前端会根据不同的响应对象给出不同的处理。而在后端处理的过程中,可能会遇到一些异常情况,而老年健康知识图谱系统中,又对异常情况进行了相应的处理。
在下面的源码分析中,我会对这些部分做进一步分析。
二、源码分析
2.1 响应
为了更好地理解请求与响应的交互关系,我决定先阅读响应部分的源码,之后再理解请求部分的源码。
首先我们可以看到,在项目中,定义了三个文件夹,这三个文件夹分别描述了
- 后端处理前端请求时可能遇到的异常
- 后端处理异常
- 返回给前端的具体的响应信息
1.响应信息
我们首先阅读响应信息部分的源码
首先我们可以看到,在对应的文件夹中,有一个BaseResponse类
在这个类中,描述了如下信息
- 两个属性,相应的状态码和具体的信息
- 有参构造,无参构造及相应的get和set方法
public class BaseResponse
private int statusCode = 200;
private String message;
public BaseResponse(int status, String message)
this.statusCode = status;
this.message = message;
public BaseResponse()
public String getMessage()
return message;
public void setMessage(String message)
this.message = message;
public int getStatusCode()
return statusCode;
public void setStatusCode(int statusCode)
this.statusCode = statusCode;
可以知道,这个类的主要作用是,用于描述正常执行时的响应状态。
接下来我们看到下一个类TableResultResponse,从类名上可以知道,这个类主要用于返回与表格相关的相应数据
- 使用一个TableData对象存储表格数据
- 在内部类TableData中,一个List类型的变量存储了表格每一行的数据,而另一个total变量则存储了表格的行数
public class TableResultResponse<T> extends BaseResponse
TableData<T> data;
public TableResultResponse(long total, List<T> rows)
this.data = new TableData<T>(total, rows);
public TableResultResponse()
this.data = new TableData<T>();
TableResultResponse<T> total(int total)
this.data.setTotal(total);
return this;
TableResultResponse<T> total(List<T> rows)
this.data.setRows(rows);
return this;
public TableData<T> getData()
return data;
public void setData(TableData<T> data)
this.data = data;
class TableData<T>
long total;
List<T> rows;
public TableData(long total, List<T> rows)
this.total = total;
this.rows = rows;
public TableData()
public long getTotal()
return total;
public void setTotal(long total)
this.total = total;
public List<T> getRows()
return rows;
public void setRows(List<T> rows)
this.rows = rows;
本项目通过将表格数据的返回封装成一个对象,并在该类中使用了范型的技术,从而提高了利用效率,这是值得借鉴的。
接下来我们看到下一个类ObjectRestResponse,这个类主要用于返回对象类型的数据
- 使用一个范型变量data存储对象的数据
- 建立了相关的构造方法,get和set方法用于赋值
public class ObjectRestResponse<T> extends BaseResponse
T data;
public ObjectRestResponse data(T data)
this.setData(data);
return this;
public T getData()
return data;
public ObjectRestResponse setData(T data)
this.data = data;
return this;
本类与上面的类作用相似,只不过上面的类用于返回表格数据,而本类用于返回对象类型的数据
此外,这两个类都继承了上面的BaseResponse类,所以我们可以知道,对与BaseResponse类来说,他存在三种形式,第一种是原生的形式,第二种是返回表格数据的形式,第三种是返回对象类型数据的形式
接下来我们关注返回错误信息的类
关于错误信息的类,本项目中主要有两个
第一个是TokenForbiddenResponse类,同样继承了BaseResponse类,在这个类中,直接调用父类的构造方法,传入对应的状态码和消息。
public class TokenForbiddenResponse extends BaseResponse
public TokenForbiddenResponse(String message)
super(RestCodeConstants.TOKEN_FORBIDDEN_CODE, message);
第二个类与上面的类类似,同样返回了一个错误码
public class TokenErrorResponse extends BaseResponse
public TokenErrorResponse(String message)
super(RestCodeConstants.TOKEN_ERROR_CODE, message);
而错误码在项目中同样有定义,定义为类中的静态变量,并且设置为常量,不可修改
public class RestCodeConstants
public static final int TOKEN_ERROR_CODE = 40101;
public static final int TOKEN_FORBIDDEN_CODE = 40301;
2.异常类定义及处理
在本项目中,对后端可能发生的异常进行了相关的处理,经过小组讨论,将由我的另一个队友对异常处理部分做详尽的描述,这里我只对异常处理做简单的介绍。
本项目的异常处理与之前的上面的响应处理类似,都先定义了一个Basexxx作为基类,之后对该基类进行拓展,最终完善整个功能
在异常处理这一部分,本项目同样使用了一个基类,即BaseException,这个类首先继承了RuntimeException,并定义了相关的状态码,及set和get方法
public class BaseException extends RuntimeException
private int status = 200;
public int getStatus()
return status;
public void setStatus(int status)
this.status = status;
public BaseException()
public BaseException(String message,int status)
super(message);
this.status = status;
public BaseException(String message)
super(message);
public BaseException(String message, Throwable cause)
super(message, cause);
public BaseException(Throwable cause)
super(cause);
public BaseException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace)
super(message, cause, enableSuppression, writableStackTrace);
而之后的其他类,也利用上面提到的,同样的方法继承了该Base异常类,从而达到对各个异常进行处理的作用
以下的代码就是具体的例子
public class UserInvalidException extends BaseException
public UserInvalidException(String message)
super(message, CommonConstants.EX_USER_PASS_INVALID_CODE);
public class UserTokenException extends BaseException
public UserTokenException(String message)
super(message, CommonConstants.EX_USER_INVALID_CODE);
关于本项目的异常处理,主要由下面的这个类完成,使用@ExceptionHandler注解,在括号中传入对应的异常类,用于指定处理对应异常类的方法。针对不同的异常,进行不同的处理。
@ControllerAdvice("com.sdu.nurse")
@ResponseBody
public class GlobalExceptionHandler
private Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
@ExceptionHandler(ClientTokenException.class)
public BaseResponse clientTokenExceptionHandler(HttpServletResponse response, ClientTokenException ex)
response.setStatus(403);
logger.error(ex.getMessage(),ex);
return new BaseResponse(ex.getStatus(), ex.getMessage());
@ExceptionHandler(UserTokenException.class)
public BaseResponse userTokenExceptionHandler(HttpServletResponse response, UserTokenException ex)
response.setStatus(401);
logger.error(ex.getMessage(),ex);
return new BaseResponse(ex.getStatus(), ex.getMessage());
@ExceptionHandler(UserInvalidException.class)
public BaseResponse userInvalidExceptionHandler(HttpServletResponse response, UserInvalidException ex)
response.setStatus(200);
logger.error(ex.getMessage(),ex);
return new BaseResponse(ex.getStatus(), ex.getMessage());
@ExceptionHandler(BaseException.class)
public BaseResponse baseExceptionHandler(HttpServletResponse response, BaseException ex)
logger.error(ex.getMessage(),ex);
response.setStatus(500);
return new BaseResponse(ex.getStatus(), ex.getMessage());
@ExceptionHandler(Exception.class)
public BaseResponse otherExceptionHandler(HttpServletResponse response, Exception ex)
response.setStatus(500);
logger.error(ex.getMessage(),ex);
return new BaseResponse(CommonConstants.EX_OTHER_CODE, ex.getMessage());
在本类中,还注入了日志对象,用这个日志对象输出对应的日志。
2.2 请求
在看完了响应的部分,接下来我们关注项目中关于“请求”的部分。
在本项目中,关于请求的部分比较简单,在之前的博客中我也略有提及,在这里详细说明一下
本项目中的请求封装在api包下的js文件中,以用户请求为例,代码如下,首先我们可以看到,js的开始部分,引入了axios的fetch,下面的四种请求,返回的都是一个fetch对象。
以get请求为例,传入一个query对象,直接调用fetch,指定对应对应的url,指定method,指定params(get请求所带的参数)。
而在post请求中,将要传递给后端接口的参数写在data中。
import fetch from '@/plugin/axios'
export function page (query)
return fetch(
url: '/api/nurse/user/page',
method: 'get',
params: query
)
export function addObj (obj)
return fetch(
url: '/api/nurse/user',
method: 'post',
data: obj
)
export function getObj (id)
return fetch(
url: '/api/nurse/user/' + id,
method: 'get'
)
export function delObj (id)
return fetch(
url: '/api/nurse/user/' + id,
method: 'delete'
)
export function putObj (id, obj)
return fetch(
url: '/api/nurse/user/' + id,
method: 'put',
data: obj
)
在具体的页面中,该项目中调用了上面封装好的请求代码,在按下确认按钮后,执行then方法,then方法中调用了delObj方法,而该方法封装在js代码中。
handleDelete (row)
this.$confirm('此操作将永久删除, 是否继续?', '提示',
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
)
.then(() =>
delObj(row.id)
.then(() =>
this.$notify(
title: '成功',
message: '删除成功',
type: 'success',
duration: 2000
)
const index = this.list.indexOf(row)
this.list.splice(index, 1)
)
)
三、总结
在本次阅读源码的过程中,我主要分析了老年健康知识图谱系统中关于请求和响应的内容。在本次阅读源码的过程中,我体会到了该项目在请求封装和异常类封装的巧妙之处,在这个过程中也感谢老师和小组成员对我的帮助,本学期的软件工程应用与实践的源码分析就分析到这里,之后还有一篇博客用于总结。
以上是关于软件工程应用与实践(15)——请求与响应的主要内容,如果未能解决你的问题,请参考以下文章