服务器后端接收前端传来的字符串带空格,如下
现在在后端接收时需要把字符串前后的空格去除掉。
解决办法
import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; import com.xxx.convertor.StringWithoutSpaceDeserializer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import java.util.List; @Configuration public class HttpMessageConvertor implements WebMvcConfigurer { @Autowired private ObjectMapper mapper; @Override public void extendMessageConverters(List<HttpMessageConverter<?>> converters) { converters.add(mappingJackson2HttpMessageConverter()); } @Bean public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() { MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); SimpleModule module = new SimpleModule(); module.addDeserializer(String.class, new StringWithoutSpaceDeserializer(String.class)); mapper.registerModule(module); converter.setObjectMapper(mapper); return converter; } }
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import java.io.IOException; public class StringWithoutSpaceDeserializer extends StdDeserializer<String> { private static final long serialVersionUID = -6972065572263950443L; public StringWithoutSpaceDeserializer(Class<String> vc) { super(vc); } @Override public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { return p.getText() != null ? p.getText().trim() : null; } }
最终在服务端接收到数据如下:
其他参考
import com.xxx.util.security.StringEscapeEditor; import org.springframework.beans.propertyeditors.CustomDateEditor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.format.support.DefaultFormattingConversionService; import org.springframework.format.support.FormattingConversionService; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.support.ConfigurableWebBindingInitializer; import java.text.SimpleDateFormat; import java.util.Date; /** * 自定义Web绑定初始化器 * @see org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport 的getConfigurableWebBindingInitializer方法 */ @Configuration @ControllerAdvice public class WebBindingInitializerConfiguration { // final ConfigurableWebBindingInitializer initializer = new ConfigurableWebBindingInitializer(); // final FormattingConversionService conversionService = new DefaultFormattingConversionService(); // @Bean // public ConfigurableWebBindingInitializer configurableWebBindingInitializer(FormattingConversionService conversionService, Validator mvcValidator) { // ConfigurableWebBindingInitializer initializer = new ConfigurableWebBindingInitializer(); // initializer.setConversionService(conversionService); // initializer.setValidator(mvcValidator); // //装配自定义属性编辑器 // initializer.setPropertyEditorRegistrar(propertyEditorRegistry -> { // //PropertyEditors并不是线程安全的,对于每一个请求,我们都需要new一个PropertyEditor对象 // propertyEditorRegistry.registerCustomEditor(String.class, new StringEscapeEditor()); // propertyEditorRegistry.registerCustomEditor(Date.class, new DateEditor()); // }); // return initializer; // } @Bean public ConfigurableWebBindingInitializer getConfigurableWebBindingInitializer() { ConfigurableWebBindingInitializer initializer = new ConfigurableWebBindingInitializer(); FormattingConversionService conversionService = new DefaultFormattingConversionService(); //we can add our custom converters and formatters //conversionService.addConverter(...); //conversionService.addFormatter(...); initializer.setConversionService(conversionService); //we can set our custom validator //initializer.setValidator(....); //here we are setting a custom PropertyEditor initializer.setPropertyEditorRegistrar(propertyEditorRegistry -> { SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd"); propertyEditorRegistry.registerCustomEditor(Date.class, new CustomDateEditor(dateFormatter, true)); propertyEditorRegistry.registerCustomEditor(String.class, new StringEscapeEditor()); }); return initializer; } }
import org.springframework.web.util.HtmlUtils; import org.springframework.web.util.JavaScriptUtils; import java.beans.PropertyEditorSupport; import java.util.Objects; /** * * @description 与spring mvc的@InitBinder结合 用于防止XSS攻击 */ public class StringEscapeEditor extends PropertyEditorSupport { /** 转义HTML */ private boolean escapeHTML; /** 转义javascript */ private boolean escapeJavaScript; /** 是否将空字符串转换为null */ private final boolean emptyAsNull; /** 是否去掉前后空格 */ private final boolean trimmed; public StringEscapeEditor() { this(true,true,false,false); } public StringEscapeEditor(boolean escapeHTML, boolean escapeJavaScript) { this(true,true,escapeHTML,escapeJavaScript); } public StringEscapeEditor(boolean emptyAsNull,boolean trimmed, boolean escapeHTML, boolean escapeJavaScript) { super(); this.emptyAsNull = emptyAsNull; this.trimmed = trimmed; this.escapeHTML = escapeHTML; this.escapeJavaScript = escapeJavaScript; } @Override public String getAsText() { Object value = getValue(); if(Objects.nonNull(value)) { return value.toString(); } return value != null ? value.toString() : null; } @Override public void setAsText(String text) throws IllegalArgumentException { String value = text; if (value == null || emptyAsNull && text.isEmpty()) { //do nothing } else if (trimmed) { value = value.trim(); } if (escapeHTML) { //HTML转义(防止XSS攻击) //HtmlUtils.htmlEscape 默认的是ISO-8859-1编码格式,会将中文的某些符号进行转义。 //如果不想让中文符号进行转义请使用UTF-8的编码格式。例如:HtmlUtils.htmlEscape(text, "UTF-8") value = HtmlUtils.htmlEscape(value); } if (escapeJavaScript) { //HTML转义(防止XSS攻击) //HtmlUtils.htmlEscape 默认的是ISO-8859-1编码格式,会将中文的某些符号进行转义。 //如果不想让中文符号进行转义请使用UTF-8的编码格式。例如:HtmlUtils.htmlEscape(text.trim(), "UTF-8") value = JavaScriptUtils.javaScriptEscape(value); } setValue(value); } }
参考来源:
https://stackoverflow.com/questions/39853350/spring-initbinder-register-multiple-custom-editor-string-class/39869054#39869054
https://stackoverflow.com/questions/42362490/how-to-auto-trim-strings-of-bean-object-in-spring-with-restful-api
https://stackoverflow.com/questions/25403676/initbinder-with-requestbody-escaping-xss-in-spring-3-2-4
https://stackoverflow.com/questions/57090437/spring-mvc-stringtrimmereditor-not-working
https://stackoverflow.com/questions/57134262/spring-stringtrimmereditor-not-trimming-the-whitespaces
https://stackoverflow.com/questions/25403676/initbinder-with-requestbody-escaping-xss-in-spring-3-2-4/25405385#25405385
https://stackoverflow.com/questions/50297719/using-initbinder-with-command-objects