spring mvc 传入参数 String类型去掉空格

背景

在我们的工程中,要考虑到一些人工的上的错误,一个很常见的错误就是输入参数,前后都有空格,这个在进入controller 的时候,我们就应该去掉。技术背景为ssm框架。

1.考虑AOP

  • 在进入controller层的时候做一个切面,在切面的时候进行得到入参的类型,然后通过反射的思想,进行遍历对象里面的类型,如果是String类型的话,就trim操作重新赋值进去。
  • 问题1:如果入参本身就是String类型,就需要进行修改String类型里面的char[]value这个数组,不然无法设置进去。
  • 缺点:就是在使用反射的时候,如果对象里面还有对象,里面的对象的里面还有String类型的话,按理来说是要进行trim的,这样就是要进行递归操作,进行trim,对性能的代价很大。

2.重写DataBinder

  • Databinder 类型是spring mvc 里面进行入参绑定的类,里面有一个方法叫做getTarget()这个方法,是得到目标类型的,我们在工程进行覆写这个类的getTarget()方法,在通过tomcat加载类的顺序不同,让加载器优先加载我们的类,从而达到trim的操作。
  • 缺点:改动比较大,改了只有相当如每个参数都会走这个方法,但是有一些String是需要空格进行的,这样就造成了风险比较大。

3.StringTrimmerEditor + 重写ObjectMapper

  • 以上的方法都是有风险或者不足,其实spring mvc 提供了很多的扩展点。我们通过注册的方式就行。
  • MyStringTrimmerEditor

     @ControllerAdvice
    public class MyStringTrimmerEditor implements WebBindingInitializer {
    
        @InitBinder
        public void initBinder(WebDataBinder webDataBinder, WebRequest webRequest) {
            webDataBinder.registerCustomEditor(String.class,new StringTrimmerEditor(true));
        }
    }
  • 上面就是将spring的StringTrimmerEditor进行属性的绑定,StringTrimmerEditor是spring 实现的将String类型的值进行trim的editor类,但是默认为不添加的,但是我们现在可以添加,这样完成60%了。
  • 剩下40%
    • StringTrimmerEditor可以进行处理的是原始的HttpServletRequest里面的getParameter方法,但是如果为Body的内容,已流的形式进行转化的就不行了,最典型就是json格式。这个里面spring 默认的实现是MappingJackson2XmlHttp-MessageConverter进行实现的,而进行转化的是Jackson这个json转化的工具类型,我们只要实现自己的objectMapper来进行处理String的时候trim就行了。
@Component("customObjectMapper")
public class CustomObjectMapper extends ObjectMapper {

    public CustomObjectMapper() {
        CustomSerializerFactory  factory = new CustomSerializerFactory();
        factory.addGenericMapping(Date.class, new JsonSerializer<Date>() {
            @Override
            public void serialize(Date value, JsonGenerator jsonGenerator,
                                  SerializerProvider provider) throws IOException, JsonProcessingException {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                jsonGenerator.writeString(sdf.format(value));
            }
        });
        this.setSerializerFactory(factory);
    }
}

将这个进行注册到MappingJackson2XmlHttpMessageConverter类的objectMapper属性中就行。

测试

  • 测试是最重要的,使用的是mock controller 来进行实现的。
/**
 * Created by 黄建辉 on 2016/11/30.
 */
@RestController
@RequestMapping("/demo")
public class DemoController {

    @RequestMapping(value="/getGetData",method = RequestMethod.GET)
    public AttachAppQueryRequest returnData(AttachAppQueryRequest demo){
        return demo;
    }

    @RequestMapping(value="/getPostData",method = RequestMethod.POST)
    public AttachAppQueryRequest returnPostData(AttachAppQueryRequest demo){
        return demo;
    }

    @RequestMapping(value="/getJsonData",method = RequestMethod.POST)
    public AttachAppQueryRequest returnJsonData(@RequestBody AttachAppQueryRequest demo){
        return demo;
    }


    @RequestMapping(value="/getStringData",method = RequestMethod.POST)
    public String returnJsonData(String name){
        return name;
    }

}
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = Application.class)
public class StudentServiceImplTest {


    protected MockMvc mockMvc;

    @Autowired
    protected WebApplicationContext wac;

    @Before()
    public void setup() {
        mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();  //初始化MockMvc对象
    }


    @Test
    public void returnGetData() throws Exception {
        String responseString = mockMvc.perform(
                get("/demo/getGetData")
                        .contentType(MediaType.APPLICATION_FORM_URLENCODED)
                        .param("moduleCode","  root   ")
                        .param("dataCode"," code ")
                        .param("actionCode","11")
                        .param("actionType","12312")
        ).andExpect(status().isOk())    //返回的状态是200
                .andDo(print())         //打印出请求和相应的内容
                .andReturn().getResponse().getContentAsString();   //将相应的数据转换为字符串

        AttachAppQueryRequest request = JSON.parseObject(responseString,AttachAppQueryRequest.class);
        Assert.assertEquals("root",request.getModuleCode());
        Assert.assertEquals("code",request.getDataCode());

    }


    @Test
    public void returnPostData() throws Exception {
        String responseString = mockMvc.perform(
                post("/demo/getPostData")
                        .contentType(MediaType.APPLICATION_FORM_URLENCODED)
                        .param("moduleCode","  root   ")
                        .param("dataCode"," code ")
                        .param("actionCode","11")
                        .param("actionType","12312")
        ).andExpect(status().isOk())    //返回的状态是200
                .andDo(print())         //打印出请求和相应的内容
                .andReturn().getResponse().getContentAsString();   //将相应的数据转换为字符串

        AttachAppQueryRequest request = JSON.parseObject(responseString,AttachAppQueryRequest.class);
        Assert.assertEquals("root",request.getModuleCode());
        Assert.assertEquals("code",request.getDataCode());
    }

    @Test
    public void returnJsonData() throws Exception {

        AttachAppQueryRequest request = new AttachAppQueryRequest();
        request.setActionCode(1L);
        request.setModuleCode("  code ");
        request.setActionType(1);
        request.setDataCode("  dataCode ");

        String str = JSON.toJSONString(request);

        String responseString = mockMvc.perform(
                post("/demo/getJsonData")
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(str)
        ).andExpect(status().isOk())    //返回的状态是200
                .andDo(print())         //打印出请求和相应的内容
                .andReturn().getResponse().getContentAsString();   //将相应的数据转换为字符串
        request = JSON.parseObject(responseString,AttachAppQueryRequest.class);
        Assert.assertEquals("code",request.getModuleCode());
        Assert.assertEquals("dataCode",request.getDataCode());
    }

    @Test
    public void returnStringData() throws Exception {
        String responseString = mockMvc.perform(
                post("/demo/getStringData")
                        .contentType(MediaType.APPLICATION_FORM_URLENCODED)
                        .param("name","  root   ")
        ).andExpect(status().isOk())    //返回的状态是200
                .andDo(print())         //打印出请求和相应的内容
                .andReturn().getResponse().getContentAsString();   //将相应的数据转换为字符串

        Assert.assertEquals("root",responseString);

    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值