问题
本日在用前端 post 请求后端时发现,由于是以 Json对象的形式传输的,后端用两个字符串形参无法获取到对应的参数值
前端代码如下:
- axios.post('http://localhost:8083/test/postParams',{a: '1', b:'2'} ,{
- 'Content-Type': 'application/json'
- }).then(response => {
- console.log(response.data);
- })
- .catch(error => {
- console.error('There was an error!', error);
- });
复制代码 后端代码如下:
- @RequestMapping("/test")
- @RestController
- @Slf4j
- public class TestController {
- @PostMapping("/postParams")
- public void postParams(String a, String b) {
- log.info(String.valueOf(a));
- log.info(b);
- }
- }
复制代码
解决
在网上学习了一下,究其原因是Spring Boot 无法直接将 JSON 字符串转换为一个 String 变量, Spring Boot 必要通过相应的机制,将 JSON 字符串剖析成可用的 Java 对象或 Map,在学习了某位前辈的文章后,通过自定义注解的方式解决了问题:
总的思路就是,getRequestBody()将请求的json对象字符串先缓存到cache中,然后将该字符串剖析成Json对象,在根据对应的方法形参的名字,将值注入进去。
自定义注解类
- /**
- * @author yamu
- * @version 1.0
- * @description: 接收前端传的 包装类数据 或 String 自定义注解
- * @date 2025/1/13 11:05
- */
- @Target(ElementType.PARAMETER)
- @Retention(RetentionPolicy.RUNTIME)
- @Documented
- public @interface RequestJson {
- //参数值(对应的键名)
- String value() default "";
- }
复制代码 定义@RequestJson的方法形参剖析器
- /**
- * @author yamu
- * @version 1.0
- * @description: 自定义注解 RequestJson 方法形参解析器
- * @date 2025/1/13 11:07
- */
- @Component
- @Slf4j
- public class RequestJsonMethodArgumentResolver implements HandlerMethodArgumentResolver {
- public static String cache = "";//缓存请求体
- @Override
- public boolean supportsParameter(MethodParameter parameter) {
- return parameter.hasParameterAnnotation(RequestJson.class);
- }
- /**
- * @description String 参数注入
- * @param: parameter
- * @param: mavContainer
- * @param: webRequest
- * @param: binderFactory
- * @returns Object
- * @author yamu
- * @date 2025/1/20 14:33
- */
- @Override
- public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
- RequestJson requestJson = parameter.getParameterAnnotation(RequestJson.class);
- HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
- //未指定映射的键时,默认值为形参名
- String value = requestJson.value();
- if (value.isEmpty()) {
- value = parameter.getParameterName();
- }
- JSONObject jsonObject = getRequestBody(request);
- //遍历完最后一个参数,则清理缓存
- if (parameter.getMethod().getParameterCount() - 1 <= parameter.getParameterIndex()) {
- cache = "";
- }
- //请求的参数为空,直接返回null
- if (jsonObject == null) {
- return null;
- }
- return jsonObject.get(value);
- }
- /**
- * 获取参数列表
- * @param request
- * @return
- */
- private JSONObject getRequestBody(HttpServletRequest request) {
- //cache不为空
- if (!cache.isEmpty()) {
- return JSONObject.parseObject(cache);
- }
- //字符串拼接成Json字符串
- StringBuilder sb = new StringBuilder();
- try {
- BufferedReader reader = request.getReader();
- char[] buf = new char[1024];
- int rd;
- while ((rd = reader.read(buf)) != -1) {
- sb.append(buf, 0, rd);
- }
- } catch (IOException ex) {
- log.error(ex.getMessage());
- }
- cache = sb.toString();
- return JSONObject.parseObject(sb.toString());
- }
- }
复制代码 在WebConfig里注册剖析器
- @Configuration
- @Slf4j
- public class WebConfig extends WebMvcConfigurationSupport {
- @Autowired
- private RequestJsonMethodArgumentResolver requestJsonMethodArgumentResolver;
- /**
- * @description 配置方法解析器
- * @param: argumentResolvers
- * @returns void
- * @author yamu
- * @date 2025/1/23 16:00
- */
- @Override
- public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
- argumentResolvers.add(requestJsonMethodArgumentResolver);
- }
- }
复制代码 在方法形参上加上注解
- @RequestMapping("/test")
- @RestController
- @Slf4j
- public class TestController {
- @PostMapping("/postParams")
- public void postParams(@RequestJson String a, @RequestJson String b) {
- log.info(a);
- log.info(b);
- }
- }
复制代码
上述方式存在几个问题:
- 由于要缓存请求的 Json字符串,所以在每次请求完之后要清除cache,上述方法是在方法形参的最后一个并且加了@RequestJson注解的参数才可以清理
- 由于必要对每个参数举行赋值,所以必要对每个要注入的参数都要加上@RequestJson注解
- 处置惩罚包装类或字符串类时,形参类型必要强同等(不能用Stringl类型接收一个Integer的参数值),同时也无法处置惩罚复杂的对象类型
后续在渐渐的深入学习后我会优化上述方式。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |