账号密码登录
微信安全登录
微信扫描二维码登录

登录后绑定QQ、微信即可实现信息互通

手机验证码登录
找回密码返回
邮箱找回 手机找回
注册账号返回
其他登录方式
分享
  • 收藏
    X
    spring-webflux两种开发模式,获取不到使用ajax的post提交的数据?
    • 2019-03-16 00:00
    • 10
    30
    0

    遇到的问题:

    1、使用注解式:在js中使用ajax提交post数据name,在controller中使用@RequestBody无法获取到数据。
    2、使用函数式:在js中使用ajax提交post数据name,在hander中怎么使用ServerRequest获取到提交的数据name的值呢?

    相关尝试:

    在注解式中:开始我使用的是@RequestBody String name,但是获取到的值是空的。然后看到网上的有用@RequestBody final Mono<String> name,但是这种也没有获取到值。
    在函数式中:我想直接从request中拿,使用方法resolveBodyFromRequest将serverHttpRequest.getBody得到的mono数据转为String.但是仍然拿到的值是空的。

    麻烦用过webflux获取到post请求参数的大佬帮忙看看应该怎么获取?

    相关代码

    // 注解式的请求js
    $.ajax({
            type: 'POST',
            url: "/postController/find",
            data: {
                name: "aa",
            },
            dataType: "json",
            success: function (data) {
                console.log(data);
            },error:function () {
                console.log("error");
            }
        });
    
    
    // 注解式 controller
    @RestController
    @RequestMapping("/postController")
    public class PostController {
        @PostMapping(value = "/find", produces = MediaType.APPLICATION_STREAM_JSON_VALUE)
        public Mono<String> find(@RequestBody final String name) {
             // 这里一直拿不到 post过来的name   ???
            System.out.println(name);
            return Mono.justOrEmpt(name);
        }
    }
    
    
    // 函数式的请求js
    $.ajax({
            type: 'POST',
            url: "/post/find",
            data: {
                name: "aa",
            },
            dataType: "json",
            success: function (data) {
                console.log(data);
            },error:function () {
                console.log("error");
            }
        });
        
    // 函数式 router
        @Configuration
    public class PostRouter {
        @Bean
        public RouterFunction<ServerResponse> route(PostHandler handler) {
                    return RouterFunctions
                    .route(RequestPredicates.POST("/post/find")
                                    .and(RequestPredicates.accept(MediaType.TEXT_PLAIN)),
                            handler::find);
        }
    }
    
    
    // 函数式 handle
        @Component
    public class PostHandler {
    
        public Mono<ServerResponse> find(ServerRequest serverRequest){
            // 这里一直拿不到 post过来的data  ???
            String str =readRequestData((ServerHttpRequest)serverRequest);
            return ServerResponse.ok().contentType(MediaType.TEXT_PLAIN)
                    .body(BodyInserters.fromObject(str));
        }
    
    
        public  String readRequestData(ServerHttpRequest serverHttpRequest) {
            String bodyData = "";
            String method = serverHttpRequest.getMethodValue();
            if ("POST".equals(method)) {
                bodyData = resolveBodyFromRequest(serverHttpRequest);
            } else if ("GET".equals(method)) {
                bodyData = getContentByGetRequest(serverHttpRequest);
            }
            return bodyData;
        }
    
        private String getContentByGetRequest(ServerHttpRequest serverHttpRequest) {
            Map requestQueryParams = serverHttpRequest.getQueryParams().toSingleValueMap();
            StringBuffer s = new StringBuffer();
            String content = "";
            requestQueryParams.forEach((k, v) -> {
                System.out.println(k + "  v:" + v);
                s.append(k + "=" + v + "&");
            });
            if (null != s && !s.equals("")) {
                content = s.toString().substring(0, s.toString().lastIndexOf('&'));
            }
            return content;
        }
    
        /**
         * * 从Flux<DataBuffer>中获取字符串的方法
         * @return 请求体
         */
        private String resolveBodyFromRequest(ServerHttpRequest serverHttpRequest) {
            //获取请求体
            Flux<DataBuffer> body = serverHttpRequest.getBody();
            System.out.println(body);
            AtomicReference<String> bodyRef = new AtomicReference<>();
            body.subscribe(buffer -> {
                CharBuffer charBuffer = StandardCharsets.UTF_8.decode(buffer.asByteBuffer());
                DataBufferUtils.release(buffer);
                bodyRef.set(charBuffer.toString());
            });
            //获取request body
            return bodyRef.get();
        }
    }
    
    

    你期待的结果是什么?实际看到的错误信息又是什么?

    1
    打赏
    收藏
    点击回答
    您的回答被采纳后将获得:提问者悬赏的 10 元积分
        全部回答
    • 0
    • 怎能用文字帶過 普通会员 1楼

      在Spring WebFlux中,有两种主要的开发模式:Controller编程和基于Promises的编程。使用Controller编程的开发模式可以更简单地处理HTTP请求和响应,但它在处理Ajax请求时可能会遇到一些问题。基于Promises的编程模式可以帮助我们更优雅地处理异步操作,但在处理Ajax请求时可能会遇到一些问题。

      假设我们有一个Controller,它在处理一个Ajax POST请求时,将数据发送到另一个服务:

      ```java @RestController public class MyController {

      @PostMapping("/api/data")
      public void handlePost(@RequestBody MyRequest request) {
          // 在这里,我们假设我们的服务可以接收POST请求并返回数据
          // 这只是一个示例,实际的实现可能需要根据你的服务进行修改
          Data service = new Data();
          service.addData(request.getData());
      }
      

      } ```

      在这个例子中,我们使用了Java的@PostMapping注解来指定这个控制器应该处理POST请求。然后,我们使用@RequestBody注解来指定请求体的类型。

      然后,我们假设我们的服务可以接收POST请求并返回数据:

      ```java @Service public class Data {

      private List<MyRequest> data;
      
      public Data(List<MyRequest> data) {
          this.data = data;
      }
      
      public List<MyRequest> getData() {
          return data;
      }
      

      } ```

      在这个例子中,我们定义了一个名为Data的服务类,它有一个名为getData的方法,这个方法返回一个List<MyRequest>类型的列表。

      现在,如果你在前端使用Ajax发送POST请求,你需要在前端使用fetchaxios等库来发送请求,而不是在后端。这将使你的前端代码更容易地处理异步操作,但同时也可能需要使用到 Promises。

      例如:

      ```javascript async function sendPostRequest() { const response = await fetch('/api/data', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ data: 'Hello World' }) }); const data = await response.json(); console.log(data); }

      sendPostRequest(); ```

      在这个例子中,我们使用了async/await来简化异步代码,同时也使用了fetchaxios来发送请求。

      最后,如果你使用的是 Spring WebFlux,你可以使用@PreAuthorize注解来确保只有在特定的用户角色下,才能调用这个方法。但是,这种方式并不能解决Ajax请求的问题,因为Ajax请求仍然是异步的,而且需要处理X-XSS-Protection头。

    更多回答
    扫一扫访问手机版
    • 回到顶部
    • 回到顶部