如何在 CXF 中的 JAX-RS Restful Web 服务中接收 POST 正文中的 JSON 消息?

问题描述 投票:0回答:1

我正在尝试在 JAX-RS 之上使用 Apache-CXF 开发 REST 服务。首先,我有一个名为

test
的方法,它接收
String message
int value
。我希望客户端能够在 POST 消息正文中传递这些参数。我似乎无法实现这一目标。

在将代码粘贴到此处之前,这里有一些详细信息:

  • 我使用的是没有 Spring 的 CXF
  • 它不是一个网络应用程序,所以我没有带有 web.xml 的 WEB-INF 文件夹
  • 我使用 SoapUI 和 Postman(Google Chrome 应用程序)测试该服务

使用以下代码,我得到

WARNING: javax.ws.rs.BadRequestException: HTTP 400 Bad Request

DemoService.java

@WebService(targetNamespace = "http://demoservice.com")
@Path("/demoService")
public interface DemoService {
    @POST
    @Path("/test")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    public String test (String message, int value);
}

DemoServiceImpl.java

public class DemoServiceImpl implements DemoService {
    @Override
    public String test(String message, int value) {
        return "test message: " + message + " value =  : " + value;
    }
}

演示服务器.java

public class DemoServer{
    public static void main(String[] args) {

        JAXRSServerFactoryBean serverFactory = new JAXRSServerFactoryBean();
        DemoService demoService = new DemoServiceImpl();
        serverFactory.setServiceBean(demoService);
        serverFactory.setAddress("http://localhost:9090");
        serverFactory.create();
    }
}

我的 POM.xml(减去根标签中的属性,一切都在那里)

<project ...>
    <modelVersion>4.0.0</modelVersion>
    <groupId>demo</groupId>
    <artifactId>demoService</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <cxf.version>3.0.0</cxf.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxws</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxrs</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <!-- Jetty is needed if you're are not using the CXFServlet -->
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http-jetty</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-rs-service-description</artifactId>
            <version>3.0.0-milestone1</version>
        </dependency>

    </dependencies>
</project>

使用

{"message":"hello there!", "value":"50"}
对 URL
http://localhost:9090/demoService/test
进行测试,得到 HTTP 400 Bad Reuest。

然后我在 S.O. 上看到这个问题:如何在 RESTful POST 方法中访问参数并尝试了这个:

在 DemoServer.java 中添加了以下嵌套类:

    @XmlRootElement
    public static class TestRequest {
        private String message;
        private int value;

        public String getMessage() { return message; }
        public void setMessage(String message) { this.message = message; }
        public int getValue() { return value; }
        public void setValue(int value) { this.value = value; }
    }

我还修改了 DemoService 接口和实现,以在

test
方法中使用此类作为参数,尽管这最终仍然不是我想要做的。 (只是在这里展示实现,问题已经很长了):

@Override
public String test(TestRequest testRequest) {
    String message = testRequest.getMessage();
    int value = testRequest.getValue();
    return "test message: " + message + " value =  : " + value;
}

为了修复我遇到的这个错误:

SEVERE: No message body reader has been found for class DemoService$TestRequest, ContentType: application/json
(在 Postman 中我看到错误 415 - 不支持的媒体类型)我在 POM.xml 中添加了以下依赖项(jettison 和其他东西):

<dependency>
    <groupId>org.codehaus.jettison</groupId>
    <artifactId>jettison</artifactId>
    <version>1.3.5</version>
</dependency>
<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-rs-extension-providers</artifactId>
    <version>2.6.0</version>
</dependency>

我在 HTTP POST 请求中使用以下 JSON 消息测试了该服务:

{"testRequest":{"message":"hello there!", "value":"50"}}

这有效。虽然我使用 TestRequest 类封装参数的解决方案有效,但这不是我正在寻找的解决方案。我希望能够在 JSON 消息中传递两个参数,而不必(显式)引入此 TestRequest 类。

问题:

  • 使用 Jersey 会更容易实现吗?
  • 我没有 web.xml 也没有 WEB-INF 文件夹,所以我无法在 cxf.xml 文件中配置 CXF,可以吗?网上的很多教程似乎都没有使用大量的 XML 配置,但我不想仅仅为了做到这一点而部署像 TomEE 或 Spring 或 Glassfish 这样的框架。
  • 在网上搜索解决方案,我遇到了Spring Boot。也许您会推荐使用它?这会让开发这样的 Web 服务变得更容易吗?
  • 另外,如何让它以 JSON 格式返回值(或者不应该对字符串执行此操作?)
json web-services rest cxf jettison
1个回答
0
投票

我的朋友向我指出了这个堆栈交换问题:JAX-RS Post multiple object

还有以下文档:http://cxf.apache.org/docs/jax-rs-and-jax-ws.html

其中指出:

public class CustomerService {
   public void doIt(String a, String b) {...};
}

默认情况下,JAX-RS 可能无法处理此类方法 要求签名中只能使用单个参数 没有被 JAX-RS 注释之一注释,例如 @PathParam。因此,如果“String a”参数可以映射到@Path 模板变量或查询段之一然后是此签名 不需要改变:

@Path("/customers/{a}")
public class CustomerService {
   public void doIt(@PathParam("a") String a, String b) {...};
}

所以,回答我的问题,不,这是不可能的。

© www.soinside.com 2019 - 2024. All rights reserved.