我正在开发一个restful WS,我想让用户选择以XML或Json的形式从我的WS中取回数据,并且如果他们想要Jsonp,也可以选择一个回调函数。这是我迄今为止所拥有的,而拦截器的部分基于CXF - JAX-RS : Data Bindings。
我的休息服务:
@GET
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Produces({ "application/x-javascript", MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public Response getServers(@Context ServletContext context,
@Context Request request,
@QueryParam("format") String format,
@QueryParam("callback") String callback) {
some code where server object is created....
if(format.equals("json"){
if(callback!= null){
response = Response.status(Status.OK).type("application/x-javascript")
.entity(server).build();
}else{
response = Response.status(Status.OK).type("application/json")
.entity(server).build();
}
} else {
response = Response.status(Status.OK).type("application/xml")
.entity(server).build();
}
return response;
}
我的服务器对象:
@XmlRootElement (name="Server")
public class Server implements Serializable {
private String name=null;
private String hardware = null;
public Server(){
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getHardware() {
return hardware;
}
public void setHardware(String hardware) {
this.hardware = hardware;
}
}
WEB-INF中的my beans.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<context:property-placeholder/>
<context:annotation-config/>
<bean class="org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer"/>
<bean class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer"/>
<jaxrs:server id="services" address="/">
<jaxrs:serviceBeans>
<bean class="com.ba.serversws_cxf.resources.MyResource" />
</jaxrs:serviceBeans>
<jaxrs:inInterceptors>
<bean class="org.apache.cxf.jaxrs.provider.jsonp.JsonpInInterceptor">
<property name="callbackParam" value="callback"/>
</bean>
</jaxrs:inInterceptors>
<jaxrs:outInterceptors>
<bean class="org.apache.cxf.jaxrs.provider.jsonp.JsonpPreStreamInterceptor">
<property name="mediaType" value="application/x+javascript"/>
</bean>
<bean class="org.apache.cxf.jaxrs.provider.jsonp.JsonpPostStreamInterceptor"/>
</jaxrs:outInterceptors>
<jaxrs:providers>
<bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"/>
</jaxrs:providers>
</jaxrs:server>
</beans>
设置查询参数“callback”时出现的错误是:
org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor writeResponseErrorMessage
WARNING: No message body writer has been found for response class Server.
它适用于其他两种情况。
我已经寻找解决方案,但仍然没有。
有什么想法吗?
由于
答案 0 :(得分:0)
以下是@Overrides
wrtieTo()
org.apache.cxf.jaxrs.provider.json.JSONProvider;
方法的<jaxrs:extensionMappings>
首先,在我的beans.xml文件中,我使用了jsonp
并且我声明了<jaxrs:server id="services" address="/">
<jaxrs:extensionMappings>
<entry key="xml" value="application/xml" />
<entry key="json" value="application/json" />
<entry key="jsonp" value="application/javascript"/>
</jaxrs:extensionMappings>
</jaxrs:server>
扩展名。
这是代码
writeTo()
以下是我@Override
<{1}}方法的代码import java.io.IOException;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import org.apache.cxf.jaxrs.provider.json.JSONProvider;
import org.apache.cxf.jaxrs.utils.HttpUtils;
@SuppressWarnings("rawtypes")
@Produces("application/javascript")
public class JsonpProvider extends JSONProvider {
@SuppressWarnings("unchecked")
@Override
public void writeTo(Object obj, Class cls, Type genericType,
Annotation[] anns, MediaType m, MultivaluedMap headers,
OutputStream os) throws IOException {
String requestURI = getContext().getHttpServletRequest()
.getRequestURI();
if (requestURI.contains(".jsonp")) {
String prefix = getContext().getHttpServletRequest().getParameter(
"_jsonp");
if (prefix != null && !prefix.isEmpty()) {
os.write(prefix.getBytes(HttpUtils.getSetEncoding(m, headers,
"UTF-8")));
} else {
os.write("callback".getBytes(HttpUtils.getSetEncoding(m,
headers, "UTF-8")));
}
os.write('(');
super.writeTo(obj, cls, genericType, anns, m, headers, os);
os.write(')');
} else {
super.writeTo(obj, cls, genericType, anns, m, headers, os);
}
}
}
.jsonp
所以我在上面的代码中正在做的是检查是否已经为URL提供了_jsonp
扩展名。如果是,那么我知道我必须使用回调函数返回jsopn。最后一件事是设置回调函数的名称。如果用户已将_jsonp
查询参数设置为URL,则此参数的值将是回调函数的名称。如果callback
pquery参数为null,那么我放置一个defult名称beans.xml
。
当你在json
文件中作为<jaxrs:providers>
<bean class="org.apache.cxf.jaxrs.ext.search.SearchContextProvider"/>
<bean class="com.ba.serversws_cxf.utils.JsonpProvider">
<property name="ignoreNamespaces" value="true" />
<property name="dropRootElement" value="false" />
<property name="supportUnwrapped" value="true" />
</bean>
</jaxrs:providers>
提供程序时,你将JsonpProvider放在上面:
{{1}}
希望能帮助@bhuvan!