【问题标题】:Spring Reactive get body JSONObject using ServerRequestSpring Reactive 使用 ServerRequest 获取正文 JSONObject
【发布时间】:2019-03-23 01:20:45
【问题描述】:

我是 Spring 响应式新手。

我正在尝试使用邮递员从服务器获取请求信息。

首先,postman 使用 post 方法向服务器发送信息。 其次,我们一直在使用相关代码在服务器端工作并获取请求信息。

在下面的代码sn-p中

不知能不能得到ServerRequest函数的JSONObject。

邮递员正文(应用程序/json)

{
    "name": "aaaa",
    "name_order": ["aa", "bb", "cc"],
    "type": "12",
    "query": ""
}

java (RouterFunction)

import com.ntels.io.input.handler.RestInHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.config.EnableWebFlux;
import org.springframework.web.reactive.config.WebFluxConfigurer;
import org.springframework.web.reactive.function.server.*;

import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
import static org.springframework.web.reactive.function.server.RequestPredicates.POST;
import static org.springframework.web.reactive.function.server.RequestPredicates.PUT;
import static org.springframework.web.reactive.function.server.RequestPredicates.DELETE;

@Configuration
@EnableWebFlux
public class RestConfig implements WebFluxConfigurer {

    @Bean
    public RouterFunction<ServerResponse> routes(RestInHandler restInHandler){
        return RouterFunctions.route(POST("/input/event").
        and(RequestPredicates.accept(MediaType.APPLICATION_JSON)), restInHandler::toRESTInVerticle);
    }
}

java(处理程序)

public Mono<ServerResponse> toRESTInVerticle(ServerRequest serverRequest) {
    String serverRequestUrl = serverRequest.uri().toString();

    System.out.println("RestInHandler test in");
    System.out.println(serverRequest.method());
    System.out.println(serverRequest.headers());
    System.out.println(serverRequest.uri().toString());

    // how can i get the jsonbody using serverrequest

    // testing..

    // Mono<JSONObject> jsonObjectMono = serverRequest.bodyToMono(JSONObject.class);
    // Flux<JSONObject> jsonObjectFlux = serverRequest.bodyToFlux(JSONObject.class);
-> MonoOnErrorResume

    return (Mono<ServerResponse>) ServerResponse.ok();
}

