Skip to content

Instantly share code, notes, and snippets.

@codethereforam
Created December 20, 2018 03:05
Show Gist options
  • Save codethereforam/cae4546827873b2a55f940ce7783697b to your computer and use it in GitHub Desktop.
Save codethereforam/cae4546827873b2a55f940ce7783697b to your computer and use it in GitHub Desktop.
配置SpringMVC使用fastjson
/**
* Spring MVC {@link View} that renders JSON content by serializing the model for the current request
* using fastjson.
*
* <p>By default, the entire contents of the model map (with the exception of framework-specific classes)
* will be encoded as JSON. If the model contains only one key, you can have it extracted encoded as JSON
* alone via {@link #setExtractValueFromSingleKeyModel}.
*
* @author yanganyu
* @date 2018/10/15 15:48
*/
public class MappingFastjson2JsonView extends AbstractView {
/**
* Default content type: "application/json".
* Overridable through {@link #setContentType}.
*/
public static final String DEFAULT_CONTENT_TYPE = "application/json";
private JsonEncoding encoding = JsonEncoding.UTF8;
private boolean disableCaching = true;
/**
* Default content type for JSONP: "application/javascript".
*
* @deprecated Will be removed as of Spring Framework 5.1, use
* <a href="https://docs.spring.io/spring/docs/5.0.x/spring-framework-reference/web.html#mvc-cors">CORS</a> instead.
*/
@Deprecated
public static final String DEFAULT_JSONP_CONTENT_TYPE = "application/javascript";
/**
* Pattern for validating jsonp callback parameter values.
*/
private static final Pattern CALLBACK_PARAM_PATTERN = Pattern.compile("[0-9A-Za-z_\\.]*");
@Nullable
private Set<String> modelKeys;
private boolean extractValueFromSingleKeyModel = false;
@Nullable
private Set<String> jsonpParameterNames = new LinkedHashSet<>();
public MappingFastjson2JsonView() {
setContentType(DEFAULT_CONTENT_TYPE);
setExposePathVariables(false);
}
/**
* Set the {@code JsonEncoding} for this view.
* By default, {@linkplain JsonEncoding#UTF8 UTF-8} is used.
*/
public void setEncoding(JsonEncoding encoding) {
Assert.notNull(encoding, "'encoding' must not be null");
this.encoding = encoding;
}
/**
* Return the {@code JsonEncoding} for this view.
*/
public final JsonEncoding getEncoding() {
return this.encoding;
}
/**
* Disables caching of the generated JSON.
* <p>Default is {@code true}, which will prevent the client from caching the generated JSON.
*/
public void setDisableCaching(boolean disableCaching) {
this.disableCaching = disableCaching;
}
/**
* Set whether to serialize models containing a single attribute as a map or
* whether to extract the single value from the model and serialize it directly.
* <p>The effect of setting this flag is similar to using
* {@code MappingJackson2HttpMessageConverter} with an {@code @ResponseBody}
* request-handling method.
* <p>Default is {@code false}.
*/
public void setExtractValueFromSingleKeyModel(boolean extractValueFromSingleKeyModel) {
this.extractValueFromSingleKeyModel = extractValueFromSingleKeyModel;
}
@Override
protected void prepareResponse(HttpServletRequest request, HttpServletResponse response) {
setResponseContentType(request, response);
response.setCharacterEncoding(this.encoding.getJavaName());
if (this.disableCaching) {
response.addHeader("Pragma", "no-cache");
response.addHeader("Cache-Control", "no-cache, no-store, max-age=0");
response.addDateHeader("Expires", 1L);
}
}
/**
* {@inheritDoc}
*/
public void setModelKey(String modelKey) {
this.modelKeys = Collections.singleton(modelKey);
}
/**
* Set the attributes in the model that should be rendered by this view.
* When set, all other model attributes will be ignored.
*/
public void setModelKeys(@Nullable Set<String> modelKeys) {
this.modelKeys = modelKeys;
}
/**
* Return the attributes in the model that should be rendered by this view.
*/
@Nullable
public final Set<String> getModelKeys() {
return this.modelKeys;
}
/**
* Set JSONP request parameter names. Each time a request has one of those
* parameters, the resulting JSON will be wrapped into a function named as
* specified by the JSONP request parameter value.
* <p>As of Spring Framework 5.0.7, there is no parameter name configured
* by default.
*
* @see <a href="http://en.wikipedia.org/wiki/JSONP">JSONP Wikipedia article</a>
* @since 4.1
* @deprecated Will be removed as of Spring Framework 5.1, use
* <a href="https://docs.spring.io/spring/docs/5.0.x/spring-framework-reference/web.html#mvc-cors">CORS</a> instead.
*/
@Deprecated
public void setJsonpParameterNames(Set<String> jsonpParameterNames) {
this.jsonpParameterNames = jsonpParameterNames;
}
@Nullable
private String getJsonpParameterValue(HttpServletRequest request) {
if (this.jsonpParameterNames != null) {
for (String name : this.jsonpParameterNames) {
String value = request.getParameter(name);
if (StringUtils.isEmpty(value)) {
continue;
}
if (!isValidJsonpQueryParam(value)) {
if (logger.isDebugEnabled()) {
logger.debug("Ignoring invalid jsonp parameter value: " + value);
}
continue;
}
return value;
}
}
return null;
}
/**
* 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}
* @since 4.1.8
* @deprecated Will be removed as of Spring Framework 5.1, use
* <a href="https://docs.spring.io/spring/docs/5.0.x/spring-framework-reference/web.html#mvc-cors">CORS</a> instead.
*/
@Deprecated
protected boolean isValidJsonpQueryParam(String value) {
return CALLBACK_PARAM_PATTERN.matcher(value).matches();
}
/**
* Filter out undesired attributes from the given model.
* The return value can be either another {@link Map} or a single value object.
* <p>The default implementation removes {@link BindingResult} instances and entries
* not included in the {@link #setModelKeys modelKeys} property.
*
* @param model the model, as passed on to {@link #renderMergedOutputModel}
* @return the value to be rendered
*/
protected Object filterModel(Map<String, Object> model) {
Map<String, Object> result = new HashMap<>(model.size());
Set<String> modelKeys = (!CollectionUtils.isEmpty(this.modelKeys) ? this.modelKeys : model.keySet());
model.forEach((clazz, value) -> {
if (!(value instanceof BindingResult) && modelKeys.contains(clazz)) {
result.put(clazz, value);
}
});
return (this.extractValueFromSingleKeyModel && result.size() == 1 ? result.values().iterator().next() : result);
}
@Override
protected void setResponseContentType(HttpServletRequest request, HttpServletResponse response) {
if (getJsonpParameterValue(request) != null) {
response.setContentType(DEFAULT_JSONP_CONTENT_TYPE);
} else {
super.setResponseContentType(request, response);
}
}
@Override
protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
Object value = filterModel(model);
response.getWriter().write(JSONObject.toJSONString(value));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment