Solucionado (ver solução)
Solucionado
(ver solução)
11
respostas

Receber no controller parâmetro HTTP

Tenho o meu controller pronto e a submissão que envia os dados via ajax, tudo funcionando, mas não consigo receber os dados nesse formato que vem em uma única linha: Como faço para receber esse objeto, lembrando que a submissão chega, mas quando tento imprimir no console vem nulo:

action create
data[0][descricaoReceita] Receita+de+entrada
data[0][dataReceita][year] 20/08/2017
data[0][minhasContas] Conta+4
data[0][tipoReceitas] Tipo+de+receita
data[0][valorReceita] 50000
11 respostas

Olá Clerman, se eu entendi bem você está tentando enviar esse trecho acima no corpo de uma requisição do tipo POST correto?

Eu recomendo você tentar converter no seu frontend esse texto para Json, mas no caso de você precisar realmente enviar via texto, você pode tentar configurar seu método mais ou menos conforme o exemplo abaixo:

@RequestMapping(path = "/meuPath", method = RequestMethod.POST)
public void meuMetodo(@RequestBody String movements) {
//body
}

Nesse método eu preciso dele com duas funções.

Esse é o meu método que estou tentando receber os dados que postei acima: esta vindo nulo!

    @RequestMapping(value = "listAll", method = { RequestMethod.GET,
            RequestMethod.POST }, produces = "application/json")
    public @ResponseBody ResponseEntity<DataTableMinhasReceitas> getListReceitas(DataTableMinhasReceitas Object) {

        System.out.println("======================================= " + Object);

        List<MinhasReceitas> listAllMinhasReceitas = receitasService.findAll();

        DataTableMinhasReceitas dataTableMinhasReceitas = new DataTableMinhasReceitas();

        dataTableMinhasReceitas.setData(listAllMinhasReceitas);

        return ResponseEntity.status(HttpStatus.OK).body(dataTableMinhasReceitas);
    }

Denis na documentação do Datatables informa que os dados enviados está no formato que te enviei:

action              = create
data[0][extn]       = 2947
data[0][first_name] = Fiona
data[0][last_name]  = Green
data[0][office]     = San Francisco
data[0][position]   = Chief Operating Officer (COO)
data[0][salary]     = 850000
data[0][start_date] = 2010-03-11

e desse dados é gerado um json nesse formato:

{
    "data": [
        {
            "DT_RowId":   "row_29",
            "first_name": "Fiona",
            "last_name":  "Green",
            "position":   "Chief Operating Officer (COO)",
            "office":     "San Francisco",
            "extn":       "2947",
            "salary":     "850000",
            "start_date": "2010-03-11"
        }
    ]
}

De que forma que eu recebo esses dados no controller?

Olá Denis, estava testando aqui a sugestão que passou, que é a de inserir @RequestBody como parâmetro e obtive o erro:


org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported
    at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:235)
    at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.readWithMessageConverters(RequestResponseBodyMethodProcessor.java:147)
    at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:125)
    at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:99)
    at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:161)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:128)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:832)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:743)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:961)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:895)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:869)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:207)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:176)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
    at org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.doFilterInternal(OpenEntityManagerInViewFilter.java:178)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:94)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:620)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:509)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1104)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:684)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1524)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1480)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Unknown Source)

Olá Clerman, acredito que o problema no seu código deve-se ao fato do json que você esta recebendo estar diferente do seu objeto de modelo, você poderia postar o código da classe DataTableMinhasReceitas?

Ela possui o atributo data? Pois o spring não vai conseguir transformar o Json em objeto caso ela não tenha.

Eis:

package br.com.clipboard.financeiro.entity;

import java.util.List;

import javax.persistence.Entity;
import javax.persistence.OneToMany;

import org.springframework.data.jpa.domain.AbstractPersistable;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@Entity
@JsonIgnoreProperties(value = {"id", "sEcho", "sColumns", "new"})
public class DataTableMinhasReceitas extends AbstractPersistable<Long> {

    int iTotalRecords;
    int iTotalDisplayRecords;
    String sEcho;
    String sColumns;

    @OneToMany
    List<MinhasReceitas> data;

    public int getiTotalRecords() {
        return iTotalRecords;
    }

    public void setiTotalRecords(int iTotalRecords) {
        this.iTotalRecords = iTotalRecords;
    }

    public int getiTotalDisplayRecords() {
        return iTotalDisplayRecords;
    }

