我正在尝试在 JAX-RS 之上使用 Apache-CXF 开发 REST 服务。对于初学者,我有一个名为的方法test
,它接收 aString message
和int value
. 我希望客户端能够在 POST 消息正文中传递这些参数。我似乎无法做到这一点。
在我在这里粘贴代码之前,这里有一些细节:
- 我正在使用没有 Spring 的 CXF
- 它不是一个网络应用程序,所以我没有带有 web.xml 的 WEB-INF 文件夹
- 我使用 SoapUI 和 Postman(Google Chrome 应用程序)测试服务
使用以下代码,我得到WARNING: javax.ws.rs.BadRequestException: HTTP 400 Bad Request
:
演示服务.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。
然后我在 SO 上看到了这个问题:How to access parameters in a RESTful POST method并尝试了这个:
在 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 - 不支持的媒体类型)我将以下依赖项(jettison 和另一件事)添加到 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>
我在 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 格式返回值(或者它不应该为字符串这样做?)