Solucionado (ver solução)

Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

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.