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

2020-11-11  本文已影响0人  do_young

请求报文封装

请求报文问题描述

框架基于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());
上一篇 下一篇

猜你喜欢

热点阅读