Java:接收 formdata 时出现 Jersey 的 ContainerException,但接收原始 JSON 数据时正常

发布于 2025-01-19 15:45:26 字数 11932 浏览 0 评论 0原文

我目前正在为Killbill制作一个插件,使用Jooby开发Servlet。 Servlet将从付款网关接收通知,并

@Singleton
public class NotificationServlet {

    private final InvoiceApi invoiceApi;
    private static final Logger logger = LoggerFactory.getLogger(NotificationServlet .class);

    @Inject
    public NotificationServlet() {
        // initiate InvoiceApi
        this.invoiceApi = new InvoiceApi(new KillBillHttpClient()); 
    }

    @POST
    @Path("/notify")
    public Result notify(@Body String body) throws KillBillClientException {
        logger.info(body);
        JSONObject dataJson = new JSONObject(body);
        if (dataJson.getString("status_code").equalsIgnoreCase("1")) {
            String referenceId = dataJson.getString("reference_id");
            String[] referenceIdArray = referenceId.split("\\|");
            String apiKey = referenceIdArray[0];
            String apiSecret = referenceIdArray[1];
            String accountId = referenceIdArray[2];
            String invoiceId = referenceIdArray[3];
            String amount = referenceIdArray[4];

            InvoicePayment invoicePayment = new InvoicePayment();
            invoicePayment.setPurchasedAmount(new BigDecimal(amount));
            invoicePayment.setAccountId(UUID.fromString(accountId));
            invoicePayment.setTargetInvoiceId(UUID.fromString(invoiceId));

            RequestOptions requestOptions = RequestOptions.builder()
                                                          .withCreatedBy("createdBy")
                                                          .withReason("reason")
                                                          .withComment("comment")
                                                          .withQueryParams(ArrayListMultimap.create())
                                                          .withTenantApiKey(apiKey)
                                                          .withTenantApiSecret(apiSecret)
                                                          .build();

            InvoicePayment result = invoiceApi.createInstantPayment(UUID.fromString(invoiceId),
                                                                    invoicePayment,
                                                                    true,
                                                                    null,
                                                                    null,
                                                                    requestOptions);
        }

        return Results.with("", Status.OK)
                      .type(MediaType.json);
    }

在我使用Postman测试此Servlet时将更新处理到内部Killbill系统中,Servlet可以正常工作。但是,当我用付款网关测试此操作时,我得到了泽西岛的contererexception,

2022-04-07T16:08:07,423+0000 lvl='ERROR', log='[default]', th='catalina-exec-10', xff='', rId='', tok='', aRId='', tRId='', Servlet.service() for servlet [default] in context with path [] threw exception [org.glassfish.jersey.server.ContainerException: java.io.IOException: Stream closed] with root cause
java.io.IOException: Stream closed
        at org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:367)
        at org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:152)
        at com.google.common.io.ByteStreams.copy(ByteStreams.java:109)
        at org.killbill.billing.jaxrs.resources.PluginResource.createInputStream(PluginResource.java:247)
        at org.killbill.billing.jaxrs.resources.PluginResource.serviceViaOSGIPlugin(PluginResource.java:185)
        at org.killbill.billing.jaxrs.resources.PluginResource.doFormPOST(PluginResource.java:140)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.lambda$static$0(ResourceMethodInvocationHandlerFactory.java:52)
        at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:124)
        at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:167)
        at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:176)
        at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:79)
        at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:475)
        at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:397)
        at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:81)
        at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:255)
        at org.glassfish.jersey.internal.Errors$1.call(Errors.java:248)
        at org.glassfish.jersey.internal.Errors$1.call(Errors.java:244)
        at org.glassfish.jersey.internal.Errors.process(Errors.java:292)
        at org.glassfish.jersey.internal.Errors.process(Errors.java:274)
        at org.glassfish.jersey.internal.Errors.process(Errors.java:244)
        at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:265)
        at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:234)
        at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:680)
        at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:394)
        at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:346)
        at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:366)
        at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:319)
        at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:205)
        at com.google.inject.servlet.ServletDefinition.doServiceImpl(ServletDefinition.java:290)
        at com.google.inject.servlet.ServletDefinition.doService(ServletDefinition.java:280)
        at com.google.inject.servlet.ServletDefinition.service(ServletDefinition.java:184)
        at com.google.inject.servlet.ManagedServletPipeline.service(ManagedServletPipeline.java:89)
        at org.killbill.billing.server.security.TenantFilter.handleAuthenticationError(TenantFilter.java:120)
        at org.killbill.billing.server.security.TenantFilter.doFilter(TenantFilter.java:89)
        at org.killbill.billing.server.filters.ResponseCorsFilter.doFilter(ResponseCorsFilter.java:75)
        at ch.qos.logback.classic.helpers.MDCInsertingServletFilter.doFilter(MDCInsertingServletFilter.java:49)
        at com.google.inject.servlet.ManagedFilterPipeline.dispatch(ManagedFilterPipeline.java:121)
        at com.google.inject.servlet.GuiceFilter.doFilter(GuiceFilter.java:133)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.apache.shiro.guice.web.SimpleFilterChain.doFilter(SimpleFilterChain.java:44)
        at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)
        at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)
        at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
        at org.apache.shiro.guice.web.SimpleFilterChain.doFilter(SimpleFilterChain.java:41)
        at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)
        at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)
        at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
        at org.apache.shiro.guice.web.SimpleFilterChain.doFilter(SimpleFilterChain.java:41)
        at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449)
        at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)
        at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
        at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
        at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:383)
        at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)
        at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at com.codahale.metrics.servlet.AbstractInstrumentedFilter.doFilter(AbstractInstrumentedFilter.java:111)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:544)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
        at org.apache.catalina.valves.rewrite.RewriteValve.invoke(RewriteValve.java:305)
        at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:690)
        at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:747)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:616)
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:818)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1626)
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)

