欢迎来到1890的博客

你站在桥上看风景,看风景人在楼上看你。明月装饰了你的窗子,你装饰了别人的梦。

Springboot中前后端数据交互问题

Springboot中前后端数据交互问题

技术概述

在使用Springboot进行前后端分离时,测试前后端数据的交互情况、交互过程出现的明确各种问题及其解决方法。学习该技术原因是为了应对各种情况下前后端的数据交互,避免因为Content-Type发送信息至服务器时内容编码类型不一致造成问题。技术难点是不协调一致容易出现接口数据交互出错,比较细节容易踩坑。

前后端数据交互问题和容易踩坑的地


前端请求:
Content-Type:application/x-www-form-urlencoded
@RequestParam或者无注释后端响应:

//添加一个用户
@PostMapping(value = "/user/create")
    public HashMap<String, Object> user_Create(@RequestParam("userName") String userName,@RequestParam("sex") Integer sex,
                                               @RequestParam("age") Integer age,@RequestParam("phone") String phone,
                                               @RequestParam("address") String address,@RequestParam("password") String password,
                                               @RequestParam("root") Integer root){
        return userService.userCreate(userName,sex,age,phone,address,password,root);
    }

@RequestBody后端无法响应:

/*修改个人信息
    * 成功返回true
    * */
    @ResponseBody
    @PostMapping(value = "/user/update")
    public HashMap<String,Object> update(@RequestBody User user){
        return userService.updateCheck(user);
    }

结论:当前端以application/x-www-form-urlencoded格式上传数据时,后台可以使用@RequestParam或者不使用任何注解来获取参数。 后台不可以使用@RquestBody来获取参数,使用的话会报错误。


前端请求:
Content-Type:application/json
@RequestParam或者无注释后端无法响应:

//添加一个用户
@PostMapping(value = "/user/create")
    public HashMap<String, Object> user_Create(@RequestParam("userName") String userName,@RequestParam("sex") Integer sex,
                                               @RequestParam("age") Integer age,@RequestParam("phone") String phone,
                                               @RequestParam("address") String address,@RequestParam("password") String password,
                                               @RequestParam("root") Integer root){
        return userService.userCreate(userName,sex,age,phone,address,password,root);
    }

参数添加@RequestBody注解无法响应:

/*修改个人信息
    * 成功返回true
    * */
    @ResponseBody
    @PostMapping(value = "/user/update")
    public HashMap<String,Object> update(@RequestBody String userName
                                        @RequestBody String address){
        return userService.updateCheck(userName,address);
    }

参数用@RequestBody注解,是一个Java bean,响应:

/*修改个人信息
    * 成功返回true
    * */
    @ResponseBody
    @PostMapping(value = "/user/update")
    public HashMap<String,Object> update(@RequestBody User user){//区别
        return userService.updateCheck(user);
    }

参数用@RequestBody注解,是一个Map,响应:

/*修改个人信息
    * 成功返回true
    * */
    @ResponseBody
    @PostMapping(value = "/user/update")
    public HashMap<String,Object> update(@RequestBody Map<String,Object> map){//区别
        return userService.updateCheck(map);
    }

结论:当前端使用application/json来传递数据的时候,后端只能使用 @RequestBody 以及 Java bean或者 map 的方式来接收数据。

输出接口日志来发现问题

//引入日志配置
    private static final Log LOG = LogFactory.getLog(LogAspect.class);

    /**
     * 定义一个切入点 只拦截controller.
     * 解释下:
     * ~ 第一个 * 代表任意修饰符及任意返回值.
     * ~ 第二个 * 定义在web包或者子包
     * ~ 第三个 * 任意方法
     * ~ .. 匹配任意数量的参数.
     */
    @Pointcut("execution(* com.manager.system.controller..*.*(..))")
    public void logPointcut() {
    }

    //around(和上面的方法名一样)
    @org.aspectj.lang.annotation.Around("logPointcut()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        LOG.info("=====================================Method  start====================================");
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        long start = System.currentTimeMillis();
        try {
            Object result = joinPoint.proceed();
            long end = System.currentTimeMillis();
            LOG.info("请求地址:" + request.getRequestURI());
            LOG.info("用户IP:" + request.getRemoteAddr());
            LOG.info("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
            LOG.info("参数: " + Arrays.toString(joinPoint.getArgs()));
            LOG.info("执行时间: " + (end - start) + " ms!");
            LOG.info("=====================================Method  End====================================");
            return result;
        } catch (Throwable e) {
            long end = System.currentTimeMillis();
            LOG.info("URL:" + request.getRequestURI());
            LOG.info("IP:" + request.getRemoteAddr());
            LOG.info("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
            LOG.info("ARGS : " + Arrays.toString(joinPoint.getArgs()));
            LOG.info("执行时间: " + (end - start) + " ms!");
            LOG.info("=====================================Method  End====================================");
            throw e;
        }
    }

参考

SpringBoot和前端数据交互
SpringBoot中前后端数据交互
处理Web请求日志

posted @ 2020-06-23 21:18  1890  阅读(2429)  评论(0编辑  收藏  举报