restful 风格如何使用 get 方式传递复杂参数

我没有对象是因为不想找吗?你不上清华北大是因为不想上吗?

后端代码放在https://gitee.com/siumu/springboot-xiumu.git
前端代码放在https://gitee.com/siumu/xiumu-admin-ui.git

问题

restful 规范中 GET 请求用来查询数据,但是它又不能在请求体里传递参数,如果把请求参数放在请求体里,大概率会直接被忽略掉,那么如何用 GET 请求传递复杂的参数呢?

举个例子

例如,分页请求规定的请求参数是这样的。

{
  "condition": {}, // 查询条件
  "size": 0,       // 每页条数
  "current": 0,    // 当前页数
}

如果我要分页查询第1页,10条,性别为男的用户,那么传递的参数就是这个样子:

{
  "condition": {
    gender: '男'
  }, 
  "size": 10,       // 每页条数
  "current": 1,    // 当前页数
}

这样的参数如果使用 GET 请求传递给后端,后端又该如何接收呢?或者更加复杂的对象结构又该如何传参呢?

解决办法

此时就需要前后端共同规定规范了。

  • 前端: 将参数转成 json 格式,再通过 Base64 编码之后拼在 GET 请求的 ? 后面
  • 后端: 自定义参数解析器, Base64 解码之后,再通过 json 工具将参数反序列化为对象

前端倒是很好解决,我们引入 js-base64 然后引入它的 Base64 对象

import { Base64 } from 'js-base64
// 将参数序列化成 json,再经过 Base64 编码之后放在 url 上传输
url = url + '?' + Base64.encode(JSON.stringify(params))

后端就需要我们自己自定义参数解析器了。这个也是非常简单。

  1. 首先我们模仿 @RequestBody 注解,自定义一个 @RequestJson 注解
/**
 * get 请求参数使用该注解就会使用自定义的参数解析器来解析复杂的参数
 */
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestJson {
}
  1. 自定义一个参数解析器。
/**
 * 自定义参数解析器,请求参数使用该注解 {@link RequestJson} 就会使用以下解析方式。
 * 说明:前端将参数序列化成 json,再经过 Base64 编码之后放在 url 上传输。
 * 后端 Base64 解码之后,再通过 json 工具将参数反序列化为对象。
 * 例如:http://localhost:8080/user/page?eyJjdXJyZW50IjoxLCJzaXplIjoxMCwidG90YWwiaG9uZSI6IiJ9fQ==
 */
@Slf4j
public class HandlerRequestJsonArgumentResolver implements HandlerMethodArgumentResolver {

    /**
     * 该方法判断是否要使用该参数解析器。这里我们就判断 有没有使用 @RequestJson 注解来判断是否使用该解析器
     * 如果返回 true 就运行 resolveArgument 方法来解析参数
     * 如果返回 false 使用其他参数解析器来解析参数,springframework 有很多参数解析器
     */
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(RequestJson.class);
    }

    /**
     * 该方法真正用来解析参数。
     * 先使用 Hutool 的 Base64 工具将 json 字符串解析出来
     * 再使用 Hutool 的 JSONUtil 工具将 json 转成 Bean 对象
     */
    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
        try {
            String json = Base64.decodeStr(request.getQueryString());
            return JSONUtil.toBean(json, parameter.getGenericParameterType(),false);
        } catch (Exception e) {
            log.error("请求参数解析失败,请检查!" + e.getMessage());
            throw new XiuMuException(SysException.SERVE_FAIL);
        }
    }
}
  1. 将该参数解析器注册一下

@Configuration
public class WebConfig implements WebMvcConfigurer {
    /**
     * 注册自定义参数解析器
     */
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(new HandlerRequestJsonArgumentResolver());
    }
}

使用方式

像使用 @RequestBody 一样使用 @RequestJson 即可

    /**
     * 分页查询
     * 可传递查询参数,按照某些字段分页查询
     *
     * @param pageQuery 分页条件,查询参数
     * @return
     */
    @GetMapping("/user/page")
    public ResultJSON page( @RequestJson PageQuery pageQuery) {
        return ResultJSON.success(userService.listPage(pageQuery));
    }

后端代码放在https://gitee.com/siumu/springboot-xiumu.git
前端代码放在https://gitee.com/siumu/xiumu-admin-ui.git

  • 6
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SOAP(Simple Object Access Protocol)和RESTful(Representational State Transfer)是两种不同的网络服务架构。 SOAP是一种基于XML的远程调用协议,它使用XML格式来进行消息传递,并且通常使用HTTP或SMTP等协议来传输这些消息。SOAP支持复杂的消息格式和功能,包括安全性、事务处理、可靠性等。SOAP使用WSDL(Web Services Description Language)来描述服务和消息的结构。 而RESTful是一种基于HTTP的架构风格,它将网络资源抽象为一组可访问的URI,并通过HTTP方法(如GET、POST、PUT、DELETE)来对资源进行操作。RESTful架构通常使用JSON或者XML来传输数据,但没有像SOAP那样复杂的消息格式和功能。 要将SOAP转换为RESTful,你需要重新设计和实现你的服务接口。首先,你需要将SOAP消息中的操作和参数转换为相应的RESTful资源和URI。然后,你可以使用RESTful风格的HTTP方法来替代SOAP中的操作,例如使用GET方法获取资源,使用POST方法创建资源,使用PUT方法更新资源,使用DELETE方法删除资源。最后,你可以使用JSON或者XML来传输数据。 要将RESTful转换为SOAP,你需要创建一个SOAP服务端,并且为每个资源和操作定义相应的Web服务。你需要将RESTful中的资源和URI转换为SOAP中的消息和操作,并且使用WSDL来描述这些服务。然后,你可以使用SOAP的XML格式来传输数据。 需要注意的是,SOAP和RESTful是两种不同的架构风格,转换过程中可能会涉及到一些设计和实现上的调整。此外,SOAP和RESTful在功能和性能上也有一些差异,你需要根据实际需求选择适合的架构。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值