1
resposta

Como consumir um recurso rest no Spring?

Finalizei a segunda aula do módulo de Spring MVC II e estou tentando testar um serviço Rest. Criei uma JSP qualquer para fazer a chamada:

<a href="/casadocodigo/teste/detalhe/5"><button>Testar JSON - Produto 5</button></a>

No controller, recebo a rquisição e encaminho para o serviço rest com o id do produto. O retorno do rest, que é um produto, encaminho para a view de detalhamento do produto. No entanto, o rest me retorna um objeto vazio.

@RequestMapping("/teste/detalhe/{id}")
    public Callable<ModelAndView> detalheTeste(@PathVariable("id") Integer id) {

        return () -> {

                String uri = "http://localhost:8080/casadocodigo/produtos/detalhe/"+id+".json";

            Produto response = restTemplate.postForObject(uri, new Produto(id), Produto.class);

            ModelAndView modelAndView = new ModelAndView("produtos/detalhe");
            modelAndView.addObject("produto", response);

            return modelAndView;
        };

    }

Estou encaminhando para um rest que é da própria aplicação. No método abaixo, o id chega correto e o objeto é recuperado corretamente.

@RequestMapping("/detalhe/{id}")
    public ModelAndView detalhe(@PathVariable("id") Integer id) {
        ModelAndView modelAndView = new ModelAndView("produtos/detalhe");
        Produto produto = produtoDao.find(id);
        modelAndView.addObject("produto", produto);
        return modelAndView;
    }

O response é um objeto vazio. Se eu testar a URI http://localhost:8080/casadocodigo/produtos/detalhe/5.json em um cliente Rest, o retorno é um JSON.

Alguém poderia me ajudar?

1 resposta

Fala Michael, tudo bem ?

Creio que deva implementar diferente seu serviço rest. Em geral eles devem devolver representações dos objetos usando notações menos específicas que html (retornado por padrão pelo seu template de View - carregado pelo ModelAndView), como um JSON por exemplo.

Exemplo Serviço Rest:

@CrossOrigin
@RestController
@RequestMapping("/rest/service")
public class ProdutoRestController {

    @Autowired
    private ProdutoDao produtoDao;

    @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
    public Iterable<Produto> listAllProducts() {
        return produtoDao.findAll();
    }

    @GetMapping(value = "/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
    public Produto get(@PathVariable Integer id) {
        return produtoDao.findOne(id);
    }

    @PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE, 
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<Produto> save(@RequestBody Produto produto) {
        Produto createdProduct = produtoDao.save(produto);
        return new ResponseEntity<Produto>(createdProduct, HttpStatus.CREATED);
    }
}

Devolvendo representações simples como JSON, mapeando e configurando MediaType de entrada e saída. O Spring vai usar a JacksonJson para serializar para JSON seus objetos retornados pelos métodos do RestController.

Exemplo de consumo:

@Controller
public class ProdutoController {

    private RestTemplate rest = new RestTemplate();

    @GetMapping("/produto/{id}")
    public ModelAndView exibeDetalhes(@PathVariable Integer id) {
        String uri = "http://localhost:8080/rest/service/" + id;
        Produto produto = rest.getForObject(uri, Produto.class);

        ModelAndView modelAndView = new ModelAndView("produto/detalhe");
        modelAndView.addObject("produto", produto);
        return modelAndView;
    }
}

Exemplo de saída no postman:

postman

Espero ter ajudado. Abraço!