博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
RestEasy与Jsonp(ajax跨域)
阅读量:5246 次
发布时间:2019-06-14

本文共 10388 字,大约阅读时间需要 34 分钟。

1. ajax跨域的是利用了动态加载js文件没有跨域限制的特性。

2. 服务端返回jsonp格式的文本:xx({weather:"晴天",temp:"30C",:wind:"东南风"});

    这本质上是一个函数调用语句,实参为json对象,函数名为xx。

3. 客户端:利用jquery插件:jquery.jsonp-2.4.0.js

   代码:  

<script type="text/javascript">

  function xx(data)

  {
   alert(data);
   if(data)
             {
              var weatherStr = "今日天气:&nbsp;&nbsp;";
              weatherStr +=  data.weather + "&nbsp;&nbsp;";
              weatherStr +=  data.temp + "&nbsp;&nbsp;";
              weatherStr +=  data.wind + "<br/>";
     alert(weatherStr);
                 document.getElementById("weather_zone").innerHTML = weatherStr;
    }
  }

  function getCurrentDayWeather()
  {
   var currentDayWeatherUrl = "";

   $.jsonp({url: 'http://localhost:9090/httpapi/service/weather/detail/101190501.json?callback=xx'});

    
  }
  
  </script>

 

4. 服务端RestEasy的使用:

@Component("weatherService")

@Transactional
@Path("weather")
public class WeatherService
{
    @Autowired
    private WeatherDao weatherDao = null;
    
    public Weather queryById(String id)
    {
        Weather weather = weatherDao.get(id);
       
        return weather;
    }
   
    @GET
    @Path("/detail/{cityCode}.json")
    @Produces("application/json")
    public Weather getCurrentDayWeather(@PathParam("cityCode") String cityCode)
    {
        Weather weather = weatherDao.get(DateTimeUtil.getCurrentDay() + "_"
                + cityCode);
       
        if (null == weather || StringUtils.isEmpty(weather.getWeather()))
        {
            Weather emptyWeather = new Weather();
            emptyWeather.setWeatherId(DateTimeUtil.getCurrentDay() + "_"
                    + cityCode);
            emptyWeather.setWeather("暂无实况");
            emptyWeather.setTemp("暂无实况");
            emptyWeather.setWind("暂无实况");
           
            return emptyWeather;
        }
       
        return weather;
    }

    这个Rest接口只能返回 json,不能返回jsonp。

