All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.alibaba.fastjson.support.spring.FastJsonpResponseBodyAdvice Maven / Gradle / Ivy

There is a newer version: 3.2.26
Show newest version
package com.alibaba.fastjson.support.spring;

import org.springframework.core.MethodParameter;
import org.springframework.core.annotation.Order;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import javax.servlet.http.HttpServletRequest;
import java.util.regex.Pattern;

/**
 * A convenient base class for {@code ResponseBodyAdvice} implementations
 * that customize the response before JSON serialization with {@link FastJsonpHttpMessageConverter4}'s concrete
 * subclasses.
 * 

* Compatible Spring MVC version 4.2+ * * @author Jerry.Chen * @see JSONPResponseBodyAdvice * @since 1.2.20 */ @Deprecated @Order(Integer.MIN_VALUE) //before FastJsonViewResponseBodyAdvice @ControllerAdvice public class FastJsonpResponseBodyAdvice implements ResponseBodyAdvice { /** * Pattern for validating jsonp callback parameter values. */ private static final Pattern CALLBACK_PARAM_PATTERN = Pattern.compile("[0-9A-Za-z_\\.]*"); private final String[] jsonpQueryParamNames; /** * Default JSONP query param names: callback/jsonp */ public static final String[] DEFAULT_JSONP_QUERY_PARAM_NAMES = {"callback", "jsonp"}; public FastJsonpResponseBodyAdvice() { this.jsonpQueryParamNames = DEFAULT_JSONP_QUERY_PARAM_NAMES; } public FastJsonpResponseBodyAdvice(String... queryParamNames) { Assert.isTrue(!ObjectUtils.isEmpty(queryParamNames), "At least one query param name is required"); this.jsonpQueryParamNames = queryParamNames; } public boolean supports(MethodParameter returnType, Class> converterType) { return FastJsonHttpMessageConverter.class.isAssignableFrom(converterType); } public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { MappingFastJsonValue container = getOrCreateContainer(body); beforeBodyWriteInternal(container, selectedContentType, returnType, request, response); return container; } /** * Wrap the body in a {@link MappingFastJsonValue} value container (for providing * additional serialization instructions) or simply cast it if already wrapped. */ protected MappingFastJsonValue getOrCreateContainer(Object body) { return (body instanceof MappingFastJsonValue ? (MappingFastJsonValue) body : new MappingFastJsonValue(body)); } /** * Invoked only if the converter type is {@code FastJsonpHttpMessageConverter4}. */ public void beforeBodyWriteInternal(MappingFastJsonValue bodyContainer, MediaType contentType, MethodParameter returnType, ServerHttpRequest request, ServerHttpResponse response) { HttpServletRequest servletRequest = ((ServletServerHttpRequest) request).getServletRequest(); for (String name : this.jsonpQueryParamNames) { String value = servletRequest.getParameter(name); if (value != null) { if (!isValidJsonpQueryParam(value)) { continue; } // MediaType contentTypeToUse = getContentType(contentType, request, response); // response.getHeaders().setContentType(contentTypeToUse); bodyContainer.setJsonpFunction(value); break; } } } /** * Validate the jsonp query parameter value. The default implementation * returns true if it consists of digits, letters, or "_" and ".". * Invalid parameter values are ignored. * * @param value the query param value, never {@code null} */ protected boolean isValidJsonpQueryParam(String value) { return CALLBACK_PARAM_PATTERN.matcher(value).matches(); } /** * Return the content type to set the response to. * This implementation always returns "application/javascript". * * @param contentType the content type selected through content negotiation * @param request the current request * @param response the current response * @return the content type to set the response to */ protected MediaType getContentType(MediaType contentType, ServerHttpRequest request, ServerHttpResponse response) { return new MediaType("application", "javascript"); } }