복붙노트

[SPRING] Spring 3.0.5에서 매개 변수 바인딩이 쉼표를 해석하지 못하게하는 방법은 무엇입니까?

SPRING

Spring 3.0.5에서 매개 변수 바인딩이 쉼표를 해석하지 못하게하는 방법은 무엇입니까?

다음 제어기 방법을 고려하십시오.

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

다음은 서로 다른 fq 조합에 대한 출력입니다.

예 3이 문제입니다. 나는 fq = foo, bar를 출력하기를 기대한다.

\를 사용하여 콤마를 이스케이프 처리했지만 % 3C를 사용했지만 작동하지 않았습니다.

HttpServletRequest 객체의 버전을 보면 :

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

예상되는 출력을 출력합니다 : fqs = foo, bar. 따라서 "문제"는 Spring 데이터 바인딩에 있습니다.

나는 Spring의 바인딩을 우회하여 HttpServletRequest를 사용할 수 있지만 실제 코드에서 backing bean을 사용하고 (같은 일이 일어나고있다.) 바인딩 기능을 다시 구현하기를 원하지 않는다. 저는 누군가가 탈출이나 다른 메커니즘을 통해 이러한 행동을 막을 수있는 간단한 방법을 제공하기를 희망합니다.

TIA

업데이트 : 나는이 Q를 트위터에 올렸고 예상 출력이 Spring 3.0.4.RELEASE와 함께 나타났다는 답변을 받았다. 이제는 이것이 사실임을 확인했으며 임시 수정 사항입니다. Spring JIRA 시스템에 버그로 기록 할 것입니다. 누구나 해결 방법을 제공하거나 3.0.5로 해결할 수 있다면 그 대답을 받아 들일 것입니다.

해결법

  1. ==============================

    1.귀하의 코드를 테스트했습니다 : 믿을 수 없지만 문제를 재현 할 수는 없습니다. 스프링 (3.0.5)의 최신 버전을 다운로드했습니다. 이것이 제 컨트롤러입니다.

    귀하의 코드를 테스트했습니다 : 믿을 수 없지만 문제를 재현 할 수는 없습니다. 스프링 (3.0.5)의 최신 버전을 다운로드했습니다. 이것이 제 컨트롤러입니다.

    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;
        }
    }
    

    이것은 내 간단한 봄 구성입니다 :

    <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>
    

    내가 톰캣 7.0.8 내 코드를 테스트했습니다; http : // localhost : 8080 / testweb / test / params.htm? fq = foo, bar라고 입력하면 로그 파일에서 DEBUG fq = foo, bar를 읽을 수 있습니다. 내 코드와 당신의 차이점은 무엇입니까? 내가 뭔가 잘못하고 있는거야? 나는 너를 돕고 싶다. 그래서 너는 의심의 여지가 있거나 내가 너를 위해서 다른 시험을 할 수 있다면, 그것은 즐거움 일 것이다.

    업데이트 / 솔루션 귀하의 코드를 사용하여 문제를 재현했습니다. Dispatcher 서블릿 구성에 태그가 있으므로 쉼표를 구분 기호로 사용하는 String에서 String []으로의 기본 변환기가 포함 된 FormattingConversionService의 인스턴스 인 자동 변환 서비스를 사용합니다. String에서 String []에 이르는 변환기를 포함하는 다른 변환 서비스 bean을 사용해야합니다. 다른 구분 기호를 사용해야하며 ";"을 사용하도록 선택했습니다. 이것은 주로 쿼리 문자열에 사용되는 구분 기호이기 때문에 ( "? 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>
    

    문제가 해결되었으므로 부작용이 있는지 확인해야합니다. 응용 프로그램에서 String에서 String [] (구분 기호로 쉼표 사용)으로의 원래 변환이 필요하지 않기를 바랍니다. ;-)

  2. ==============================

    2.나는 나를 위해 가장 우아하고 가장 짧은 길을 찾았습니다. @InitBinder를 @Controller에 추가하십시오 :

    나는 나를 위해 가장 우아하고 가장 짧은 길을 찾았습니다. @InitBinder를 @Controller에 추가하십시오 :

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

    Spring 클래스 인 org.springframework.beans.propertyeditors.StringArrayPropertyEditor를 사용하여 분리 자 (null param)를 사용하지 않고 String []으로 변환합니다. 같은 프로젝트에있는 누군가가 새로운 기본 변환 방법을 사용한다면 괜찮을 것입니다.

  3. ==============================

    3.Philip Potter가 제안한대로, 필자는 대답으로 내 질문에 "업데이트"를 게시하고 있습니다. 놓치기 쉽기 때문에 ...

    Philip Potter가 제안한대로, 필자는 대답으로 내 질문에 "업데이트"를 게시하고 있습니다. 놓치기 쉽기 때문에 ...

    Spring 3.0.5.RELEASE에서 3.0.4.RELEASE로 다운 그레이드하면 @RequestParam annotation을 사용할 때 3.0.5의 버그임을 나타내는 이슈가 수정되었습니다.

    그러나 양식 백킹 빈에 바인딩 할 때 관련된 문제는 수정하지 않습니다. 이것이 내 webapp에 있습니다. 나는 모든 버전을 3.0.0.RELEASE로 테스트했고 동일한 결과를 얻었다. (/ test? fq = foo, bar는 fq = foo | bar를 만든다.)

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

    여기서 SearchRequestParams는 String [] fq 필드를 포함합니다.

    누구든지이 문제를 해결하면 기꺼이 대답을 수락합니다.

  4. ==============================

    4.javanna는 이미 정확한 근본 원인을 지적했습니다. 여기 그리고 여기에 표시된 것처럼 StringToArrayConverter를 모두 제거 할 수 있다는 점을 더 지적했습니다.

    javanna는 이미 정확한 근본 원인을 지적했습니다. 여기 그리고 여기에 표시된 것처럼 StringToArrayConverter를 모두 제거 할 수 있다는 점을 더 지적했습니다.

  5. ==============================

    5.그것의 해킹하지만, 당신은 '-'로 구분 된 매개 변수를 전달하는 것으로 생각 해 봤나?

    그것의 해킹하지만, 당신은 '-'로 구분 된 매개 변수를 전달하는 것으로 생각 해 봤나?

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

    또는 다른 구분 기호는 ~, 또는!, 또는 ^, 또는 ???

  6. from https://stackoverflow.com/questions/4998748/how-to-prevent-parameter-binding-from-interpreting-commas-in-spring-3-0-5 by cc-by-sa and MIT license