복붙노트

[SPRING] 쿼리 문자열 매개 변수를 JavaBean에 매핑 할 수 없습니다 (Spring 4 및 Datatables 사용).

SPRING

쿼리 문자열 매개 변수를 JavaBean에 매핑 할 수 없습니다 (Spring 4 및 Datatables 사용).

정말 내 QueryString 매개 변수를 내 Spring JavaBean Command 개체에 매핑하려고 시도하고 있습니다. 지금까지 내 질문에 대한 답을 찾을 수 없었습니다.

내 데이터 테이블에있는 각 동작이 내 Spring 애플리케이션에 AJAX 요청을 트리거하도록 서버 측 처리와 jQuery Datatables 플러그인을 사용하고 있습니다.

Datatable 플러그인이 내 Rest 서비스에 보내는 매개 변수입니다.

http://localhost:8080/relatorios/produtos-source?draw=2&columns[0][data]=nome&columns[0][name]=&columns[0][searchable]=true&columns[0][orderable]=true&columns[0][search][value]=&columns[0][search][regex]=false&columns[1][data]=nomesAlternativos&columns[1][name]=&columns[1][searchable]=true&columns[1][orderable]=true&columns[1][search][value]=&columns[1][search][regex]=false&order[0][column]=2&order[0][dir]=asc&start=0&length=10&search[value]=ss&search[regex]=false&_=1400248561282

이것이 스프링 컨트롤러에서 어떻게 받아 들여지는지입니다 :

@RequestMapping(value = "/produtos-source", method = RequestMethod.GET)
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public ProdutoTable dataTableRequest(@ModelAttribute DataTableCriterias criterias) {
    ...
}

마지막으로, 이것은 DataTableCriterias JavaBean (@ModelAttribute로 표시)입니다.

public class DataTableCriterias {
    private int draw;
    private int start;
    private int length;

    private Map<SearchCriterias, String> search;

    private List<Map<OrderCriterias, String>> order;

    private List<Column> columns;

    public enum SearchCriterias {
        value,
        regex
    }

    public enum OrderCriterias {
        column,
        dir
    }

    public class Column {
        private String data;
        private String name;
        private boolean searchable;
        private boolean orderable;
        private Map<SearchCriterias, String> search;
    }
}

(get / setters가 생략 됨)

이것은 거의 완벽하게 작동합니다! 이 줄을 제거하면 :

private List<Column> columns;

그러면 Spring은 자동으로 쿼리 문자열에서 내 DataTableCriterias 빈을 채 웁니다 (물론, 매핑 된 열 속성을 얻지 못합니다)

그러나이 줄을 추가하면이 오류가 발생합니다.

