服务器后端接收前端传来的字符串带空格,如下

springboot/spring/springmvc 中前台传来的string字符串自动去除前后面的空格_html

 

 现在在后端接收时需要把字符串前后的空格去除掉。

解决办法

 

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;
}
}

 

最终在服务端接收到数据如下:

springboot/spring/springmvc 中前台传来的string字符串自动去除前后面的空格_javascript_02

 

 

 

其他参考

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​