Spring - Não retorna o jason dos recursos no Postman [RESOLVIDO]

Boa noite, pessoal.
Bom, estou com um problema quando quero mostrar o jason de um comentário criado (post) ou da listagem de comentários (via get), tudo isso vindos da minha API REST.
Sendo que está retornando o seguinte quando faço a requisição com o postman:
Quem puder me ajudar, ficarei muito grato mesmo!!

Está dando esse erro “404 Not Found”, porém há comentários com a determinada ordem de serviço (id = 1).

Classes de Domínio:

@Entity
public class OrdemServico {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;
	
	@ManyToOne
	@JoinColumn(name = "id_Cliente")
	private Cliente cliente;
	
	@Enumerated(EnumType.STRING)
	private OrdemStatusServico status;
	
	@Column(name = "descricao")
	private String descricao;
	
	@Column(name = "preco")
	private BigDecimal preco;

	@Column(name = "data_abertura")
	private OffsetDateTime dataAbertura;

	@Column(name = "data_finalizacao")
	private OffsetDateTime dataFinalizacao;
	
	@OneToMany(mappedBy = "ordemServico")
	private List<Comentario> comentarios = new ArrayList<>();
	
	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	
	public Cliente getCliente() {
		return cliente;
	}
	public void setCliente(Cliente cliente) {
		this.cliente = cliente;
	}	
	
	public OrdemStatusServico getStatus() {
		return status;
	}
	public void setStatus(OrdemStatusServico status) {
		this.status = status;
	}
	
	public String getDescricao() {
		return descricao;
	}
	public void setDescricao(String descricao) {
		this.descricao = descricao;
	}
	
	public BigDecimal getPreco() {
		return preco;
	}
	public void setPreco(BigDecimal preco) {
		this.preco = preco;
	}
	
	public OffsetDateTime getDataAbertura() {
		return dataAbertura;
	}
	public void setDataAbertura(OffsetDateTime dataAbertura) {
		this.dataAbertura = dataAbertura;
	}
	
	public OffsetDateTime getDataFinalizacao() {
		return dataFinalizacao;
	}
	public void setDataFinalizacao(OffsetDateTime dataFinalizacao) {
		this.dataFinalizacao = dataFinalizacao;
	}
	
	public List<Comentario> getComentarios() {
		return comentarios;
	}
	public void setComentarios(List<Comentario> comentarios) {
		this.comentarios = comentarios;
	}

	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		OrdemServico other = (OrdemServico) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		return true;
	}
}

//------------- comentario -------------

@Entity
public class Comentario {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;
	
	@ManyToOne
	@JoinColumn(name = "id_Ordem_servico")
	private OrdemServico ordemServico;
	
	@Column(name = "descricao")
	private String descricao;
	
	@Column(name = "data_envio")
	private OffsetDateTime dataEnvio;
	
	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	
	public OrdemServico getOrdemServico() {
		return ordemServico;
	}
	public void setOrdemServico(OrdemServico ordemServico) {
		this.ordemServico = ordemServico;
	}
	
	public String getDescricao() {
		return descricao;
	}
	public void setDescricao(String descricao) {
		this.descricao = descricao;
	}
	
	public OffsetDateTime getDataEnvio() {
		return dataEnvio;
	}
	public void setDataEnvio(OffsetDateTime dataEnvio) {
		this.dataEnvio = dataEnvio;
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		return result;
	}
	
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		
		Comentario other = (Comentario) obj;
		
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		
		return true;
	}
}

Controladores REST de Comentário:

@Controller
@RequestMapping("/ordens-servico/{ordemServicoId}/comentarios")
public class ComentarioController {
	
	@Autowired
	private ModelMapper modelMapper;
	
	@Autowired
	private OrdemServicoRepository ordemServicoRepository;
	