【问题讨论】:

    标签: java spring reactive


    【解决方案1】:

    谢谢。 Alexander Terekhov

    您的回答对解决问题有很大帮助。

    我的测试代码。

    RouterFunction = 与现有代码相同。

    处理程序

    public Mono<ServerResponse> toRESTInVerticle(ServerRequest serverRequest) {
        String uri = serverRequest.uri().toString();
        String method = serverRequest.methodName();
        String contentType = serverRequest.headers().contentType().get().toString();
        String characterSet = serverRequest.headers().acceptCharset().get(0).toString();
        JSONObject bodyData = serverRequest.bodyToMono(JSONObject.class).toProcessor().peek();
    
        System.out.println("==========toRESTInVerticle Data Check==========");
        System.out.println(uri);
        System.out.println(method);
        System.out.println(contentType);
        System.out.println(characterSet);
        System.out.println(bodyData);
        System.out.println("======toRESTInVerticle Data Check Complete======");
    
        return Mono.empty();
    }
    

    控制台中的结果如下所示:-

    ==========toRESTInVerticle Data Check==========
    http://localhost:8082/input/event/check
    POST
    application/json
    UTF-8
    {"event_type":"12","event_name_order":["aa","bb","cc"],"event_query":"","event_name":"aaaa","init_value":"","init_value_yn":"N","event_descp":"ddd"}
    ======toRESTInVerticle Data Check Complete======
    

    编码愉快,谢谢。


    已更新。

    谢谢。 @Zon 评论。 toProcessor 现在已弃用 - 更喜欢 share() 共享父订阅,或使用接收器 https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html#toProcessor--也请参考这个网址。

    【讨论】:

    • 请告诉我JSONObject类的导入路径是什么。
    • @Nick 嗨,我使用 org.json.simple.JSONObject 类。在 Maven 设置中。像这样。 com.googlecode.json-simplejson-simple1.1
    • toProcessor 现已弃用 - 首选 share() 共享父订阅,或使用 Sinks
    • @Zon 谢谢。 projectreactor.io/docs/core/release/api/reactor/core/publisher/…也请参考这个网址。
    【解决方案2】:

    我认为您可以尝试通过以下方式注册一种“回调”:

            return request.bodyToMono(JSONObject.class)
                      .doOnNext(jsonObject -> // testing..)
                      .then(ServerResponse.ok().build());
    

    另外,我注意到您将ServerResponse.ok() 转换为Mono&lt;ServerResponse&gt;。我认为它不会投。使用ServerResponse.ok().build() 制作Mono&lt;ServerResponse&gt;

    【讨论】:

    • 我尝试了这种方法,但我观察到然后在 doOnNext 之前被调用,因为我正在更改 doOnNext 中的响应,我的要求是等到 doOnNext 完成
    • 一些数据库调用
    • 同步与否?
    【解决方案3】:

    @oddeveloper 我发现 Mono.toProcessor() 已被弃用。

    最简单的方法就是拥有这样的POJO

    import java.util.List;
    import java.util.Objects;
    import java.util.logging.Logger;
    
    public class Person {
        
        private String name;
        
        private List<String> nameOrder;
        
        private String type;
        
        private String query;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public List<String> getNameOrder() {
            return nameOrder;
        }
    
        public void setNameOrder(List<String> nameOrder) {
            this.nameOrder = nameOrder;
        }
    
        public String getType() {
            return type;
        }
    
        public void setType(String type) {
            this.type = type;
        }
    
        public String getQuery() {
            return query;
        }
    
        public void setQuery(String query) {
            this.query = query;
        }
        
        
        @Override
        public String toString() {
            return "Person{" + "name=" + name + ", nameOrder=" + nameOrder + ", type=" + type + ", query=" + query + '}';
        }
    }
    

    然后提取Person person = serverRequest.bodyToMono(Person.class).toFuture().get()

    get() 函数

    如有必要,等待这个未来完成,然后返回它的 结果。

    @terekhov你的解决方案对我不起作用,我不知道为什么

    如果这对你不起作用并且你必须有一个 JSONObject 然后像这样创建一个 JSONObjectBodyExtractor

    import java.nio.charset.StandardCharsets;
    import org.json.JSONObject;
    import org.reactivestreams.Subscriber;
    import org.reactivestreams.Subscription;
    import org.springframework.http.ReactiveHttpInputMessage;
    import org.springframework.web.reactive.function.BodyExtractor;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import org.springframework.core.io.buffer.DataBuffer;
    import reactor.core.publisher.Mono;
    
    /**
     *
     * @author timot
     * @param <T>
     * @param <M>
     */
    public class JSONObjectBodyExtractor<T extends Mono<JSONObject>, M extends ReactiveHttpInputMessage> implements BodyExtractor {
    
        private static final Logger LOG = Logger.getLogger(JSONObjectBodyExtractor.class.getName());
    
        @Override
        public Mono<JSONObject> extract(ReactiveHttpInputMessage inputMessage, Context context) {
    
            return Mono.<JSONObject>create(sink -> {
                inputMessage.getBody().subscribe(new Subscriber() {
    
                    @Override
                    public void onSubscribe(Subscription s) {
                        s.request(1);
                    }
    
                    @Override
                    public void onNext(Object t) {
                        
                        DataBuffer dataBuffer=(DataBuffer) t;
                        
                        sink.success(new JSONObject(dataBuffer.toString(StandardCharsets.UTF_8)));
                    }
    
                    @Override
                    public void onError(Throwable thrwbl) {
                        LOG.log(Level.SEVERE, "jsonobjectbodyextractor onerror", thrwbl);
                    }
    
                    @Override
                    public void onComplete() {
                        LOG.log(Level.INFO, "jsonobjectbodyextractor oncomplete");
                    }
    
                });
            });
        }
    
    }
    

    然后在您的反应式处理程序中像这样提取

        Mono<JSONObject> jsonObjectMono = (Mono<JSONObject>) request.body(jsonObjectBodyExtractor);
    JSONObject jsonObject=jsonObjectMono.toFuture().get();
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-29
    • 2021-01-28
    • 2021-06-02
    • 2020-01-29
    • 2020-10-20
    • 2019-01-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多