我怀疑这可能是因为发送了不同类型的身体,因为我使用JSON格式的原始数据与Postman进行了测试,同时Gateway正在发送X wwww-form - urlencoded。我注意到了这一点,因为出现此错误之前有警告,

2022-04-07T16:08:01,477+0000 lvl='WARN', log='WebComponent', th='catalina-exec-9', xff='', rId='', tok='', aRId='', tRId='', 
A servlet request to the URI http://path/to/my/notify-servlet contains form parameters in 
the request body but the request body has been consumed by the servlet or a servlet filter 
accessing the request parameters. Only resource methods using @FormParam will work as 
expected. Resource methods consuming the request body by other means will not work as expected.

我尝试根据 Jooby在表单提交中的文档,但问题仍然存在。那么问题仍然在Jooby还是在泽西岛?

I'm currently working on a plugin for Killbill, using Jooby for developing the servlet. The servlet will receive a notification from payment gateway and process the update into internal Killbill system

@Singleton
public class NotificationServlet {

    private final InvoiceApi invoiceApi;
    private static final Logger logger = LoggerFactory.getLogger(NotificationServlet .class);

    @Inject
    public NotificationServlet() {
        // initiate InvoiceApi
        this.invoiceApi = new InvoiceApi(new KillBillHttpClient()); 
    }

