SpringBoot跨域请求支持JSONP


前言

文章主要会对SpringMVC4.1版本提供的AbstractJsonpResponseBodyAdvice类,以及高版本SpringMVC弃用该类后如何继续支持JSONP数据跨域方式


一、SpringBoot跨域请求支持JSONP

项目中有可能会遇到跨域请求,所以需要组装支持跨域请求的JSONP数据,在SpringMVC 4.1版本中为我们提供了AbstractJsonpResponseBodyAdvice 类来支持跨域请求。由于使用JSONP数据方式是不安全的spingboot2.0开始已经不推荐了, Spring 5.07 和4.3.18开始已经弃用AbstractJsonpResponseBodyAdvice,在版本5.1中被完全移除,并且建议使用Cross-Origin方式来支持(文章这里就不展开)。这里主要对于AbstractJsonpResponseBodyAdvice 方式如何使用以及高版本弃用后旧的项目如何继续支持展开。

1.AbstractJsonpResponseBodyAdvice 类支持JSONP

代码如下(示例):

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.AbstractJsonpResponseBodyAdvice;
import com.alone.jpa.controller.UserController;
//只对UserController生效
@ControllerAdvice(basePackageClasses = {
    
    UserController.class})
public class JsonpAdvice extends AbstractJsonpResponseBodyAdvice {
    
    
    public JsonpAdvice() {
    
    
        super("callback");
    }
}

2. 实现ResponseBodyAdvice 类方式

代码如下(示例):

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONPObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alone.jpa.controller.UserController;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.regex.Pattern;
//只对UserController生效
@ControllerAdvice(basePackageClasses = {
    
    UserController.class})
public class Jsonp implements ResponseBodyAdvice {
    
    

    private static final Pattern CALLBACK_PARAM_PATTERN = Pattern.compile("[0-9A-Za-z_\\.]*");

    @Override
    public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
    
    

        HttpServletRequest servletRequest = ((ServletServerHttpRequest) serverHttpRequest).getServletRequest();
        HttpServletResponse response = ((ServletServerHttpResponse) serverHttpResponse).getServletResponse();
        String value = servletRequest.getParameter("callback");
        if (value != null) {
    
    
            if (this.isValidJsonpQueryParam(value)) {
    
    
                JSONPObject jsonp = new JSONPObject(value);
                String text = JSON.toJSONString(o, new SerializerFeature[0]);
                String jsonpText = new StringBuilder(jsonp.getFunction()).append("(").append(text).append(")").toString();
                byte[] bytes = jsonpText.getBytes(Charset.forName("UTF-8"));
                OutputStream out = null;
                try {
    
    
                    out = response.getOutputStream();
                    out.write(bytes);
                    out.flush();
                    out.close();
                } catch (IOException e) {
    
    
					e.printStackTrace();
                }
            }
        }
        return o;
    }

    @Override
    public boolean supports(MethodParameter methodParameter, Class aClass) {
    
    
        return true;
    }

    protected boolean isValidJsonpQueryParam(String value) {
    
    
        return CALLBACK_PARAM_PATTERN.matcher(value).matches();
    }
}

2.1.普通请求

请求:

http://localhost:8080/alone-server/user/get?userNumber=1

返回结果:

{
    
    "id":1,"userNumber":1,"nickName":"nick","sex":0,"avatar":null,"mobile":"","email":""}

2.2.跨域请求

请求:

http://localhost:8080/alone-server/user/get?userNumber=1&callback=jsonp_00011100123456789874

返回结果:

jsonp_00011100123456789874({
    
    "email":"","id":1,"mobile":"","nickName":"nick","sex":0,"userNumber":1})

猜你喜欢

转载自blog.csdn.net/qq_38531706/article/details/113757975