	@Autowired
	private GestaoOrdemServicoService gestaoOrdemServicoService;

	
	@GetMapping
	public List<ComentarioRepresentationModel> listar(@PathVariable Long ordemServicoId) {
		
		OrdemServico ordemServico = ordemServicoRepository.findById(ordemServicoId)
				.orElseThrow(() -> new EntidadeNaoEncontradaException("Ordem de serviço não encontrada."));
		
		return toCollectionModel( ordemServico.getComentarios() );
	}
	
	
	@PostMapping
	@ResponseStatus(HttpStatus.CREATED)
	public Comentario adicionar(@PathVariable Long ordemServicoId, 
			@Valid @RequestBody ComentarioInputRepresentationModel comentarioInput) {
		
		return gestaoOrdemServicoService.adicionarComentario(ordemServicoId, 
				comentarioInput.getDescricao());
	}
	
	public ComentarioRepresentationModel toModel(Comentario comentario) {
		return modelMapper.map(comentario, ComentarioRepresentationModel.class);
	}
	
	public List<ComentarioRepresentationModel> toCollectionModel(List<Comentario> listaComentarios) {
		List<ComentarioRepresentationModel> collectionModel = new ArrayList<>();
		
		for (Comentario comentario : listaComentarios) {
			collectionModel.add( toModel(comentario) );
		}
		
		return collectionModel;
	}
}

OrdemServicoRepository para fazer operações com o banco:

package com.algaworks.osworks.domain.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.algaworks.osworks.domain.model.OrdemServico;

@Repository
public interface OrdemServicoRepository extends JpaRepository<OrdemServico, Long>  {
	
}

GestaoOrdemServicoService para implementação de regras de negócio:

@Service
public class GestaoOrdemServicoService {

@Autowired
private ComentarioRepository comentarioRepository;

@Autowired
private OrdemServicoRepository ordemServicoRepository;

@Autowired
private ClienteRepository clienteRepository;

public OrdemServico criar(OrdemServico ordemServico) {

	Long idCliente = ordemServico.getCliente().getId();

	Cliente cliente = clienteRepository.findById(idCliente)
			.orElseThrow(() -> new NegocioException("Cliente não encontrado."));
	
	ordemServico.setCliente(cliente); //resolve o problema dos dados do cliente vierem nulos
	ordemServico.setStatus(OrdemStatusServico.ABERTA);
	ordemServico.setDataAbertura(OffsetDateTime.now());
	
	return ordemServicoRepository.save(ordemServico);
}

public Comentario adicionarComentario(Long ordemServicoId, String descricao) {
	OrdemServico ordemServico = buscar(ordemServicoId);
	
	Comentario comentario = new Comentario();
	comentario.setOrdemServico(ordemServico);
	comentario.setDescricao(descricao);
	comentario.setDataEnvio(OffsetDateTime.now());
	
	return comentarioRepository.save(comentario);
}

public OrdemServico buscar(Long ordemServicoId) {
	return ordemServicoRepository.findById(ordemServicoId)
			.orElseThrow(() -> new EntidadeNaoEncontradaException("Ordem de serviço não encontrada."));
}

}

Tabelas do banco em forma lógica:

ordem_servico ( id , id_Cliente , descricao , preco , status , data_abertura , data_finalizacao )
comentario ( id , id_Ordem_Servico , descricao , data_envio )

É um projeto spring-boot? Se sim, como está o seu application.yaml (ou application.properties) do seu projeto?

Para teste, mude de @Controller para @RestController.

1 curtida

É um projeto Spring Boot.
Nossa mano, era só corrigir para RestController mesmo que deu certo aqui! Cara, muito obrigado mesmo, estava a um dia tentando resolver e nada kk.

1 curtida

Uma dúvida agora que me surgiu aqui, qual seria a diferença dessas duas anotações, RestController para Controller ? Seria apenas um para teste e outro para produção mesmo ?

O @RestController é para trabalhar com requisições no padrão REST (geralmente trafegando conteúdo json). Apenas @Controller é usado em requisições feitas por formulário html que geralmente retorna uma página completa para ser renderizada pelo navegador.

1 curtida