Gordian Yuan
Gordian Yuan

Reputation: 5040

Can spring mvc trim all strings obtained from forms?

I know struts2 default config will trim all strings obtained from forms.

For example:

I type

"   whatever "
in a form and submit, I will get
"whatever"
The string has been auto trimmed

Does spring mvc have this function too? THX.

Upvotes: 40

Views: 28905

Answers (6)

Jaille Chen
Jaille Chen

Reputation: 21

first,trim requestparam which is String,you can create a class and implimplements WebBingdingInitializer

 @ControllerAdvice
public class CustomWebBindingInitializer implements WebBindingInitializer {

    @InitBinder
    @Override
    public void initBinder(WebDataBinder webDataBinder, WebRequest webRequest) {
        webDataBinder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
    }
}

please use componentScan make this Class to be a Spring Bean.

But, I don't know how to trim the String value in requestBody JSON data.

Upvotes: 0

Sarvar Nishonboyev
Sarvar Nishonboyev

Reputation: 13090

Just customized the above code in order to adjust to Spring Boot, if you want to explicit trim function for some fields in the form, you can show them as below:

@Component
@ControllerAdvice
public class ControllerSetup {
    @InitBinder({"dto", "newUser"})
        public void initBinder(WebDataBinder binder) {
          binder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
          binder.registerCustomEditor(String.class, "userDto.username", new StringTrimmerEditor(false));
          binder.registerCustomEditor(String.class, "userDto.password", new DefaultStringEditor(false));
          binder.registerCustomEditor(String.class, "passwordConfirm", new DefaultStringEditor(false));
        }
}

Upvotes: 2

Janning Vygen
Janning Vygen

Reputation: 9192

Using Spring 3.2 or greater:

@ControllerAdvice
public class ControllerSetup
{
    @InitBinder
    public void initBinder ( WebDataBinder binder )
    {
        StringTrimmerEditor stringtrimmer = new StringTrimmerEditor(true);
        binder.registerCustomEditor(String.class, stringtrimmer);
    }
}

Testing with an MVC test context:

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration
public class ControllerSetupTest
{
    @Autowired
    private WebApplicationContext   wac;
    private MockMvc                 mockMvc;

    @Before
    public void setup ( )
    {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
    }

    @Test
    public void stringFormatting ( ) throws Exception
    {
        MockHttpServletRequestBuilder post = post("/test");
        // this should be trimmed, but only start and end of string
        post.param("test", "     Hallo  Welt   ");
        ResultActions result = mockMvc.perform(post);
        result.andExpect(view().name("Hallo  Welt"));
    }

    @Configuration
    @EnableWebMvc
    static class Config
    {
        @Bean
        TestController testController ( )
        {
            return new TestController();
        }

        @Bean
        ControllerSetup controllerSetup ( )
        {
            return new ControllerSetup();
        }
    }
}

/**
 * we are testing trimming of strings with it.
 * 
 * @author janning
 * 
 */
@Controller
class TestController
{
    @RequestMapping("/test")
    public String test ( String test )
    {
        return test;
    }
}

And - as asked by LppEdd - it works with passwords too as on the server side there is no difference between input[type=password] and input[type=text]

Upvotes: 52

Patrick
Patrick

Reputation: 3981

You can also use Spring's conversion service, which has the added benefit of working with <mvc:annotation-driven/> and with Spring Webflow. As with the other answers, the major downside is that this is a global change and can't be disabled for certain forms.

You'll need a converter to do the trimming

public class StringTrimmingConverter implements Converter<String, String> {

    @Override
    public String convert(String source) {
       return source.trim();
    }

}

Then define a conversion service that knows about your converter.

<bean id="applicationConversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
    <property name="converters">
    <list>
        <bean class="mypackage.util.StringTrimmingConverter"/>
    </list>
    </property>
</bean>

and tie that in to mvc.

<mvc:annotation-driven conversion-service="applicationConversionService"/>

If you use Spring Webflow then it require a wrapper

 <bean id="defaultConversionService" class="org.springframework.binding.convert.service.DefaultConversionService">
    <constructor-arg ref="applicationConversionService"/>
</bean>

and a setting on your flow builder

<flow:flow-builder-services id="flowBuilderServices" conversion-service="defaultConversionService" development="true"  validator="validator" />

Upvotes: 4

Lonre Wang
Lonre Wang

Reputation: 2265

register this property editor: org.springframework.beans.propertyeditors.StringTrimmerEditor

Example for AnnotionHandlerAdapter:

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
  ...
  <property name="webBindingInitializer">
    <bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
      <property name="propertyEditorRegistrar">
         <bean class="org.springframework.beans.propertyeditors.StringTrimmerEditor" />
      </property>
    </bean>
  </property>
  ...
</bean>

Upvotes: 11

Arthur Ronald
Arthur Ronald

Reputation: 33785

You can user a Spring-MVC Interceptor

public class TrimInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Enumeration<String> e = request.getParameterNames();
        while(e.hasMoreElements()) {
            String parameterName = e.nextElement();

            request.setParameter(parameterName, request.getParameter(parameterName).trim());
        }

        return true;
    }

And set up your HandlerMapping interceptors property

<bean id="interceptorTrim" class="br.com.view.interceptor.TrimInterceptor"/>
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" p:interceptors-ref="interceptorTrim"/>
}

Or use a Servlet Filter

Upvotes: 1

Related Questions