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

来源:互联网 发布:js中如何遍历json数组 编辑:程序博客网 时间:2024/06/13 12:19

上一篇我们提到了使用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.Providerpublic 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,再把拦截器的类加进去就行了。

0 0