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

Resolver exceção: Could not find acceptable representation

Como posso resolver essa exceção?

        JSONObject jo = new JSONObject();
        JSONArray jr = new JSONArray();
        jr.put(getDespesas);
        jo.put("data:", jr);
        return ResponseEntity.status(HttpStatus.OK).body(jo);
org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
    at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:251)
    at org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor.handleReturnValue(HttpEntityMethodProcessor.java:183)
    at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:81)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:126)
    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$VirtualFilterChain.doFilter(FilterChainProxy.java:316)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:126)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:122)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
19 respostas

O padrão indica que a chamada da api, feita pelo cliente, não indicou que ele aceitava json como resposta.

Olá Alberto, tomara que me retorne e não deixe um aluno no vácuo com em outras questões. O meu método esta com essa assinatura:

@RequestMapping(value = "listOne{id}", method = { RequestMethod.GET, RequestMethod.POST }, produces = "application/json")
    public @ResponseBody Object getListDepesasOne(HttpServletRequest request,
            String action, @PathVariable("id") Long id, @AuthenticationPrincipal UsuarioLogado logado) throws JSONException {

Como devo assinar para aceitar esse tipo de retorno?

Parece que o erro indica que a chama do cliente não aceita json como resposta, foi isso que eu entendi.

Uma outra coisa que pode ser, é que você está passando o ObjectArray direto no body, o interessante é você transformar para String.

Da uma olhada na String retornada, uma representação do objeto = "[\"Entity of type br.com.clipboard.financeiro.entity.MinhasDespesas with id: 3\"]". transformei para String no body!

Essa String não é um json valido, talvez esse seja o problema. você precisa procurar um método que gere o json válido.

O que estou tentando fazer é colocar um único objeto dentro de uma array. O único objeto esta assim:

{
    "iTotalRecords": 0,
    "iTotalDisplayRecords": 0,
    "data": {
        "id": 1,
        "descricaoDespesa": "Despesa 1",
        "dataDespesa": {
            "year": 2018,
            "month": "FEBRUARY",
            "monthValue": 2,
            "dayOfMonth": 8,
            "hour": 10,
            "minute": 26,
            "second": 9,
            "nano": 0,
            "dayOfWeek": "THURSDAY",
            "dayOfYear": 39,
               ...
    }
}

e preciso dele assim , por isso as alterações no método para tentar resolver esse problema, colocar as informações de data dentro de um array.

{
    "iTotalRecords": 0,
    "iTotalDisplayRecords": 0,
    "data": [ {
        "id": 1,
        "descricaoDespesa": "Despesa 1",
        "dataDespesa": {
            "year": 2018,
            "month": "FEBRUARY",
            "monthValue": 2,
            "dayOfMonth": 8,
            "hour": 10,
            "minute": 26,
            "second": 9,
            "nano": 0,
            "dayOfWeek": "THURSDAY",
            "dayOfYear": 39,
               ...
    } ]
}

Quando é para gerar uma lista esta prefeito e tenho o método para isso:

// Lista as despesas por mes/ano
    @RequestMapping(value = "listMesAno", method = RequestMethod.GET, produces = "application/json")
    public @ResponseBody ResponseEntity<DataTableMinhasDespesas> getMesAno(
            @AuthenticationPrincipal UsuarioLogado logado) {

        Long id1 = (long) 1; // Passa o valor para recuperar o ID
        Long usuarioId = logado.getId();
        AtualizaMesAno aMesAnoId = mesAnoService.findId(id1);

        String mes1 = aMesAnoId.getMes();
        String ano1 = aMesAnoId.getAno();
        List<MinhasDespesas> listMinhasDespesas = despesasService.buscarPorAno(usuarioId, mes1, ano1);

        DataTableMinhasDespesas dataTableMinhasDespesas = new DataTableMinhasDespesas();
        dataTableMinhasDespesas.setData(listMinhasDespesas);

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

mas para apenas um item da lista não vi outra solução...

Não pode retornar uma representação de uma despesa então?

uma despesa retorno tranquilamente, mas o formato do json é que é o problema como postei, nesse formato tudo certo:

{
    "iTotalRecords": 0,
    "iTotalDisplayRecords": 0,
    "data": {
        "id": 1,
        "descricaoDespesa": "Despesa 1",
        "dataDespesa": {
            "year": 2018,
            "month": "FEBRUARY",
             ...
    }
}

mas não consigo alterar para esse outro formato:

{
    "iTotalRecords": 0,
    "iTotalDisplayRecords": 0,
    "data": [ {
        "id": 1,
        "descricaoDespesa": "Despesa 1",
        "dataDespesa": {
            "year": 2018,
            "month": "FEBRUARY"
              ...
    } ]
}

Então, você pode criar.uma classe que represente exatamente esse formato. Aí você passa o objeto base e popula o que precisa.

eu já tenho a classe que representa o outro formato:

public class DataTableMinhasDespesasOne extends AbstractPersistable<Long>{
    int iTotalRecords;
    int iTotalDisplayRecords;
    String sEcho;
    String sColumns;
    @OneToOne
    MinhasDespesas data;
    //ggas

se eu colocar o tipo List<> para minhasDespesas data, entra no outro formato que te falei daí é gerado um lista das despesas, e como faço para colocar apenas uma despesa dentro dessa lista?

Crie um objeto dessa classe e não coloque numa lista. Retorne direto.

O meu controller que me parece que tem o que vc pediu. Da uma olhada por favor!

    // Lista todas as despesas
    @RequestMapping(value = "listAll{id}", method = { RequestMethod.GET,
            RequestMethod.POST }, produces = "application/json")
    public @ResponseBody Object getListDepesas(@PathVariable("id") Long id, HttpServletRequest request, String action,
            @AuthenticationPrincipal UsuarioLogado logado) {

        Long userId = logado.getId();

        Usuario usuario = usuarioService.findById(userId);

        List<MinhasDespesas> listAllMinhasDespesas = despesasService.findByUsuario(usuario);
        DataTableMinhasDespesas dataTableMinhasDespesas = new DataTableMinhasDespesas();


        dataTableMinhasDespesas.setData(listAllMinhasDespesas);
        dataTableMinhasDespesas.setiTotalDisplayRecords(listAllMinhasDespesas.size());
        dataTableMinhasDespesas.setiTotalRecords(listAllMinhasDespesas.size());

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

Setei na assinatura do método Object e no retorno o objeto da classe , retornou no mesmo formato...

Tentei ArrayList e também nada, será que pode ajudar, ou passar para outra pessoa que possa...?

Opa. Pegue um objeto da sua lista, Monte o outro objeto da classe DatatableMinhasDespesas e retorne no metodo. Quando você acessa o endpoint o que é gerado?

Esse é um projeto particular, como não temos nenhuma referência é mais complicado mesmo. Os outros alunos podem tentar te ajudar também, mas como eu disse, quanto mais especifico, mais difícil.

Amanha eu tento colaborar mais na sua dúvida

é gerado o json no formato que ja tenho, e preciso do json com saída em outro formato: com o data dentro de um array:

{
    "iTotalRecords": 0,
    "iTotalDisplayRecords": 0,
    "data": [ {
        "id": 1,
        "descricaoDespesa": "Despesa 1",
        "dataDespesa": {
            "year": 2018,
            "month": "FEBRUARY"
              ...
    } ]
}

Resolvi aqui Alberto, Obrigado pela ajuda

Opa, pode compartilhar? Criou uma classe específica para o formato que você precisa?

solução!

Opa, com prazer. Da minha classe MinhasDespesas criei uma instância que recebe uma lista onde faço um pesquisa por id e usuario, retornando apenas um objeto:

List<MinhasDespesas> listAllMinhasDespesas = despesasService.findByIdByUsuario(id, usuario);

e apenas setei a lista na classe que retorna o formato de JSON que precisava:

DataTableMinhasDespesas dataTableMinhasDespesas = new DataTableMinhasDespesas();
        dataTableMinhasDespesas.setData(listAllMinhasDespesas);

no retorno do método retorno o objeto dessa classe.