spring boot 支持jsonp请求
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;
}
@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; // 或者抛出异常,取决于你的需求
}
}
加入配置
@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));
}
}
测试:
@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"}