考虑以下 Controller 方法:

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

这是不同fq组合的输出:
  • /test?fq=foo结果为fq = foo
  • /test?fq=foo&fq=bar结果为fq = foo|bar
  • /test?fq=foo,bar结果为fq = foo|bar
  • /test?fq=foo,bar&fq=bash结果为fq = foo,bar|bash
  • /test?fq=foo,bar&fq=结果为fq = foo,bar|

  • 示例3是问题所在。我希望(想要/需要)它输出fq = foo,bar

    我试过用\转义逗号,并使用%3C,但是没有用。

    如果我查看HttpServletRequest对象的版本:
    String[] fqs = request.getParameterValues("fq");
    logger.debug(fqs = " + StringUtils.join(fqs, "|"));
    

    它输出预期的输出:fqs = foo,bar。因此,“问题”在于Spring数据绑定(bind)。

    我可以绕过Spring的绑定(bind)并使用HttpServletRequest,但我真的不想要,因为我在我的真实代码中使用了支持bean (发生了同样的事情),并且不想重新实现绑定(bind)功能。我希望有人可以提供一种通过转义或其他机制防止这种行为的简单方法。

    TIA

    更新:我在Twitter上发布了此Q,并得到答复说预期的输出将在Spring 3.0.4.RELEASE 中出现。我现在已经确认是这种情况,因此是一个临时解决方案。我将继续并将其记录为Spring JIRA系统上的错误。如果任何人都可以提供解决方法或使用3.0.5进行修复,我将接受他们的回答。

    最佳答案

    我已经测试了您的代码:令人难以置信,但是我无法重现您的问题。我已经下载了最新版本的spring(3.0.5),这是我的 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(), "|"));
        }
    }
    

    这是我的SearchRequestParams类:
    package test;
    
    public class SearchRequestParams {
        private String[] fq;
    
        public String[] getFq() {
        return fq;
        }
    
        public void setFq(String[] fq) {
        this.fq = fq;
        }
    }
    

    这是我简单的spring配置:
    <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>
    

    我已经在tomcat 7.0.8中测试了我的代码;当我键入http://localhost:8080/testweb/test/params.htm?fq=foo,bar时,我可以在日志文件中读取以下行:DEBUG fq = foo,bar
    我的代码与您的代码有什么区别?难道我做错了什么?
    我想为您提供帮助,因此,如果您有任何疑问或可以为您做其他测试,那将是一种荣幸。

    更新/解决方案
    通过您的代码,我重现了该问题;您在调度程序Servlet配置中具有标记<mvc:annotation-driven />,因此您默默地使用默认转换服务FormattingConversionService实例,该实例包含从StringString[]的默认转换器,该转换器使用逗号作为分隔符。
    您必须使用其他转换服务Bean,其中包含您自己的从StringString[]的转换器。您应该使用其他分隔符,我选择使用“;”因为它是查询字符串中常用的分隔符(“?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, ";");
        }
    }
    

    然后,您必须在配置中指定此转换服务bean:
    <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>
    

    该问题已解决,现在您应该检查是否有副作用。我希望您在应用程序中不需要从StringString[]的原始转换(用逗号作为分隔符)。 ;-)

    09-11 19:21