2014-05-16 17:20:16.605 ERROR 2368 --- [tomcat-http--99] o.a.c.c.C.[.[.[.[dispatcherServlet]      : Servlet.service() for servlet [dispatcherServlet] in context with path [/relatorios] threw exception [Request processing failed; nested exception is org.springframework.beans.InvalidPropertyException: Invalid property 'columns[0][data]' of bean class [com.bergermobile.rest.domain.DataTableCriterias]: Illegal attempt to get property 'columns' threw exception; nested exception is org.springframework.beans.NullValueInNestedPathException: Invalid property 'columns' of bean class [com.bergermobile.rest.domain.DataTableCriterias]: Could not instantiate property type [com.bergermobile.rest.domain.DataTableCriterias$Column] to auto-grow nested property path: java.lang.InstantiationException: com.bergermobile.rest.domain.DataTableCriterias$Column] with root cause

org.springframework.beans.NullValueInNestedPathException: Invalid property 'columns' of bean class [com.bergermobile.rest.domain.DataTableCriterias]: Could not instantiate property type [com.bergermobile.rest.domain.DataTableCriterias$Column] to auto-grow nested property path: java.lang.InstantiationException: com.bergermobile.rest.domain.DataTableCriterias$Column
    at org.springframework.beans.BeanWrapperImpl.newValue(BeanWrapperImpl.java:651)

필자가 보았 듯이 Datatable 플러그인에서 전송하는 '열'매개 변수는 양방향이며 때로는 3 차원 배열이기도합니다.

columns[0][data]=nome
columns[0][search][regex]=false

그래서, 그것은 내 콩이 옳았다는 것처럼 보이지만, 나는이 오류를 얻었고 지금은 붙어 있습니다.

어떤 아이디어?

고마워요!

해결법

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

    1.좋아, 그래서 나는이 문제를 수정하여 서버에 보내진 매개 변수를 약간 수정하여 두 개의 3D 배열을 2D 배열로 변환했다. 그래서:

    좋아, 그래서 나는이 문제를 수정하여 서버에 보내진 매개 변수를 약간 수정하여 두 개의 3D 배열을 2D 배열로 변환했다. 그래서:

    columns[0][search][value]=myvalue
    columns[0][search][regex]=false
    

    결국 존재 :

    columns[0][searchValue]=myvalue
    columns[0][searchRegex]=false
    

    이것은 Datatables에서이를 수행하는 방법입니다.

    $('#produtosTable').DataTable({
        serverSide: true,
        ajax: {
            "url": "produtos-source",
            "data": function(data) {
                planify(data);  
            } 
        }
    });
    
    function planify(data) {
        for (var i = 0; i < data.columns.length; i++) {
            column = data.columns[i];
            column.searchRegex = column.search.regex;
            column.searchValue = column.search.value;
            delete(column.search);
        }
    }
    

    이렇게하면이 필드를 사용하여 Model 객체에서 해당 속성을받을 수 있습니다.

    private List<Map<ColumnCriterias, String>> columns;
    

    참고로 여기 내 컨트롤러는 다음과 같습니다.

    @RequestMapping(value = "/produtos-source", method = RequestMethod.GET)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public ProdutoTable dataTableRequest(@ModelAttribute DataTableCriterias criterias) {
        ProdutoTable produtoTable = produtosService.findProdutos();
        produtoTable.setDraw(criterias.getDraw());
        return produtoTable;
    }
    

    여기 내 DataTableCriterias @ ModelAttriute의 최종본이 있습니다.

    public class DataTableCriterias {
        private int draw;
        private int start;
        private int length;
    
        private Map<SearchCriterias, String> search;
    
        private List<Map<ColumnCriterias, String>> columns;
    
        private List<Map<OrderCriterias, String>> order;
    
        public enum SearchCriterias {
            value,
            regex
        }
        public enum OrderCriterias {
            column,
            dir
        }
        public enum ColumnCriterias {
            data,
            name,
            searchable,
            orderable,
            searchValue,
            searchRegex
        }
    

    (get / setters가 생략 됨)

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

    2.나는 내가 파티에 늦었다는 것을 알고있다. 그러나 이것 : https://github.com/darrachequesne/spring-data-jpa-datatables

    나는 내가 파티에 늦었다는 것을 알고있다. 그러나 이것 : https://github.com/darrachequesne/spring-data-jpa-datatables

    귀하의 datatables 입력을 우아하게 읽는 멋진 대안입니다. JPA를 사용하지 않으려는 경우에도 DataTablesInput 및 DataTablesOutput 클래스를 사용하여 입력을 올바르게 읽을 수 있습니다. 또한 jquery.spring-friendly.min.js를 포함 시켰기 때문에 Spring은 쉽게 들어오는 변수를 읽을 수있었습니다.

    멋진 우아한 솔루션에 대한 https://github.com/darrachequesne에 감사드립니다.

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

    3.열 [0]을 매개 변수로 보내지 만 열에는 색인 0이없는 항목이 있습니다. 사실 null이기 때문에 항목이 없습니다.

    열 [0]을 매개 변수로 보내지 만 열에는 색인 0이없는 항목이 있습니다. 사실 null이기 때문에 항목이 없습니다.

    이 작업을 수행하려면 DataTableCriterias 생성자에서 목록을 인스턴스화해야합니다. 그리고 보내는 매개 변수에 대한 충분한 항목이 있어야합니다.

  4. from https://stackoverflow.com/questions/23704352/cant-map-a-query-string-parameters-to-my-javabean-using-spring-4-and-datatable by cc-by-sa and MIT license