Как настроить split-pattern для параметра запроса - PullRequest
2 голосов
/ 03 мая 2011

Моя проблема в том, что у меня есть следующий URL:

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

У меня есть бин, который отображает эти параметры запроса:

public class SearchParams {

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

    // getters goes here...
}

Моя проблема в том, что Spring автоматически разделяет 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()));
   ...
}

Имой Spring-Config выглядит так:

<!-- 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" />

Ответы [ 4 ]

3 голосов
/ 09 июля 2011

Я столкнулся с подобной проблемой, пытаясь использовать @RequestParameter с List (он продолжал прерываться на запятые.

Решение, которое я нашел, состояло в том, чтобы использовать параметр WebRequest в моем методе контроллера,позволяет мне использовать request.getParameterValues ​​("blar")

@RequestMapping(value = "search", method = RequestMethod.GET)
public String search(WebRequest req, BindingResult bindResult, Model  model)  {
    String[] searchParams = req.getParameterValues("fq")
1 голос
/ 06 марта 2014

Регистрация пользовательского редактора для String [], предложенного Юджином, не работает, поскольку String [] преобразуется в String с помощью CollectionToStringConverter перед использованием любого пользовательского редактора.

Чтобы использовать другой разделитель, чем запятая (по умолчанию это поведение CollectionToStringConverter), вам необходимо добавить свой собственный конвертер, как описано в Справочная документация Spring MVC .

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

Для реализации MyCustomCollectionToStringConverter вы не можете расширить CollectionToStringConverter, поскольку он является окончательным, но вы можете взглянуть на его исходный код , чтобы создать свой собственный.

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 голосов
/ 22 июля 2011

Вы можете использовать аннотацию @InitBinder для настройки привязки массива.Примерно так должно работать:

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

Более подробное объяснение вы можете прочитать в Spring MVC документации

0 голосов
/ 03 мая 2011

Поскольку никто не придумал «правильного» ответа на этот вопрос, ваш самый простой вариант, вероятно, состоит в том, чтобы вообще не заставлять Spring разделять параметр, а вместо этого добавлять логику разделения в методе получения:

public class SearchParams {

    private String q = "";
    private String fq;

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

Это, вероятно, проще, чем пытаться убедить Spring сделать это по вашей собственной спецификации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...