    public void setiTotalDisplayRecords(int iTotalDisplayRecords) {
        this.iTotalDisplayRecords = iTotalDisplayRecords;
    }

    public String getsEcho() {
        return sEcho;
    }

    public void setsEcho(String sEcho) {
        this.sEcho = sEcho;
    }

    public String getsColumns() {
        return sColumns;
    }

    public void setsColumns(String sColumns) {
        this.sColumns = sColumns;
    }

    public List<MinhasReceitas> getData() {
        return data;
    }

    public void setData(List<MinhasReceitas> Data) {
        this.data = Data;
    }

}

Parece que seu Model esta certo, eu tentaria adicionar a anotação conforme eu já falei, porém você precisa enviar no header da requisição que o Content-Type é application/json, pois parece que ele está enviando com o Content-Type 'application/x-www-form-urlencoded' conforme mostra no erro que você postou.

Qualquer coisa posta o código do seu frontend.

public @ResponseBody ResponseEntity<DataTableMinhasReceitas> getListReceitas(@RequestBody DataTableMinhasReceitas Object)

Mesmo erro;

Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported

Segue todos os script : o código esta dentro da função getDataTable().

<script type="text/javascript">
        var editor; // use a global for the submit and return data rendering in the examples
        var messageFiles = 'Clipboard - Lista de receitas(entradas)';
        var classeBtn = 'btn btn-outline btn-default';
        var classeBtnEditor = 'btn btn-info';
        var erroValorTxt = '<strong>Erro</strong> ao carregar o valor total das receitas';
        var erroDataTxt = '<strong>Erro</strong> ao carregar as datas, atualize a página. [F5]';
        var positionExport = {columns: [0, 1, 2, 3]};
        var header = $("meta[name='_csrf_header']").attr("content");
        var token = $("meta[name='_csrf']").attr("content");

        $(document).ready(function() {

            getDataTable();
            pegaData();
            getValMesAnoReceitas();

            function getDataTable(){

                editor = new $.fn.dataTable.Editor( {
                    ajax: "/financeiro/receitas/salvarReceitasAjax",
                    table: "#receitasTable",
                    idSrc: "id",
                    fields: [ {
                            label: "Descrição:",
                             name: "descricaoReceita"
                        }, {
                            label: "Data:",
                            name: "dataReceita.year"
                      }, {
                            label: "Contas:",
                            name: "minhasContas[0].nome"
                      }, {
                            label: "Tipo:",
                            name: "tipoReceitas[0].corTipoReceita"
                      }, {
                            label: "Valor:",
                            name: "valorReceita"
                        }
                    ]
                } );

                var oTable = $('#receitasTable').DataTable( {
                    ajax: "/financeiro/receitas/listAll",
                    dom: '<"row"<"col-sm-8"B><"col-sm-4"f>><"row"<"col-sm-12"tr>><"row"<"col-sm-5 font-size-12"i><"col-sm-7"p>>',
                    bProcessing : true,
                    lengthMenu: [
                        [ 5, 10, 20, 30, 50, 100, -1 ],
                        [ '5 itens', '10 itens', '20 itens', '30 itens', '50 itens', '100 itens', 'Todos' ]
                    ],
                    columns: [
                        { data: "id" }, 
                        { data: "descricaoReceita" },
                        { 
                            data: "dataReceita" ,
                            mRender: function(data){
                                dataDay = data.dayOfMonth < 10 ? '0' + data.dayOfMonth : data.dayOfMonth;
                                dataMonth = data.monthValue < 10 ? '0' + data.monthValue : data.monthValue;
                                dataObj = dataDay + '/' + dataMonth + '/' + data.year
                                return dataObj;
                            },
                        },
                        {
                            data: "minhasContas[0].nome"/* ,
                            mRender: function (data, type, full){
                               return data[0].nome;
                            },
                            sDefaultContent: '' */
                          },
                          {
                            data: "tipoReceitas[0].nome"/*  ,
                            mRender: function (data, type, full){
                               return data[0].corTipoReceita;
                            },
                            sDefaultContent: '' */
                          },
                        { 
                              data: "valorReceita",
                              mRender: $.fn.dataTable.render.number('.', ',', 2, 'R$ ') 
                        }
                    ],
                    select: "single",
                    buttons: [
                         {    extend:     "create", 
                            editor:     editor, 
                            text:       '<i class="icon fa-plus"></i>',
                            titleAttr:     'Criar receita',
                            className: classeBtnEditor
                        },
                        {    extend: "edit",
                            editor: editor,
                            text:       '<i class="icon fa-edit"></i>',
                            titleAttr:     'Editar receita',
                            className: classeBtnEditor
                        },
                        {     extend: "remove",
                            editor: editor,
                            text:       '<i class="icon fa-trash-o"></i>',
                            titleAttr:     'Excluir receita',
                            className: classeBtnEditor,
                            exportOptions: {
                                columns: [ 1, ':visible' ]
                            }
                        }, 
                        {      extend:     'pageLength',
                            text:         '<i class="icon wb-list"></i>  ',
                            titleAttr:  'Listar itens',
                               className:  classeBtn
                        },
                        {
                            text:       '<i class="icon fa-refresh"></i>',
                            titleAttr:  'Atualizar itens',
                            className: classeBtn,
                            action: function ( e, dt, node, config ) {
                                dt.ajax.reload();
                            }
                        },
                        {
                            extend:    'copyHtml5',
                            text:      '<i class="fa fa-files-o"></i>',
                            titleAttr: 'Copiar',
                            exportOptions: positionExport,
                            message:   messageFiles,
                            className: classeBtn
                        },
                        {
                            extend:    'excelHtml5',
                            text:      '<i class="fa fa-file-excel-o"></i>',
                            titleAttr: 'Excel',
                            exportOptions: positionExport,
                            message:   messageFiles,
                            className: classeBtn
                        },
                        {
                            extend:    'pdfHtml5',
                            text:      '<i class="fa fa-file-pdf-o"></i>',
                            orientation: 'portrait',
                            titleAttr: 'Ver PDF',
                            exportOptions: positionExport,
                            message:   messageFiles,
                            className: classeBtn
                        },
                        {
                            extend:    'print',
                            text:      '<i class="fa fa-print"></i>',
                            titleAttr: 'Inprimir',
                            exportOptions: positionExport,
                            message:   messageFiles,
                               className: classeBtn
                        }
                     ] 
                });

                 $('button[id*="filtrarData_"]').click(function(){ 

                       oTable.rows().remove();
                       oTable.ajax.url("/financeiro/receitas/listMesAno");
                       oTable.draw();
                       setTimeout(function(){
                           oTable.ajax.reload();
                           getValMesAnoReceitas();

                       }, 400);
                     });
                     $('#filtrarTodos').click(function(){

                       oTable.rows().remove();
                       oTable.ajax.url("/financeiro/receitas/listAll");
                       oTable.draw();
                       setTimeout(function(){
                           oTable.ajax.reload();
                           getValTotalReceitas();

                        }, 400);
                     });
            };

            function getValMesAnoReceitas(){

                   $('.loaderValorBg').show();

                $.ajax({
                    url: "/financeiro/receitas/valorReceitasMesAno",
                    beforeSend: function(){

                    },
                    success: function(retorno){
                        formatCurrency();
                        var obj = JSON.parse(retorno);
                        var colorClassGrey = "bg-blue-grey-300";
                        var colorClassCyan = "bg-cyan-600";
                        var valor = obj.ValorReceitasMesAno;

                        if(valor == 0){
                            $('#colorClassDiv').removeClass(colorClassCyan).addClass(colorClassGrey);
                        }else if(valor > 0) {
                            $('#colorClassDiv').removeClass(colorClassGrey).addClass(colorClassCyan);
                        }

                        $('#valorTotalReceitas').fadeToggle();

                        setTimeout(function(){
                            $('.loaderValorBg').fadeToggle();
                            $('#valorTotalReceitas').html('R$ ' + valor.format(2, 3, '.', ',')).fadeToggle();

                        }, 300); 

                    }, 
                    error: function(){

                        var valorZero = 000000;

                        $('#erroValorTexto').html(erroValorTxt);
                        $('#erroValor').fadeToggle();
                         $('.loaderValorBg').fadeOut();

                        setTimeout(function() {
                             $('#erroValor').fadeOut();
                         }, 4000); 

                         $('#valorTotalReceitas').html('R$ ' + valorZero.format(2, 3, '.', ','));
                    }, 
                 });
            };

               function getValTotalReceitas(){

                   $('.loaderValorBg').show();

                $.ajax({
                    url: "/financeiro/receitas/valorReceitasTotal",
                    beforeSend: function(){},
                    success: function(retorno){

                        formatCurrency();
                        var obj = JSON.parse(retorno);
                        var colorClassGrey = "bg-blue-grey-300";
                        var colorClassCyan = "bg-cyan-600";
                        var valor = obj.ValorReceita;

                        if(valor == 0){
                            $('#colorClassDiv').removeClass(colorClassCyan).addClass(colorClassGrey);
                        }else if(valor > 0) {
                            $('#colorClassDiv').removeClass(colorClassGrey).addClass(colorClassCyan);
                        }

                        $('#valorTotalReceitas').fadeToggle();

                        setTimeout(function(){
                            $('.loaderValorBg').fadeToggle();
                            $('#valorTotalReceitas').html('R$ ' + valor.format(2, 3, '.', ',')).fadeToggle();

                        }, 300); 

                    }, 
                    error: function(){
                        var valorZero = 000000;

                        $('#erroValorTexto').html(erroValorTxt);
                        $('#erroValor').fadeToggle();
                         $('.loaderValorBg').fadeOut();

                        setTimeout(function() {
                             $('#erroValor').fadeOut();
                         }, 5000); 

                         $('#valorTotalReceitas').html('R$ ' + valorZero.format(2, 3, '.', ','));
                    }, 
                 });
            };


            function addZero(zero) {
                return (zero < 10 ? '0' : '') + zero;
            };

            function dataFormatada() {
                var data = new Date(),
                mes = addZero(data.getMonth() + 1),
                ano = data.getFullYear()

                return [ mes, ano ].join('/');
            };

            function stringMes(mes) {

                switch (mes) {
                case "01": mes = "Janeiro";   break;
                case "02": mes = "Fevereiro"; break;
                case "03": mes = "Março";      break;
                case "04": mes = "Abril";      break;
                case "05": mes = "Maio";      break;
                case "06": mes = "Junho";      break;
                case "07": mes = "Julho";       break;
                case "08": mes = "Agosto";    break;
                case "09": mes = "Setembro";  break;
                case "10": mes = "Outubro";   break;
                case "11": mes = "Novembro";  break;
                case "12": mes = "Dezembro";  break;
                default: break;}

                return mes;
            }

            function pegaData() {

                var dataAtualizada = dataFormatada();
                var pegaData = dataAtualizada;
                tbody(pegaData);

                $('button[id*="filtrarData_"]').click(function() {
                    var pegaData = $(this).val();
                    tbody(pegaData);
                });
            };

            function tbody(date) {
                var urlData = "datas/" + date;

                $('.loaderDataBg').show();

                $.ajax({
                    url : urlData,
                    beforeSend : function() {},
                    success : function(retorno) {

                        var obj = JSON.parse(retorno);

                        var mesAnt = obj.dataAntUrl.substring(0, 2);
                        var mesAtu = obj.dataAtuUrl.substring(0, 2);
                        var mesPos = obj.dataPosUrl.substring(0, 2);

                        $('#dataPrev').html(stringMes(mesAnt) + " de " + obj.dataAntUrl.substring(3, 7));
                        $('#filtrarData_Ant').val(obj.dataAntUrl);

                        $('#dataAtu').html(stringMes(mesAtu) + " de " + obj.dataAtuUrl.substring(3, 7));
                        $('#filtrarData_Atu').val(obj.dataAtuUrl);

                        $('#dataPost').html(stringMes(mesPos) + " de " + obj.dataPosUrl.substring(3, 7));
                        $('#filtrarData_Pos').val(obj.dataPosUrl);

                        $('.loaderDataBg').fadeOut();
                    },
                    error : function(a, b, c) {

                        $('#erroData').fadeToggle();
                        $('.loaderDataBg').fadeToggle();


                        setTimeout(function() {

                            $('#erroData').fadeToggle();

                            alert('Erro: ' + a[status] + ' ' + c);

                        }, 5000); 
                    }
                });
            };

            function formatCurrency(){
                Number.prototype.format = function(n, x, s, c) {
                    var re = '\\d(?=(\\d{' + (x || 3) + '})+' + (n > 0 ? '\\D' : '$') + ')',
                        num = this.toFixed(Math.max(0, ~~n));

                    return (c ? num.replace('.', c) : num).replace(new RegExp(re, 'g'), '$&' + (s || ','));
                };
            };
        });    

    </script>

A documentação de saída do datatable está aqui: https://editor.datatables.net/manual/server

solução!

Resolvido!

HttpServletRequest request, String action, @PathVariable("id") Long id) {

        Map<String, String[]> map = request.getParameterMap();

        for (Entry<String, String[]> entry : map.entrySet()) {

                String key = entry.getKey();
                String[] values = entry.getValue();

                for (String valor : values) {
                // iterei sobre os valores obtidos
                }
            }