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"}
相关推荐
Jabes.yang2 小时前
Java面试场景:从Spring Web到Kafka的音视频应用挑战
大数据·spring boot·kafka·spring security·java面试·spring webflux
程序员小凯4 小时前
Spring Boot性能优化详解
spring boot·后端·性能优化
tuine5 小时前
SpringBoot使用LocalDate接收参数解析问题
java·spring boot·后端
番茄Salad6 小时前
Spring Boot项目中Maven引入依赖常见报错问题解决
spring boot·后端·maven
摇滚侠6 小时前
Spring Boot 3零基础教程,yml配置文件,笔记13
spring boot·redis·笔记
!if7 小时前
springboot mybatisplus 配置SQL日志,但是没有日志输出
spring boot·sql·mybatis
阿挥的编程日记7 小时前
基于SpringBoot的影评管理系统
java·spring boot·后端
java坤坤7 小时前
Spring Boot 集成 SpringDoc OpenAPI(Swagger)实战:从配置到接口文档落地
java·spring boot·后端
摇滚侠8 小时前
Spring Boot 3零基础教程,整合Redis,笔记12
spring boot·redis·笔记
荣淘淘8 小时前
互联网大厂Java求职面试全景实战解析(涵盖Spring Boot、微服务及云原生技术)
java·spring boot·redis·jwt·cloud native·microservices·interview