如何自定义请求参数分割模式

问题描述:

我的问题是,我有以下网址:如何自定义请求参数分割模式

http://localhost:8080/shiSolrClient/app/shi/search?q=xyz&fq=author:"Max, Muster" 

我有这些requestParameters的映射豆:

public class SearchParams { 

    private String q = ""; 
    private String[] fq; 

    // getters goes here... 
} 

我的问题是,春天自动分割逗号上的fq参数。所以在我的豆有两个字符串fq:

String[0]: author:"Max 
String[1]: Muster" 

我不希望这种行为。我想要的是告诉Spring在'&'上分裂 - '不在',' - 令牌之上。例如。

http://localhost:8080/shiSolrClient/app/shi/search?q=xyz&fq=author:"Max, Muster"&content:"someContent" 

fq=  
String[0]: author:"Max, Muster" 

String[1]: content:"someContent" 

谁能告诉我如何在Spring MVC归档此3

我的控制器如下:

@RequestMapping(value = "search", method = RequestMethod.GET) 
public String search(SearchParams searchParams, BindingResult bindResult, Model 
    model) { 

    SolrQuery solrQ = getBasicQuery(searchParams).setQuery(searchParams.getQ()); 
    for(String fq : searchParams.getFq()) { 
     solrQ.setParam("fq", fq); 
    } 
    try { 
     QueryResponse rsp = getSolrServer().query(solrQ); 
     model.addAttribute("solrResults", transformResults(rsp.getResults(), 
      rsp.getHighlighting(), searchParams, rsp)); 
     model.addAttribute("facetFields", transformFacets(rsp.getFacetFields(), 
      rsp.getFacetDates(), searchParams)); 
     model.addAttribute("pagination", calcPagination(searchParams, 
      rsp.getResults())); 
    ... 
} 

我的弹簧配置看起来是这样的:

<!-- Enables the Spring MVC @Controller programming model --> 
<annotation-driven /> 

<!-- Handles HTTP GET requests for /resources/** --> 
<resources mapping="/resources/**" location="/resources/" /> 

<!-- Configure Apache Tiles for the view --> 
<beans:bean id="tilesConfigurer" 
     class="org.springframework.web.servlet.view.tiles2.TilesConfigurer"> 
    <beans:property name="definitions"> 
      <beans:list> 
     <beans:value>/WEB-INF/views/layout/layouts.xml</beans:value> 
     <beans:value>/WEB-INF/views/hitlist/views.xml</beans:value> 
     </beans:list> 
    </beans:property> 
</beans:bean> 

<beans:bean id="viewResolver" 
      class="org.springframework.web.servlet.view.UrlBasedViewResolver"> 
    <beans:property name="requestContextAttribute" value="requestContext"/> 
    <beans:property name="viewClass" 
      value="org.springframework.web.servlet.view.tiles2.TilesView"/> 
</beans:bean> 

<beans:bean id="messageSource" 
     class="org.springframework.context.support.ResourceBundleMessageSource"> 
    <beans:property name="basenames"> 
     <beans:list> 
     <beans:value>global</beans:value> 
     <beans:value>hitlist</beans:value> 
     <beans:value>local/messages</beans:value> 
     </beans:list> 
    </beans:property> 
</beans:bean> 

    <!-- Scans within the base package of the application for @Components to configure 
      as beans --> 
<context:component-scan base-package="com.shi.solrclient.web" /> 
+0

你能告诉我们你的控制器代码吗? – 2011-05-03 19:03:21

因为没有人想出了一个“正确”的答案,你的最简单的方法可能是没有得到春在所有分裂的参数,而是在getter方法添加拆分逻辑:

public class SearchParams { 

    private String q = ""; 
    private String fq; 

    public String[] getSplitFq() { 
     // split and return the array 
    } 
} 

这可能比试图说服Spring遵循自己的规范更容易。

我跑进尝试使用与列表中@RequestParameter类似的问题(它一直得到以逗号斩。

我想出了解决的办法是在我的控制方法,它允许使用的WebRequest参数。我使用request.getParameterValues( “blar”)

@RequestMapping(value = "search", method = RequestMethod.GET) 
public String search(WebRequest req, BindingResult bindResult, Model model) { 
    String[] searchParams = req.getParameterValues("fq") 

您可以使用@InitBinder注解来配置阵列结合这样的事情应该工作:

@InitBinder("fq") 
public void fqBinderInit(WebDataBinder binder) { 
    binder.registerCustomEditor(String[].class, new StringArrayPropertyEditor("&")); 
} 

您可以阅读Spring MVC documentation

更详细的说明注册一个自定义编辑器的String []所建议的尤金不起作用,因为的String []的任何自定义编辑器在使用前转换成字符串由CollectionToStringConverter。

为了使用另一个除逗号分隔符(即CollectionToStringConverter默认行为),您需要添加自己的自定义转换器,如Spring MVC reference documentation中所述。

<bean id="conversionService" 
     class="org.springframework.context.support.ConversionServiceFactoryBean"> 
    <property name="converters"> 
     <set> 
      <bean class="example.MyCustomCollectionToStringConverter"/> 
     </set> 
    </property> 
</bean> 

为了实现MyCustomCollectionToStringConverter,你不能延长CollectionToStringConverter,因为它是最后的,但你可以看看到its source code创建自己的。

final class MyCustomCollectionToStringConverter implements ConditionalGenericConverter { 

    private static final String DELIMITER = "&"; 

    private final ConversionService conversionService; 

    public MyCustomCollectionToStringConverter(ConversionService conversionService) { 
     this.conversionService = conversionService; 
    } 

    @Override 
    public Set<ConvertiblePair> getConvertibleTypes() { 
     return Collections.singleton(new ConvertiblePair(Collection.class, String.class)); 
    } 

    @Override 
    public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { 
     return ConversionUtils.canConvertElements(sourceType.getElementTypeDescriptor(), targetType, this.conversionService); 
    } 

    @Override 
    public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { 
     if (source == null) { 
      return null; 
     } 
     Collection<?> sourceCollection = (Collection<?>) source; 
     if (sourceCollection.size() == 0) { 
      return ""; 
     } 
     StringBuilder sb = new StringBuilder(); 
     int i = 0; 
     for (Object sourceElement : sourceCollection) { 
      if (i > 0) { 
       sb.append(DELIMITER); 
      } 
      Object targetElement = this.conversionService.convert(sourceElement, sourceType.elementTypeDescriptor(sourceElement), targetType); 
      sb.append(targetElement); 
      i++; 
     } 
     return sb.toString(); 
    } 

} 
+0

您提到的'ConversionServiceFactoryBean'配置对我无效,因为'MyCustomCollectionToStringConverter'具有参数化而不是默认构造函数。我刚刚在'afterPropertiesSet()'方法中添加了'registry.addConverter(new MyCustomCollectionToStringConverter(this.getObject()));' – Chris 2014-11-18 13:48:56