O que retornar se o método do controlador Spring MVC não retornar valor?

135

Estou usando o jQuery $.getJSON()para fazer chamadas assíncronas para o meu back-end simples do Spring MVC. A maioria dos métodos do controlador Spring é assim:

@RequestMapping(value = "/someURL", method = RequestMethod.POST)
public @ResponseBody SomePOJO getSomeData(@ModelAttribute Widget widget,
    @RequestParam("type") String type) {
    return someDAO.getSomeData(widget, type);
}   

Eu tenho as coisas configuradas para que cada controlador retorne o @ResponseBody como JSON, que é o que o lado do cliente espera.

Mas o que acontece quando uma solicitação não deve retornar nenhum conteúdo para o lado do cliente? Posso ter:

@RequestMapping(value = "/updateSomeData" method = RequestMethod.POST)
public @ResponseBody void updateDataThatDoesntRequireClientToBeNotified(...) {
    ...
}

Caso contrário, qual é a sintaxe apropriada para usar aqui?

IAmYourFaja
fonte
Presumo que, se você não retornar nada, não haverá conteúdo enviado de volta?
arahant
1
Eu acho que ainda retornaria um POJO de algum tipo, mesmo que na versão 1 da sua solução apenas envolva um booleano "sucesso" ou algo semelhante. Então você tem um padrão consistente em todos os seus métodos AJAX, e algo que é mais fácil de construir sobre quando ele sair você fazer necessidade de retorno alguma coisa!
22612
Ao contrário do que as respostas são sugestões, o que você teve no seu segundo snippet é perfeitamente correto e a maneira correta de lidar com os POSTdados.
Brett Ryan
Nesse caso, ele retornará nulo. @RestController classe pública RESTControllerExample {@RequestMapping (value = "/ employee", método = RequestMethod.GET) public void getEmployeeNames () {EmployeeSource.getEmployees (); System.out.println ("pronto"); }}
spandey

Respostas:

256

você pode retornar nulo e, em seguida, marcar o método com @ResponseStatus (value = HttpStatus.OK), não é necessário @ResponseBody

@RequestMapping(value = "/updateSomeData" method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK)
public void updateDataThatDoesntRequireClientToBeNotified(...) {
    ...
}

Somente os métodos get retornam uma implicação de código de status 200; todos os outros que você faz fazem uma de três coisas:

  • Retorne nulo e marque o método com @ResponseStatus(value = HttpStatus.OK)
  • Retorne um objeto e marque-o com @ResponseBody
  • Retornar uma HttpEntityinstância
ams
fonte
2
Caso a exceção de tempo de execução ocorra no meio, o HTTP 500 será retornado e não 200. Portanto, se o seu front end manipular uma falha, a mensagem de exceção / erro será exibida corretamente.
Lee Chee Kiam
27
Na verdade, você não precisa definir @ResponseStatuse não deve. Simplesmente ter @ResponseBodyum voidmanipulador é suficiente.
Brett Ryan
11
Eu acho que vai ser melhor para retornar um 204 Nenhum conteúdo em vez de um 200 para métodos vazios
raspacorp
1
O @raspacorp 200 está correto para o POST, pois não tem um corpo.
Brett Ryan
8
@BrettRyan apenas como comentário, pelo menos para uma API REST, é uma prática comum que um POST seja usado para criar conteúdo. Nesse caso, geralmente retorna o ID da (s) entidade (s) criada (s), das entidades criadas ou do link para a operação de leitura. Um retorno de status 200 sem conteúdo pode ser confuso da perspectiva da API REST.
Raspacorp
43

Você pode simplesmente retornar um ResponseEntity com o cabeçalho apropriado:

@RequestMapping(value = "/updateSomeData" method = RequestMethod.POST)
public ResponseEntity updateDataThatDoesntRequireClientToBeNotified(...){
....
return new ResponseEntity(HttpStatus.OK)
}
Biju Kunjummen
fonte
Caso alguém tenha encontrado o mesmo problema que eu, isso não funcionava em uma versão mais antiga do spring (4.1.1), eu receberia 500 erros. Eu atualizei para 4.2.0 e isso funciona muito bem
molho
Essa é a minha maneira preferida de retornar 200 vazios também. Desde o Spring 4.1, use o padrão do construtor: return ResponseEntity.ok (). Build ();
GreenTurtle
3
Embora pareça compilar, ele dá o seguinte avisoResponseEntity is a raw type. References to generic type ResponseEntity<T> should be parameterized
Gonzalo.-
8

Você pode retornar o objeto "ResponseEntity". O uso do objeto "ResponseEntity" é muito conveniente no momento da construção do objeto de resposta (que contém o Corpo da Resposta e o Código de Status HTTP) e no momento da obtenção de informações do objeto de resposta.

Métodos como getHeaders (), getBody (), getContentType (), getStatusCode () etc facilitam muito o trabalho de ler o objeto ResponseEntity.

Você deve usar o objeto ResponseEntity com um código de status http 204 (Sem conteúdo), que é especificamente para especificar que a solicitação foi processada corretamente e que o corpo da resposta está intencionalmente em branco. O uso de códigos de status apropriados para transmitir as informações corretas é muito importante, especialmente se você estiver criando uma API que será usada por vários aplicativos clientes.

Harley
fonte
3
configuração @ResponseStatus(HttpStatus.NO_CONTENT)resolvido XML Parsing Error: no root element foundpara mim no navegador
aliopi
3

Sim, você pode usar @ResponseBody com o voidtipo de retorno:

@RequestMapping(value = "/updateSomeData" method = RequestMethod.POST)
@ResponseBody
public void updateDataThatDoesntRequireClientToBeNotified(...) {
    ...
}
user1338062
fonte
1
então qual será o tipo de retorno .. é o código de status HTTP?
Spandey
@techBeginner Nesse caso, 200 (OK).
Lakatos Gyula
2

Não há nada errado em retornar um nulo @ResponseBodye você deve POSTsolicitar.

Use códigos de status HTTP para definir erros nas rotinas do manipulador de exceções, pois outros estão mencionando o status de sucesso. Um método normal, como você tem, retornará um código de resposta 200que é o que você deseja; qualquer manipulador de exceções poderá retornar um objeto de erro e um código diferente (ou seja 500).

Brett Ryan
fonte
1

Mas à medida que seu sistema cresce em tamanho e funcionalidade ... acho que retornar sempre um json não é uma má idéia. É mais uma questão de arquitetura / "design em grande escala".

Você pode pensar em manter sempre um JSON com dois campos conhecidos: código e dados. Onde código é um código numérico que especifica o sucesso da operação a ser realizada e dados são quaisquer dados adicionais relacionados à operação / serviço solicitado.

Vamos lá, quando usamos um provedor de serviços de back-end, qualquer serviço pode ser verificado para ver se funcionou bem.

Então, eu permaneço, para não permitir que a primavera gerencie isso, expondo operações de retorno híbridas (alguns retornam dados e nada ...) .. instaed certifique-se de que seu servidor exponha uma interface mais homogênea. É mais simples no final do dia.

Vencedor
fonte
0

Aqui está o código de exemplo que eu fiz para um método assíncrono

@RequestMapping(value = "/import", method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK)
public void importDataFromFile(@RequestParam("file") MultipartFile file) 
{
    accountingSystemHandler.importData(file, assignChargeCodes);
}

Você não precisa retornar nada do seu método, tudo o que precisa para usar esta anotação, para que seu método retorne OK em todos os casos

@ResponseStatus(value = HttpStatus.OK)
AbdusSalam
fonte