Ultimamente tenho trabalhado em um projeto com arquitetura REST e um dos requisitos, e que consigamos integrar e atender de maneira flexivel o maior numero possivel de clients, portanto fornecemos os recursos com diferentes tipos de formatos (media types).Basicamente o client solicita o recurso e informa em qual formato deseja receber a representacao, ou seja, ele negocia o conteudo com o servidor. Para isso o client fara uma requisicao GET e colocara no request header o atributo Accept com o valor desejado: application/xml, application/json e etc...Nosso recurso ira fornecer a representacao de um funcionario e alem dos formatos como xml e json, neste post tambem faremos uma implementacao que representa o funcionario atraves de uma imagem.Caso o cliente consiga trabalhar com mais de um media type, ele pode informar a ordem de prioridade, colocando o media type preferido primeiro, precedido dos menos importantes, separados por virgulaEx: Accept: application/xml, application/jsonCabe esclarecer que caso o client solicite o recurso em um media type que o servidor nao fornece, devera ser retornada uma resposta com o codigo 406 Not Acceptable.Para a implementacao proposta, utilizaremos JAX-RS atraves de sua implementacao padrao Jersey.@Path("/funcionarios")public class FuncionarioResource { @GET @Path("{id}") @Produces({ "application/xml", "application/json" }) public Funcionario getFuncionario(@PathParam("id") Integer id) { Funcionario funcionario = repository.get(id); return funcionario; }}Serei breve nas explicacoes das anotacoes basicas tendo em vista que existem excelentes materiais na web e focarei no necessario para a negociacao de conteudo.A anotacao @Path("/funcionarios") informa a url da nossa RootResource.Em seguida anotamos nosso metodo getFuncionario com a anotacao @GET que informa que este metodo aceita apenas requisicoes feitas pelo metodo GET do http, isso quer dizer que nosso metodo e idempotente, nao importa quantas vezes a requisicao seja feita, ela nao alterara o estado do recurso.Tambem anotamos o metodo com @Path("{id}"), informando que devemos passar o id do funcionario na URI. Para que consigamos acessar o recurso devemos usar o caminho funcionarios/1 por exemplo.Como parametro o metodo espera o id do funcionario. Anotamos esse parametro com @PathParam("id") para que seja injetado na nossa variavel id o valor passado pela URI conforme indicado na anotacao @Path("{id}").Para o assunto tratado a mais importante e a anotacao @Produces({"application/xml", "application/json"}), ela informa que este metodo retorna o nosso recurso tanto em XML quanto JSON dependendo apenas da solicitacao do cliente. A implementacao JERSEY se responsabiliza em parsear o recurso para estes formatos entao precisamos apenas retornar nosso recurso: Funcionario funcionario = repository.get(id);Agora vamos expor nosso recurso como uma imagem. Para isso, precisamos fazer nossa propria implementacao, que e transformar nosso recurso em uma imagem. Neste caso vamos usar o atributo caminhoFoto para buscar a foto e retorna-la como um array de bytes. @GET @Path("{id}") @Produces({ "image/jpeg", "image/jpg" }) public byte[] getPhoto(@PathParam("id") Integer id) { Funcionario funcionario = repository.get(1); try { InputStream is = this.getClass().getResourceAsStream(funcionario.getCaminhoFoto()); BufferedImage img = ImageIO.read(is); ByteArrayOutputStream bao = new ByteArrayOutputStream(); ImageIO.write(img, "jpg", bao); return bao.toByteArray(); } catch (IOException e) { throw new RuntimeException(e); } }Note que sao usadas as mesmas anotacoes no metodo getFuncionario e no getFoto, inclusive o @Path e o mesmo. A unica diferenca e que o metodo getFoto