美文网首页
后羿框架-公共子框架-报文封装

后羿框架-公共子框架-报文封装

作者: do_young | 来源:发表于2020-11-11 18:48 被阅读0次

请求报文封装

请求报文问题描述

框架基于spring-web实现的REST服务接口,接口调用时可基于HTTP的url传递调用参数,也可以通过post方法在HTTP的body中传递参数。

如果基于url传递参数,可以使用spirng-web的@PathVariable注解获取参数,如下所示:

    @DeleteMapping(value = "/users/{id}")
    public Result delete(@PathVariable String id) {

如果基于body传递参数,在后端可以基于@RequestParam来获取参数,如下所示:

    @GetMapping("/users")
    public PageResult<User> findUsers(@RequestParam Map<String, Object> params) {

如果body传递的参数为一个对象的Json数据结构,则可以使用@RequestBody直接转换为一个对象,如下所示:

    public Result saveOrUpdate(@RequestBody User sysUser) throws Exception {
        return appUserService.saveOrUpdateUser(sysUser);

以上基于不同的参数获取方式,提供了太多的注解方式,来基于不同的场景获取数据做数据类型转换。

解决思路

扩展一个注解,如:@HouyiRequest,该注解使用在方法参数上,注解有两个属性:

一个name属性可以指定参数名称,name属性默认值为参数名称。
一个type属性可以指定参数对应的数据类型,type属性默认值为参数类型。
则以上的请求就可以改为:

@DeleteMapping(value = "/users/{id}")
public Result delete(@HouyiRequest(name="id", type=String.class)String id) {

@GetMapping("/users")
public PageResult<User> findUsers(@HouyiRequest Map params) {

  public Result saveOrUpdate(@HouyiRequest User sysUser) throws Exception {

实现

在common-core中扩展一个注解@HouyiRequest
实现在common-web中实现Spring-web包中的HandlerMethodArgumentResolver接口


/**
 * Strategy interface for resolving method parameters into argument values in
 * the context of a given request.
 *
 * @author Arjen Poutsma
 * @since 3.1
 * @see HandlerMethodReturnValueHandler
 */
public interface HandlerMethodArgumentResolver {

    /**
     * Whether the given {@linkplain MethodParameter method parameter} is
     * supported by this resolver.
     * @param parameter the method parameter to check
     * @return {@code true} if this resolver supports the supplied parameter;
     * {@code false} otherwise
     */
    boolean supportsParameter(MethodParameter parameter);

    /**
     * Resolves a method parameter into an argument value from a given request.
     * A {@link ModelAndViewContainer} provides access to the model for the
     * request. A {@link WebDataBinderFactory} provides a way to create
     * a {@link WebDataBinder} instance when needed for data binding and
     * type conversion purposes.
     * @param parameter the method parameter to resolve. This parameter must
     * have previously been passed to {@link #supportsParameter} which must
     * have returned {@code true}.
     * @param mavContainer the ModelAndViewContainer for the current request
     * @param webRequest the current request
     * @param binderFactory a factory for creating {@link WebDataBinder} instances
     * @return the resolved argument value, or {@code null} if not resolvable
     * @throws Exception in case of errors with the preparation of argument values
     */
    @Nullable
    Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
            NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception;

}

扩展Spring-web的WebMvcConfigurationSupport类,添加springmvc对扩展注解的支持,如下是基于SpringBoot的示例。


@Configuration
public class ClientResourcesConfig extends WebMvcConfigurerAdapter {
 
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
//        super.addArgumentResolvers(argumentResolvers);
        argumentResolvers.add(new JsonPathArgumentResolver());
    }

返回报文封装

返回报文问题描述

框架可用于单体应用或微服务网关开发时,前端应用调用后端接口需要获取一个统一的返回报文,方便前端作结果展示及展示逻辑处理。

比如:

一个REST-API的接口查询指定用户信息。


http://ip:port/app/user/${userName}

如果正常访问会返回一个用户的Json结构的数据信息,如:


{
"accountNonExpired": true,
"accountNonLocked": true,
"attributes": {},
"authorityIds": [],
"credentialsNonExpired": true,
"enabled": true,
"id": "admin",
"password": "",
"permissions": [],
"username": ""
}

但如果该用户不存在,可以返回一个空的Json结构,如:


{
"accountNonExpired": true,
"accountNonLocked": true,
"attributes": {},
"authorityIds": [],
"credentialsNonExpired": true,
"enabled": true,
"id": "",               //user id is empty
"password": "",
"permissions": [],
"username": ""
}

或直接返回一条业务异常的消息提示:


{
"code": "999",
"error_mssage": "admin用户不存在"
}

这些返回结果都不方便前端封装展示逻辑。

解决思路

通过统一返回一个接口报文,如下所示:


{
    "resp_code": "",
    "resp_msg": "",
    "datas": ...
}

报文中有统一的状态码 "resp_code",前端可以根据状态码判断接口调用是成功还是失败,比如resp_code值不为“200”则为异常,前端只要判断状态码不为“200”,则可以将resp_msg属性中的异常信息直接做异常提醒展示。

{
    "resp_code": "401",
    "resp_msg": "用户未授权",
    "datas": ...
}

如果返回的状态码为“200”,则可以将datas中取出的约定好的数据格式进行解析并做相关的展示逻辑处理。

{
    "resp_code": "200",
    "resp_msg": "请求成功",
    "datas": [
        {
            "createTime": "",
            "enabled": true,
            "id": "",
            "mobile": "",
            "newPassword": "",
            "oldPassword": "",
            "password": "",
            "updateTime": "",
            "username": ""
        }
    ]
}

实现

在common-core包中定义扩展注解@HouyiResponse,该注解可以使用在方法的返回类型上。
在common-web包中实现spring-web包中接口HandlerMethodReturnValueHandler


/**
 * Strategy interface to handle the value returned from the invocation of a
 * handler method .
 *
 * @author Arjen Poutsma
 * @since 3.1
 * @see HandlerMethodArgumentResolver
 */
public interface HandlerMethodReturnValueHandler {

    /**
     * Whether the given {@linkplain MethodParameter method return type} is
     * supported by this handler.
     * @param returnType the method return type to check
     * @return {@code true} if this handler supports the supplied return type;
     * {@code false} otherwise
     */
    boolean supportsReturnType(MethodParameter returnType);

    /**
     * Handle the given return value by adding attributes to the model and
     * setting a view or setting the
     * {@link ModelAndViewContainer#setRequestHandled} flag to {@code true}
     * to indicate the response has been handled directly.
     * @param returnValue the value returned from the handler method
     * @param returnType the type of the return value. This type must have
     * previously been passed to {@link #supportsReturnType} which must
     * have returned {@code true}.
     * @param mavContainer the ModelAndViewContainer for the current request
     * @param webRequest the current request
     * @throws Exception if the return value handling results in an error
     */
    void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType,
            ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception;

}

扩展Spring-web的WebMvcConfigurerAdapter类,添加springmvc对扩展注解的支持,如下是基于SpringBoot的示例。


public class ApplicationConfigurer extends WebMvcConfigurerAdapter {
    @Override
    public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {
        super.addReturnValueHandlers(returnValueHandlers);
        returnValueHandlers.add(new Example());

相关文章

  • 后羿框架-公共子框架-报文封装

    请求报文封装 请求报文问题描述 框架基于spring-web实现的REST服务接口,接口调用时可基于HTTP的ur...

  • 公共子框架

    目的 该子框架主要基于技术栈及业务背景对常用的技术组件进行封装。 报文的封装规则 统一请求报文的解析。 统一返回报...

  • 后羿框架-权限子框架

    目的 该子框架主要是统一认证与授权、鉴权的实现方式。 设计分析 在传统的单体应用中是将认证与授权、鉴权放在同一个系...

  • 动手写个java快速开发框架-(3)统一网络请求和加解密

    一般的开发框架都会对网络的报文格式进行统一的设计,这样可以把一些公共的内容放在报文的公共区域,这样就可以在框架中设...

  • 后羿框架

    背景 目标 该框架主要从金融互联网级系统开发的业务背景出发,通过以下方式: 统一相关系统或服务的实现方案及技术栈 ...

  • Linux下Socket编程(五)——http容器(支持php)

    简介 理解http报文格式 socket+epoll+多线程框架 请求和响应类封装 正则表达式解析头部 请求文件读...

  • 框架封装

    Android 组件化 —— 路由设计最佳实践 业界最简单高效的路由方案 OkDeepLink被人忽视的面向对象的...

  • 图片加载框架的封装

    如何正确的使用图片加载框架? 封装!!! 别在图片需要加载时直接使用图片加载框架应该封装这个框架之后再间接使用 比...

  • 项目框架

    公共类(框架) YTTabBarController

  • 目录结构

    ThinkPHP.php:框架入口文件Common:框架公共文件Conf:框架配置文件Extend:框架扩展目录L...

网友评论

      本文标题:后羿框架-公共子框架-报文封装

      本文链接:https://www.haomeiwen.com/subject/oykybktx.html