2

我正在开发一个安静的 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 中的 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>

设置查询参数“回调”时出现的错误是:

org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor writeResponseErrorMessage
WARNING: No message body writer has been found for response class Server.

它适用于其他两种情况。

我一直在寻找解决方案,但仍然一无所获。

有任何想法吗?

谢谢

4

1 回答 1

0

这是我的课,@OverrideswrtieTo()方法的org.apache.cxf.jaxrs.provider.json.JSONProvider;

首先在我的 beans.xml 文件中我使用了<jaxrs:extensionMappings>并且我已经声明了一个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

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。如果是,那么我知道我必须使用回调函数返回 jsopn。最后一件事是设置回调函数的名称。如果用户已将_jsonp查询参数设置为 URL,则此参数的值将是回调函数的名称。如果_jsonppquery 参数为空,那么我输入一个默认名称callback

当然,在beans.xml文件中作为json提供者,您将 JsonpProvider 放在上面:

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

希望对@bhuvan有帮助!

于 2013-06-28T13:30:42.250 回答