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

w51jfk4q  于 2022-11-15  发布在  其他
关注(0)|答案(1)|浏览(151)

我尝试在JAX-RS上使用Apache-CXF开发REST服务。对于初学者,我有一个名为test的方法,它接收String messageint value。我希望客户端能够在POST消息体中传递这些参数。我似乎无法实现这一点。
在我粘贴代码之前,这里有一些细节:

  • 我使用的是不带Spring的CXF
  • 它不是Web应用程序,因此我没有包含web.xml的WEB-INF文件夹
  • 我使用SoapUI和Postman(Google Chrome应用程序)测试服务

下面的代码是:
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;
    }
}

DemoServer.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();
    }
}

My 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错误请求.
然后我在S.O.上看到了这个问题:如何访问RESTful POST方法中的参数,并尝试了以下操作:
在www.example.com中添加了以下嵌套类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添加了以下依赖项(抛弃和其他内容):

<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>

我在HTTPPOST请求中使用以下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格式返回值(或者它不应该对字符串这样做吗?)
laik7k3q

laik7k3q1#

我的朋友给我指了一堆交换问题:JAX-RS Post multiple objects
以及下列文件: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'参数可以Map到@Path模板变量或查询段之一,则无需更改此签名:
@Path("/customers/{a}") public class CustomerService { public void doIt(@PathParam("a") String a, String b) {...}; }
所以,回答我的问题,不,这是不可能的。

相关问题