我正在构建RESTful API,并希望为开发人员提供选择在JSON响应中返回哪些字段的选项. 此博客文章显示了几个API(Google,Facebook,LinkedIn)如何允许开发人员自定义响应的示例.这被称为部分响应.
示例可能如下所示:
/users/123?fields=userId,fullname,title
Run Code Online (Sandbox Code Playgroud)
在上面的示例中,API应返回User"123"的userId,fullName和title字段.
我正在寻找如何在我的RESTful Web服务中实现它的想法.我目前正在使用CXF(编辑:和杰克逊),但愿意尝试另一种JAX-RS实现.
这就是我现在拥有的.它返回一个完整的User对象.如何根据"字段"参数返回API调用者在运行时想要的字段?我不想让其他字段为空.我根本不想归还他们.
@GET
@Path("/{userId}")
@Produces("application/json")
public User getUser(@PathParam("userId") Long userId,
@DefaultValue("userId,fullname,title") @QueryParam("fields") String fields) {
User user = userService.findOne(userId);
StringTokenizer st = new StringTokenizer(fields, ",");
while (st.hasMoreTokens()) {
// here's where i would like to select only the fields i want to return
}
return user;
}
Run Code Online (Sandbox Code Playgroud)
更新:
我按照unludo的链接然后链接到这个:http://wiki.fasterxml.com/JacksonFeatureJsonFilter
有了这些信息,我就加入@JsonFilter("myFilter")
了我的域类.然后我修改了我的RESTful服务方法以返回String而不是User,如下所示:
@GET
@Path("/{userId}")
@Produces("application/json")
public String getUser(@PathParam("userId") Long userId,
@DefaultValue("userId,fullname,title") @QueryParam("fields") String fields) {
User user = userService.findOne(userId);
StringTokenizer …
Run Code Online (Sandbox Code Playgroud) 我正在使用Apache CXF框架.在我的客户端程序中,我需要记录CXF SOAP请求和SOAP响应.我用的时候
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setAddress(host);
factory.setServiceClass(MyService.class);
factory.getInInterceptors().add(new LoggingInInterceptor());
factory.getOutInterceptors().add(new LoggingOutInterceptor());
Run Code Online (Sandbox Code Playgroud)
我在控制台中获得了这些SOAP请求和SOAP响应:
Nov 9, 2011 6:48:01 PM org.apache.cxf.interceptor.LoggingOutInterceptor$LoggingCallback onClose
INFO: Outbound Message
---------------------------
ID: 2
Encoding: UTF-8
Content-Type: text/xml
Headers: {}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns4:MYResponse
--------------------------------------
Run Code Online (Sandbox Code Playgroud)
但我的实际要求是,我需要将它们放在日志文件中,而不是将它们打印到服务器控制台.
当我直接使用log4j时如图所示
log4j(factory.getInInterceptors().add(new LoggingInInterceptor()));
log4j(factory.getOutInterceptors().add(new LoggingOutInterceptor()));
Run Code Online (Sandbox Code Playgroud)
它只打印true
并true
在日志文件中.
有人可以告诉我如何配置吗?
我正在使用CXF rest客户端,它适用于简单的数据类型(例如:字符串,整数).但是,当我尝试使用自定义对象时,我得到了这个:
Exception in thread "main" org.apache.cxf.interceptor.Fault: .No message body writer found for class : class com.company.datatype.normal.MyObject.
at org.apache.cxf.jaxrs.client.ClientProxyImpl$BodyWriter.handleMessage(ClientProxyImpl.java:523)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263)
at org.apache.cxf.jaxrs.client.ClientProxyImpl.doChainedInvocation(ClientProxyImpl.java:438)
at org.apache.cxf.jaxrs.client.ClientProxyImpl.invoke(ClientProxyImpl.java:177)
at $Proxy13.execute(Unknown Source)
at com.company.JaxTestClient.main(JaxTestClient.java:26)
Caused by: org.apache.cxf.jaxrs.client.ClientWebApplicationException: .No message body writer found for class : class com.company.datatype.normal.MyObject.
at org.apache.cxf.jaxrs.client.AbstractClient.reportMessageHandlerProblem(AbstractClient.java:491)
at org.apache.cxf.jaxrs.client.AbstractClient.writeBody(AbstractClient.java:401)
at org.apache.cxf.jaxrs.client.ClientProxyImpl$BodyWriter.handleMessage(ClientProxyImpl.java:515)
... 5 more
Run Code Online (Sandbox Code Playgroud)
我这样称呼它:
JaxExample jaxExample = JAXRSClientFactory.create( "http://localhost:8111/", JaxExample.class );
MyObject before = ...
MyObject after = jaxExample.execute( before );
Run Code Online (Sandbox Code Playgroud)
这是界面中的方法:
@POST
@Path( "execute" )
@Produces( "application/json" )
MyObject execute( …
Run Code Online (Sandbox Code Playgroud) 当我调用使用CXF构建的特定的restful服务方法时,我收到以下错误,有人知道为什么以及如何解决它?
发生JAXBException:类com.octory.ws.dto.ProfileDto也不是它的任何超类都知道这个上下文...
以下是服务方法和相关的DTO:
public class Service {
public Response results() {
Collection<ProfileDto> profilesDto = new ArrayList<ProfileDto>();
...
SearchResultDto srd = new SearchResultDto();
srd.setResultEntities(profilesDto); // Setting profilesDto collection as resultEntities
srd.setResultSize(resultSize);
return Response.ok(srd).build();
}
}
Run Code Online (Sandbox Code Playgroud)
SearchResultDto:
@XmlRootElement(name="searchResult")
public class SearchResultDto {
private Collection resultEntities;
private int resultSize;
public SearchResultDto() { }
@XmlElementWrapper(name="resultEntities")
public Collection getResultEntities() {
return resultEntities;
}
public void setResultEntities(Collection resultEntities) {
this.resultEntities = resultEntities;
}
public int getResultSize() {
return resultSize;
}
public void …
Run Code Online (Sandbox Code Playgroud) 我已成功设置了一个快速测试,创建一个"类似REST"的服务,返回一个序列化为JSON的对象,这非常简单快捷(基于这篇文章).
但是,虽然返回JSON-ified对象很容易像桃子一样,但我还没有看到任何处理非基本输入参数的例子.如何将复杂对象作为参数传递?我正在使用Apache CXF,但是欢迎使用像Jackson这样的其他框架的例子:)
客户端可能类似于构建javascript对象,将其传递给JSON.stringify(complexObj),并将该字符串作为参数之一传递.
该服务可能看起来像这样
@Service("myService")
class RestService {
@GET
@Produces("application/json")
@Path("/fooBar")
public Result fooBar(@QueryParam("foo") double foo, @QueryParam("bar") double bar,
@QueryParam("object") MyComplex object) throws WebServiceException {
...
}
}
Run Code Online (Sandbox Code Playgroud)
将序列化对象作为参数发送可能会快速触及Internet Explorer强加的2KB URL限制.您是否建议在这些情况下使用POST,我是否需要在函数定义中进行更改?
我有一个奇怪的问题.
使用wsimport我从WSDL(在专用的eclipse java项目中)生成了JES-WS代码.这在JDK6中工作正常,没有任何外部依赖(在Eclipse中运行)
我有第二个项目,我曾经使用过Apache CXF.如果我将1.)中描述的代码复制到这个项目中,那么JDK突然不会执行JAX-WS的东西(我生成的文件),而是Apache CXF.
如何防止Apache CXF"运行"JAX-WS的东西.(问题是,CXF无法运行代码......).我也完全不明白Apache CXF如何发现这些类.我没有注册他们吗?
非常感谢你!马库斯
我需要为后端使用旧式RPC /编码的WSDL Web服务.起初我尝试使用Apache CXF和JAX-WS,但JAX-WS wsimport
工具不使用rpc/enoded WSDL.
[错误] JAXWS 2.0不支持rpc/encoded wsdls.
我也对使用JAX-RPC做这项工作有疑问,因为它已经过时了.Axis 1.4是5年的工具.
目前我看到这三个选项:
javax.xml.ws.Dispatch
来发送和接收SOAP和某种方式解析它,一个例子这些都听起来不太好,所以如果你能提供一些好的线索,想要做什么以及如何解决它,我将不胜感激.
如果有人帮助我理解axis2 web服务和CXF Web服务之间的区别,我将不胜感激.
我正在使用Apache CXF
cxf-codegen-plugin
Maven
插件从WSDL
文件生成源代码.问题是我JAXBElement<String>
生成而不是String
.我添加了如下所示的jaxb-bindings.xml
文件:
<jaxb:bindings version="2.1"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb">
<jaxb:globalBindings generateElementProperty="false"/>
</jaxb:bindings>
Run Code Online (Sandbox Code Playgroud)
这应该阻止JAXB
生成JAXBElement<String>
.但它不起作用我仍然JAXBElement<String>
生成而不是String
.
我的Maven
插件看起来像这样:
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>${cxf.runtime.version}</version>
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-bindings-soap</artifactId>
<version>${cxf.runtime.version}</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>generate-jaxb</id>
<phase>generate-sources</phase>
<configuration>
<additionalJvmArgs>-Dfile.encoding=UTF8</additionalJvmArgs>
<wsdlOptions>
<wsdlOption>
<wsdl>src/main/resources/wsdl/Cubiks.wsdl</wsdl>
<extraargs>
<extraarg>-b</extraarg>
<extraarg>${basedir}/jaxb-bindings.xml</extraarg>
<extraarg>-b</extraarg>
<extraarg>${basedir}/jaxws-bindings.xml</extraarg>
<extraarg>-exsh</extraarg>
<extraarg>true</extraarg>
<extraarg>-wsdlLocation</extraarg>
<extraarg></extraarg>
</extraargs>
</wsdlOption>
<wsdlOption>
<wsdl>src/main/resources/wsdl/CubiksCallBackService.wsdl</wsdl>
<extraargs>
<extraarg>-b</extraarg>
<extraarg>${basedir}/jaxws-bindings.xml</extraarg>
<extraarg>-b</extraarg>
<extraarg>${basedir}/jaxb-bindings.xml</extraarg>
<extraarg>-exsh</extraarg>
<extraarg>true</extraarg>
<extraarg>-p</extraarg>
<extraarg>com.cubiks.ws.callback</extraarg>
<extraarg>-wsdlLocation</extraarg>
<extraarg></extraarg>
</extraargs>
</wsdlOption>
</wsdlOptions>
</configuration> …
Run Code Online (Sandbox Code Playgroud) 我一直在写一个小应用程序,让人们上传和下载文件给我.我已经为这个applciation添加了一个Web服务来提供上传/下载功能,但我不太确定我的实现将如何处理大文件.
目前,上传和下载方法的定义如下所示(使用Apache CXF编写):
boolean uploadFile(@WebParam(name = "username") String username,
@WebParam(name = "password") String password,
@WebParam(name = "filename") String filename,
@WebParam(name = "fileContents") byte[] fileContents)
throws UploadException, LoginException;
byte[] downloadFile(@WebParam(name = "username") String username,
@WebParam(name = "password") String password,
@WebParam(name = "filename") String filename) throws DownloadException,
LoginException;
Run Code Online (Sandbox Code Playgroud)
因此文件作为字节数组上传和下载.但是,如果我有一个愚蠢的大小(例如1GB)的文件肯定会尝试将所有信息放入内存并使我的服务崩溃.
所以我的问题是 - 是否有可能返回某种流?我想这不会是非常独立的操作系统.虽然我知道Web服务背后的理论,但实际的一面是我还需要了解一些信息.
为任何输入干杯,李