     RestEasy官方文档的21.2小结有几句话,基本是一句带过:

    

      

21.2. JSONP Support

If you're use Jackson  is supported right away. If the media type of the response is json and a callback query parameter is given, the response will be a javascript snippet with a method call of the method defined by the callback parameter. For example:

GET /resources/stuff?callback=processStuffResponse

will produce this response:

processStuffResponse(
)

This supports the default behavior of .

You can change the name of the callback parameter by setting the callbackQueryParameter property.

 

我用了Jackson ,可是总返回不了jsonp,老是返回json。

后来google到了老外的帖子(),

发现可能是我的RestEasy版本低的问题,我的是2.3.3,说高版本的支持的,我懒得换高版本,于是把那个帖子中老外DIY的代码拿来用了:

思路是自己建个Filter,Wrap HttpServletRequest和HttpSerletResponse,自己把返回的json转成jsonp。

代码如下:

I make draft workaround for this problem. Try it. This solution takes data via http get parameters and translate to virtual POST request.

JQuery:

function call(){
var val ='{"routes":[{"arrivalAddress":{"fullAddress":"DME"},"destinationAddress":{"fullAddress":"SVO"}}],"carsCount":"1"}';var jHandler ="doMap";$.getJSON("http://xxx:yyy/app-0.0.0.1/rest/requestPrice?callback="+ jHandler +"&json="+ encodeURIComponent(val)+"&jsoncallback=?",null,null,"json");}function doMap(obj){
alert(obj);}

Declaration in Service interface

@POST @Path("requestPrice") @Produces("application/json") @Consumes("application/json") PriceResponse requestPrice(PriceRequest request)throwsServiceException;

Filter class:

import javax.servlet.*;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletRequestWrapper;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpServletResponseWrapper;import java.io.*;import java.util.Enumeration;import java.util.HashMap;import java.util.Iterator;import java.util.Map;publicclassJSONPRequestFilterimplementsFilter{
privateString callbackParameter;publicvoid doFilter(ServletRequest request,ServletResponse response,FilterChain chain)throwsIOException,ServletException{
if(!(request instanceofHttpServletRequest)){
thrownewServletException("This filter can "+" only process HttpServletRequest requests");}finalHttpServletRequest httpRequest =(HttpServletRequest) request;finalHttpServletResponse httpResponse =(HttpServletResponse) response;if(isJSONPRequest(httpRequest)){
RequestWrapper requestWrapper =newRequestWrapper(httpRequest); requestWrapper.setContentType("application/json; charset=UTF-8"); requestWrapper.setHeader("cache-control","no-cache"); requestWrapper.setHeader("accept","application/json"); requestWrapper.setCharacterEncoding("UTF-8"); requestWrapper.setBody(httpRequest.getParameter("json"));finalByteArrayOutputStream baos =newByteArrayOutputStream();HttpServletResponseWrapper responseWrapper =newHttpServletResponseWrapper(httpResponse){
@OverridepublicServletOutputStream getOutputStream()throwsIOException{
returnnewServletOutputStream(){
@Overridepublicvoid write(int b)throwsIOException{
baos.write(b);}};}@OverridepublicPrintWriter getWriter()throwsIOException{
returnnewPrintWriter(baos);}publicString getData(){
return baos.toString();}}; chain.doFilter(requestWrapper, responseWrapper); response.getOutputStream().write((getCallbackParameter(httpRequest)+"(").getBytes()); response.getOutputStream().write(baos.toByteArray()); response.getOutputStream().write(");".getBytes()); response.setContentType("text/javascript");}else{
chain.doFilter(request, response);}}privateString getCallbackMethod(HttpServletRequest httpRequest){
return httpRequest.getParameter(callbackParameter);}privateboolean isJSONPRequest(HttpServletRequest httpRequest){
String callbackMethod = getCallbackMethod(httpRequest);return(callbackMethod !=null&& callbackMethod.length()>0);}privateString getCallbackParameter(HttpServletRequest request){
return request.getParameter(callbackParameter);}publicvoid init(FilterConfig filterConfig)throwsServletException{
callbackParameter = filterConfig.getInitParameter("callbackParameter");}publicvoid destroy(){
}void printRequest(HttpServletRequest request)throwsIOException{
{
System.out.println("--------------Headers---------------");Enumeration en = request.getHeaderNames();while(en.hasMoreElements()){
String val = en.nextElement().toString();System.out.println(val +" :");Enumeration en1 = request.getHeaders(val);while(en1.hasMoreElements()){
System.out.println("\t"+ en1.nextElement());}}}{
System.out.println("------------Parameters--------------");Enumeration en = request.getParameterNames();while(en.hasMoreElements()){
String val = en.nextElement().toString();System.out.println(val +" :");String[] en1 = request.getParameterValues(val);for(String val1 : en1){
System.out.println("\t"+ val1);}}}System.out.println("---------------BODY--------------");BufferedReader is = request.getReader();String line;while((line = is.readLine())!=null){
System.out.println(line);}System.out.println("---------------------------------");System.out.println("ContentType: "+ request.getContentType());System.out.println("ContentLength: "+ request.getContentLength());System.out.println("characterEncodings: "+ request.getCharacterEncoding());System.out.println("AuthType: "+ request.getAuthType());System.out.println("ContextPath: "+ request.getContextPath());System.out.println("Method: "+ request.getMethod());}publicstaticclassRequestWrapperextendsHttpServletRequestWrapper{
Map
headers =newHashMap
();int contentLength;BufferedReader reader;publicRequestWrapper(HttpServletRequest request){
super(request);}publicvoid setHeader(String key,String value){
headers.put(key, value);}ByteArrayInputStream bais;publicvoid setBody(String body){
bais =newByteArrayInputStream(body.getBytes()); contentLength = body.length(); headers.put("content-length",Integer.toString(contentLength));}@OverridepublicBufferedReader getReader()throwsIOException{
reader =newBufferedReader(newInputStreamReader(bais));return reader;}@OverridepublicServletInputStream getInputStream()throwsIOException{
returnnewServletInputStream(){
@Overridepublicint read()throwsIOException{
return bais.read();}};}@OverridepublicString getMethod(){
return"POST";}privateString contentType;publicvoid setContentType(String contentType){
this.contentType = contentType; headers.put("content-type", contentType);}@OverridepublicString getContentType(){
return contentType;}@Overridepublicint getContentLength(){
return contentLength;}@OverridepublicString getHeader(String name){
String val = headers.get(name);if(val !=null){
return val;}returnsuper.getHeader(name);//To change body of overridden methods use File | Settings | File Templates.}@OverridepublicEnumeration getHeaders(finalString name){
returnsuper.getHeaders(name);}@OverridepublicEnumeration getHeaderNames(){
finalEnumeration en1 =super.getHeaderNames();finalIterator it = headers.keySet().iterator();returnnewEnumeration(){
publicboolean hasMoreElements(){
return en1.hasMoreElements()|| it.hasNext();}publicObject nextElement(){
return en1.hasMoreElements()? en1.nextElement():(it.hasNext()? it.next():null);}};}@Overridepublicint getIntHeader(String name){
String val = headers.get(name);if(val ==null){
returnsuper.getIntHeader(name);}else{
returnInteger.parseInt(val);}}}}

web.xml

JSONPRequestFilter
xxxxx.JSONPRequestFilter
callbackParameter
callback
JSONPRequestFilter
/rest/*
|
 
   

1

An enhancement to support JSONP is scheduled to be released in RESTEasy 2.3.6 Final/3.0-beta-4 (). I was able to "backport" it my project which uses RESTEasy 2.3.5 by simply copying .

RESTEasy automatically picks up the new provider based on the annotation. It works automatically by wrapping your results in a js callback once it sees a query parameter named "callback" in the url. This is compatible with what JQuery sends to the server for JSONP requests.

 

转载于:https://www.cnblogs.com/ursa/archive/2013/06/14/3135232.html

你可能感兴趣的文章
选择排序算法
查看>>
<JZOJ4726>种花
查看>>
【GMT43智能液晶模块】例程八:ADC实验——电源监控
查看>>
BZOJ1014:[JSOI2008]火星人prefix
查看>>
红外遥控 Arduino 实例
查看>>
Requests:Python HTTP Module学习笔记(二)(转)
查看>>
剑指:顺时针打印矩阵
查看>>
05_Dockerfile实战(上)
查看>>
Java项目配置log4j日志的级别
查看>>
install java 7 or 8 on Ubuntu
查看>>
http响应状态码大全
查看>>
表达式求值(二叉树方法/C++语言描述)(三)
查看>>
jQuery.imgLazyLoad图片懒加载组件
查看>>
[LeetCode] 215. Kth Largest Element in an Array 数组中第k大的元素
查看>>
POJ - 3468 A Simple Problem with Integers(线段树区间更新,区间查询)
查看>>
常用算法模板
查看>>
JS入门五
查看>>
s3存储桶:s3可扩展的云存储
查看>>
如何解决秒杀的性能问题和超卖的讨论 及防止按钮多次点击
查看>>
3.4PCL中异常处理机制
查看>>