    @POST
    @Path("/notify")
    public Result notify(@Body String body) throws KillBillClientException {
        logger.info(body);
        JSONObject dataJson = new JSONObject(body);
        if (dataJson.getString("status_code").equalsIgnoreCase("1")) {
            String referenceId = dataJson.getString("reference_id");
            String[] referenceIdArray = referenceId.split("\\|");
            String apiKey = referenceIdArray[0];
            String apiSecret = referenceIdArray[1];
            String accountId = referenceIdArray[2];
            String invoiceId = referenceIdArray[3];
            String amount = referenceIdArray[4];

            InvoicePayment invoicePayment = new InvoicePayment();
            invoicePayment.setPurchasedAmount(new BigDecimal(amount));
            invoicePayment.setAccountId(UUID.fromString(accountId));
            invoicePayment.setTargetInvoiceId(UUID.fromString(invoiceId));

            RequestOptions requestOptions = RequestOptions.builder()
                                                          .withCreatedBy("createdBy")
                                                          .withReason("reason")
                                                          .withComment("comment")
                                                          .withQueryParams(ArrayListMultimap.create())
                                                          .withTenantApiKey(apiKey)
                                                          .withTenantApiSecret(apiSecret)
                                                          .build();

            InvoicePayment result = invoiceApi.createInstantPayment(UUID.fromString(invoiceId),
                                                                    invoicePayment,
                                                                    true,
                                                                    null,
                                                                    null,
                                                                    requestOptions);
        }

        return Results.with("", Status.OK)
                      .type(MediaType.json);
    }

When I tested this servlet using Postman, the servlet works fine. But when I tested this with the payment gateway, I got Jersey's ContainerException

2022-04-07T16:08:07,423+0000 lvl='ERROR', log='[default]', th='catalina-exec-10', xff='', rId='', tok='', aRId='', tRId='', Servlet.service() for servlet [default] in context with path [] threw exception [org.glassfish.jersey.server.ContainerException: java.io.IOException: Stream closed] with root cause
java.io.IOException: Stream closed
        at org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:367)
        at org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:152)
        at com.google.common.io.ByteStreams.copy(ByteStreams.java:109)
        at org.killbill.billing.jaxrs.resources.PluginResource.createInputStream(PluginResource.java:247)
        at org.killbill.billing.jaxrs.resources.PluginResource.serviceViaOSGIPlugin(PluginResource.java:185)
        at org.killbill.billing.jaxrs.resources.PluginResource.doFormPOST(PluginResource.java:140)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.lambda$static$0(ResourceMethodInvocationHandlerFactory.java:52)
        at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:124)
        at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:167)
        at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:176)
        at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:79)
        at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:475)
        at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:397)
        at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:81)
        at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:255)
        at org.glassfish.jersey.internal.Errors$1.call(Errors.java:248)
        at org.glassfish.jersey.internal.Errors$1.call(Errors.java:244)
        at org.glassfish.jersey.internal.Errors.process(Errors.java:292)
        at org.glassfish.jersey.internal.Errors.process(Errors.java:274)
        at org.glassfish.jersey.internal.Errors.process(Errors.java:244)
        at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:265)
        at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:234)
        at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:680)
        at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:394)
        at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:346)
        at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:366)
        at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:319)
        at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:205)
        at com.google.inject.servlet.ServletDefinition.doServiceImpl(ServletDefinition.java:290)
        at com.google.inject.servlet.ServletDefinition.doService(ServletDefinition.java:280)
        at com.google.inject.servlet.ServletDefinition.service(ServletDefinition.java:184)
        at com.google.inject.servlet.ManagedServletPipeline.service(ManagedServletPipeline.java:89)
        at org.killbill.billing.server.security.TenantFilter.handleAuthenticationError(TenantFilter.java:120)
        at org.killbill.billing.server.security.TenantFilter.doFilter(TenantFilter.java:89)
        at org.killbill.billing.server.filters.ResponseCorsFilter.doFilter(ResponseCorsFilter.java:75)
        at ch.qos.logback.classic.helpers.MDCInsertingServletFilter.doFilter(MDCInsertingServletFilter.java:49)
        at com.google.inject.servlet.ManagedFilterPipeline.dispatch(ManagedFilterPipeline.java:121)
        at com.google.inject.servlet.GuiceFilter.doFilter(GuiceFilter.java:133)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.apache.shiro.guice.web.SimpleFilterChain.doFilter(SimpleFilterChain.java:44)
        at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)
        at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)
        at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
        at org.apache.shiro.guice.web.SimpleFilterChain.doFilter(SimpleFilterChain.java:41)
        at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)
        at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)
        at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
        at org.apache.shiro.guice.web.SimpleFilterChain.doFilter(SimpleFilterChain.java:41)
        at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449)
        at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)
        at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
        at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
        at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:383)
        at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)
        at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at com.codahale.metrics.servlet.AbstractInstrumentedFilter.doFilter(AbstractInstrumentedFilter.java:111)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:544)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
        at org.apache.catalina.valves.rewrite.RewriteValve.invoke(RewriteValve.java:305)
        at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:690)
        at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:747)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:616)
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:818)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1626)
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)

I'm suspecting it might be because different type of body being sent, since I tested with Postman using raw data in JSON format meanwhile the gateway is sending x-www-form-urlencoded. I noticed this since there's a warning before this error appeared

2022-04-07T16:08:01,477+0000 lvl='WARN', log='WebComponent', th='catalina-exec-9', xff='', rId='', tok='', aRId='', tRId='', 
A servlet request to the URI http://path/to/my/notify-servlet contains form parameters in 
the request body but the request body has been consumed by the servlet or a servlet filter 
accessing the request parameters. Only resource methods using @FormParam will work as 
expected. Resource methods consuming the request body by other means will not work as expected.

I've tried adjusting the method according to Jooby's docs on form submission, but the issue still persists. So is the issue still in Jooby or it's in Jersey?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文