使用jquery的getjson()遇到的跨域访问问题(二)——使用拦截器进行数据封装

上一篇我们提到了使用jsonp来解决getjson的跨域访问问题,服务器需要对数据进行一次封装,实际上jersey已经实现了这个功能,具体用法也很简单,加上@JSONP标识就行。
对上一篇的服务器代码进行修改:

    @GET
    @JSONP(queryParam = "jsoncallback")
    @Path("/test")
    @Produces("application/json;charset=utf8")
    public String go(){
        return info;
    }

其中queryparam给出了封装时使用的函数名,在客户端提交数据请求时,url地址就是****?jsoncallback=?

OK,这样就搞定了,当然了,如果需要更进一步的操作,比如说对输出的内容进行深度加工,那么可以参考jersey的实现,源代码在这里:JsonWithPaddingInterceptor.java

比如说同样的功能,自己来实现。看上边的源码,是用拦截器实现的,把源码修改下:

@javax.ws.rs.ext.Provider
public class JsonWithPaddingInterceptor implements WriterInterceptor {

    private static final Map<String, Set<String>> JAVASCRIPT_TYPES;

    static {
        JAVASCRIPT_TYPES = new HashMap<>(2);

        JAVASCRIPT_TYPES.put("application", Arrays.asList("x-javascript", "ecmascript", "javascript")
                                                  .stream().collect(Collectors.toSet()));
        JAVASCRIPT_TYPES.put("text", Arrays.asList("javascript", "x-javascript", "ecmascript", "jscript")
                                           .stream().collect(Collectors.toSet()));
    }

    @Inject
    private Provider<ContainerRequest> containerRequestProvider;

    /***实现具体操作的函数****/
    @Override
    public void aroundWriteTo(final WriterInterceptorContext context) throws IOException, WebApplicationException {
        String callbackname = getCallbackName();

        if (callbackname!=null) {
            context.setMediaType(MediaType.APPLICATION_JSON_TYPE);
            context.getOutputStream().write(callbackname.getBytes(MessageUtils.getCharset(context.getMediaType())));
            context.getOutputStream().write('(');
        }
        //这里可以添加自己感兴趣的东西
        context.proceed();

        if (callbackname!=null) {
            context.getOutputStream().write(')');
        }
    }


    /**
     * Returns a JavaScript callback name to wrap the JSON entity into. The callback name is determined from the url
     * @return a JavaScript callback name.
     */
    private String getCallbackName() {
            final ContainerRequest containerRequest = containerRequestProvider.get();
            final UriInfo uriInfo = containerRequest.getUriInfo();
            final MultivaluedMap<String, String> queryParameters = uriInfo.getQueryParameters();
        if(queryParameters.get("jsoncallback")!=null)
            return queryParameters.getFirst("jsoncallback");
        return null;
    }

}

对源码改动不大,删除了点儿东西,功能也仅仅是进行了数据封装。
拦截器的代码完成,下一步需要在web.xml里注册。

<servlet>
        ……
    <init-param>
        <param-name>jersey.config.server.provider.classnames</param-name>
         <param-value>com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider, ***.JsonWithPaddingInterceptor</param-value>
     </init-param>
     <load-on-startup>1</load-on-startup>
</servlet>

<init-param>jersey.config.server.provider.classnames里已经有了一个provider,再把拦截器的类加进去就行了。

发布了110 篇原创文章 · 获赞 19 · 访问量 46万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章