spring boot 支持jsonp请求

spring boot 支持jsonp请求

项目中有用到 jsonp请求,那怎么使用spring boot 实现呢

实现

在不改动原有的框架基础上,对jsonp响应单独处理,即 实现 AbstractHttpMessageConverter:

java 复制代码
public class JsonpHttpMessageConverter extends AbstractHttpMessageConverter<Object> {

    private final ObjectMapper objectMapper;

    public JsonpHttpMessageConverter(ObjectMapper objectMapper) {
        super(new MediaType("application", "javascript", StandardCharsets.UTF_8));
        this.objectMapper = objectMapper;
    }

    @Override
    protected boolean supports(Class<?> clazz) {
        // 这里可以限制哪些类型的对象可以被序列化为 JSONP
        //响应的数据类型
        return JsonpController.DataM.class.isAssignableFrom(clazz);
    }

    @Override
    protected Object readInternal(Class<?> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
        throw new UnsupportedOperationException("Reading is not supported");
    }

    @Override
    protected void writeInternal(Object object, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
        HttpServletRequest currentHttpRequest = getCurrentHttpRequest();
        String jsonpCallback = currentHttpRequest.getParameter("callback");
        if (jsonpCallback == null || jsonpCallback.isEmpty()) {
            // 如果没有提供回调函数,则默认返回 JSON
            objectMapper.writeValue(outputMessage.getBody(), object);
        } else {
            // 获取请求参数中的 callback 参数值
            String callbackParam = jsonpCallback; // 实际应用中应该从请求对象中获取
            outputMessage.getBody().write((callbackParam + "(").getBytes(StandardCharsets.UTF_8));
            objectMapper.writeValue(outputMessage.getBody(), object);
            outputMessage.getBody().write(");".getBytes(StandardCharsets.UTF_8));
        }
    }

    public static HttpServletRequest getCurrentHttpRequest() {
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (servletRequestAttributes != null) {
            return servletRequestAttributes.getRequest();
        }
        return null; // 或者抛出异常,取决于你的需求
    }
}

加入配置

java 复制代码
@Configuration
public class WebConfig implements WebMvcConfigurer {

    private final ObjectMapper objectMapper;

    public WebConfig(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(0, new JsonpHttpMessageConverter(objectMapper));
    }
}

测试:

java 复制代码
@RestController
public class UserController {

    @GetMapping("/index")
    public UserDto index(){
        UserDto user = new UserDto();
        user.setStartTime(LocalDateTime.now());
        return user;
    }

    @GetMapping("/test/data")
    public JsonpController.DataM getData(@RequestParam(value = "callback", required = false) String callback,
                          HttpServletRequest request) throws IOException {
        JsonpController.DataM data = new JsonpController.DataM(); // 初始化你的数据对象
        data.setKey("a");
        data.setValue("b");
        return data;
    }
}

请求jsonp, http://localhost:8080/test/data?callback=callback:

bash 复制代码
# 响应类型为 text/plain
callback({"key":"a","value":"b"}

如果不带 callback:

bash 复制代码
# 响应类型为 text/plain
{"key":"a","value":"b"}
相关推荐
XMYX-01 小时前
Spring Boot + Prometheus 实现应用监控(基于 Actuator 和 Micrometer)
spring boot·后端·prometheus
@yanyu6663 小时前
springboot实现查询学生
java·spring boot·后端
酷爱码3 小时前
Spring Boot项目中JSON解析库的深度解析与应用实践
spring boot·后端·json
java干货4 小时前
虚拟线程与消息队列:Spring Boot 3.5 中异步架构的演进与选择
spring boot·后端·架构
武昌库里写JAVA7 小时前
iview Switch Tabs TabPane 使用提示Maximum call stack size exceeded堆栈溢出
java·开发语言·spring boot·学习·课程设计
小白杨树树7 小时前
【WebSocket】SpringBoot项目中使用WebSocket
spring boot·websocket·网络协议
clk660714 小时前
Spring Boot
java·spring boot·后端
爱敲代码的TOM14 小时前
基于JWT+SpringSecurity整合一个单点认证授权机制
spring boot