spring boot 支持jsonp请求
项目中有用到 jsonp请求,那怎么使用spring boot 实现呢
实现
在不改动原有的框架基础上,对jsonp响应单独处理,即 实现 AbstractHttpMessageConverter
:
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;}@Overrideprotected boolean supports(Class<?> clazz) {// 这里可以限制哪些类型的对象可以被序列化为 JSONP//响应的数据类型return JsonpController.DataM.class.isAssignableFrom(clazz);}@Overrideprotected Object readInternal(Class<?> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {throw new UnsupportedOperationException("Reading is not supported");}@Overrideprotected void writeInternal(Object object, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {HttpServletRequest currentHttpRequest = getCurrentHttpRequest();String jsonpCallback = currentHttpRequest.getParameter("callback");if (jsonpCallback == null || jsonpCallback.isEmpty()) {// 如果没有提供回调函数,则默认返回 JSONobjectMapper.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; // 或者抛出异常,取决于你的需求}
}
加入配置
@Configuration
public class WebConfig implements WebMvcConfigurer {private final ObjectMapper objectMapper;public WebConfig(ObjectMapper objectMapper) {this.objectMapper = objectMapper;}@Overridepublic void extendMessageConverters(List<HttpMessageConverter<?>> converters) {converters.add(0, new JsonpHttpMessageConverter(objectMapper));}
}
测试:
@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
:
# 响应类型为 text/plain
callback({"key":"a","value":"b"}
如果不带 callback:
# 响应类型为 text/plain
{"key":"a","value":"b"}