How to prevent parameter binding from interpreting commas in Spring 3.0.5?

Consider the following controller method:

@RequestMapping(value = "/test", method = RequestMethod.GET) public void test(@RequestParam(value = "fq", required = false) String[] filterQuery) { logger.debug(fq = " + StringUtils.join(filterQuery, "|")); }

Here is the output for different fq combinations:

  1. /test?fq=foo results in fq = foo
  2. /test?fq=foo&fq=bar results in fq = foo|bar
  3. /test?fq=foo,bar results in fq = foo|bar
  4. /test?fq=foo,bar&fq=bash results in fq = foo,bar|bash
  5. /test?fq=foo,bar&fq= results in fq = foo,bar|

Example 3 is the problem. I expect (want/need) it to output fq = foo,bar.

I've tried escaping the comma with \ and using %3C but niether work.

If I look at the HttpServletRequest object's version:

String[] fqs = request.getParameterValues("fq"); logger.debug(fqs = " + StringUtils.join(fqs, "|"));

It prints the expected output: fqs = foo,bar. So the "problem" is with the Spring data binding.

I could by-pass Spring's binding and use HttpServletRequest but I really don't want to as I'm using a backing bean in my real code (same thing is happening) and don't wish to re-implement the binding functionality. I'm hoping someone can provide a simple way of preventing this behavior via escaping or some other mechanism.

TIA

UPDATE: I posted this Q on Twitter and got a reply saying the expected output appears with Spring 3.0.4.RELEASE. I've now confirmed this is the case and thus is a temporary fix. I'll go ahead and log this as a bug on the Spring JIRA system. If anyone can provide a work around or fix with 3.0.5, I'll accept their answer.

-------------Problems Reply------------

I've tested your code: it's unbelievable, but I can't reproduce your issue. I've downloaded the latest version of spring (3.0.5), this is my controller:

package test;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@RequestMapping("/test/**")
public class MyController {

private static final Logger logger = Logger.getLogger(MyController.class);

@RequestMapping(value = "/test/params", method = RequestMethod.GET)
public void test(SearchRequestParams requestParams, BindingResult result) {
logger.debug("fq = " + StringUtils.join(requestParams.getFq(), "|"));
}
}

this is my SearchRequestParams class:

package test;

public class SearchRequestParams {
private String[] fq;

public String[] getFq() {
return fq;
}

public void setFq(String[] fq) {
this.fq = fq;
}
}

and this is my simple spring configuration:

<bean id="urlMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />

<bean class="test.MyController" />

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>

I've tested my code within tomcat 7.0.8; when I type http://localhost:8080/testweb/test/params.htm?fq=foo,bar I'm able to read in my log file this line: DEBUG fq = foo,bar. What are the the differences from my code to yours? Am I doing something wrong? I'd like to help you, so if you have any doubts or if I can do some other tests for you, it will be a pleasure.

UPDATE / SOLUTION
With your code I've reproduced the issue; you have the tag <mvc:annotation-driven /> in your dispatcher servlet configuration, so you silently use a default conversion service, instance of FormattingConversionService, which contains a default converter from String to String[] that uses comma as separator. You have to use a different conversion service bean containing your own converter from String to String[]. You should use a different separator, I've choosed to use ";" because it's the separator commonly used into query string ("?first=1;second=2;third=3"):

import org.springframework.core.convert.converter.Converter;
import org.springframework.util.StringUtils;

public class CustomStringToArrayConverter implements Converter<String, String[]>{
@Override
public String[] convert(String source) {
return StringUtils.delimitedListToStringArray(source, ";");
}
}

Then you have to specify this conversion service bean in your configuration:

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

<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="au.org.ala.testspringbinding.CustomStringToArrayConverter" />
</list>
</property>
</bean>

The issue has fixed, now you should check for any side effects. I hope you don't need in your application the original conversion from String to String[] (with comma as separator). ;-)

As suggested by Philip Potter, I'm posting the "update" to my question as an answer, as it might've been easy to miss...

Down-grading from Spring 3.0.5.RELEASE to 3.0.4.RELEASE fixed the issue, when using the @RequestParam annotation, suggesting it is a bug with 3.0.5.

However, it does NOT fix the related issue, when binding to a form-backing bean - which is what I have in my webapp. I've tested all version back to 3.0.0.RELEASE and get the same result (/test?fq=foo,bar produces fq = foo|bar).

E.g.

@RequestMapping(value = "/test", method = RequestMethod.GET)
public void test(SearchRequestParams requestParams, BindingResult result) {
logger.debug("fq = " + StringUtils.join(requestParams.getFq(), "|"));
}

where SearchRequestParams contains a field String[] fq.

If anyone has a fix for this, I'll gladly accept their answer.

I have found the most elegant and the shortest way for me - add @InitBinder to a @Controller:

@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(String[].class, new StringArrayPropertyEditor(null));
}

It will convert String to String[] without using separator (null param), with Spring class org.springframework.beans.propertyeditors.StringArrayPropertyEditor. If someone in same project will use new default conversion way, it will be ok.

javanna already pointed out the correct root cause. I just wanted to further point out that you can also remove the StringToArrayConverter altogether as shown here and here.

Its a hack but, have you considered passing your params delimited with '-'

/test?fq=foo-bar results in fq = foo-bar
/test?fq=foo-bar&fq=bash results in fq = foo-bar|bash

Or any other delimiter maybe ~, or !,or ^, or ???

Category:java Views:0 Time:2011-02-15

Related post

  • Parameter Binding: What happens under the hood? 2008-08-18

    .NET, Java and other high level database API's in various language often provide techniques known as prepared statements and parameter binding as opposed to sending plain text commands to the Database server. What I would like to know is what happens

  • sql server function native parameter bind error 2010-06-29

    I'm using the following software stack on Ubuntu 10.04 Lucid LTS to connect to a database: python 2.6.5 (ubuntu package) pyodbc git trunk commit eb545758079a743b2e809e2e219c8848bc6256b2 unixodbc 2.2.11 (ubuntu package) freetds 0.82 (ubuntu package) W

  • Does using SQL parameter binding mean text can be directly entered from input? 2010-07-01

    As the title says, if I'm using SQL parameters, ie SQLCommand cmd = new SQLCommand("select * from users where username = @user and password = @pass limit 1", Cxn); cmd.Parameters.Add("@user", SqlDbType.VarChar): cmd.Parameters.Add("@pass", SqlDbType.

  • protecting against sql injection attacks beyond parameter binding 2012-04-26

    I have done my homework in reading about protection against sql injection attacks: I know that I need to use parameter binding but: I already do this, thank you. I know that some of the db drivers my users use implement parameter binding in the most

  • Stored procedures vs. parameter binding 2010-05-13

    I am using SQL server and ODBC in visual c++ for writing to the database. Currently i am using parameter binding in SQL queries ( as i fill the database with only 5 - 6 queries and same is true for retrieving data). I dont know much about stored proc

  • how to do parameter binding of a DataView Parameter with Value of a drop down list ? 2010-12-13

    I have a dataview webpart, which is a dashboard. the value of the dashboard is obtained through different algorithms which are coded in XSL. I created a DataView parameter which is used as a variable in the algorithm. My requirement is to give the va

  • MVC 1 Parameter Binding 2011-04-12

    I'm passing a date to my server in Invariant Culture, the following format 'mm/dd/yy' The parameter binding in MVC fails to parse this date and returns null for the parameter. This is persumably because IIS is running on a machine using English cultu

  • Spring MVC customized method parameter binding 2011-06-29

    I'm looking for a way to customize the default Spring MVC parameter binding. Take this method as an example: @RequestMapping(value="/index.html") public ModelAndView doIndex(@RequestParam String param) { ... This is easy, when I have just a Stringtha

  • How do I get all parameter binding information from a CallableStatement? 2011-07-12

    I'm working with legacy code that uses some convoluted logic to bind IN and OUT parameters in a JDBC CallableStatement. The code looks like it is binding the correct types for IN and OUT parameters, but when the CallableStatement is executed the Orac

  • Parameter binding with Hibernate SessionFactory statistics 2011-08-11

    Here's an excerpt: this.sessionFactory.getStatistics().setStatisticsEnabled(true); .. final Map<String, Object> customParams = new HashMap<String, Object>(); customParams.put("active", true); genericDao.getModifiedDate("getModifiedDateFor

  • Show Hibernate parameter binding 2012-03-12

    Whenever i am inserting values the Hibernate log is showing insert into FRIEND_JOB (COMPANY_NAME, PRIMARY_KEY) values (?, ?) is there a way to show also the actual data which is inserted? like :- insert into FRIEND_JOB (COMPANY_NAME, PRIMARY_KEY) val

  • How to bind a ip address in Spring rmi settings? 2010-11-29

    How to bind a ip address in spring rmi settings? Instead of listen all IP in Server. Currently I am using: <bean class="org.springframework.remoting.rmi.RmiServiceExporter"> <property name="serviceName" value="TestRmiService" /> <prope

  • Is there SQL parameter binding for arrays? 2009-02-04

    Is there a standard way to bind arrays (of scalars) in a SQL query? I want to bind into an IN clause, like so: SELECT * FROM junk WHERE junk.id IN (?); I happen to be using Perl::DBI which coerces parameters to scalars, so I end up with useless queri

  • Objective C run-time parameter binding 2009-11-11

    I'd like (at runtime) to bind a parameter to a function as you can do in boost::bind - a little like the following: -(void)myFuncWithParameter:(NSString*)param { NSLog(param); } -(void)init { UIButton *helloButton = [UIButton buttonWithType:UIButtonT

  • How to prevent "parameter PLSQL_DEBUG is deprecated" compiler warning in Oracle SQL Developer 2010-06-15

    When I execute a package body DDL statement SQL Developer warns, Warning: PLW-06015: parameter PLSQL_DEBUG is deprecated; use PLSQL_OPTIMIZE_LEVEL=1 How can SQL Developer be configured to not use PLSQL_DEBUG? PLSQL_DEBUG is set to false in an sql*plu

  • Struts 2 dynamic parameter binding 2010-10-20

    The default stack has the parms interceptor who binds the parameters to the setters found in the action who is being invoked. That works fine when you know the name of the parameter. For example if a request parameter is "employee.name" that could be

  • return a function object with parameter binded? 2010-10-28

    All, def a(p): return p+1 def b(func, p): return func(p) b(a,10) # 11 here I do not want the result "11" actually, what I want is a function object with the parameter has been binded, let's name it c. when I use c() or something alike, it will give m

  • Spring @ModelAttribute and translating request parameter binding names 2010-12-29

    I'm working on converting a legacy project to Spring (trying to adjust little as possible for now) and I'm running into a small issue with mapping/translating legacy parameters to a model attribute object. I may be completely wrong in thinking about

  • How to prevent Sqlite unbound parameters interpreted as NULL 2011-01-03

    As the Sqlite docs specify, unbound parameters in prepared statements are interpreted as NULL - my question is this then: Is there a way to have Sqlite ensure that all parameters have been bound at least once, thereby ensuring none were missed by acc

Copyright (C) dskims.com, All Rights Reserved.

processed in 0.154 (s). 11 q(s)