[英]How to capture exceptions on a REST client?
我已經使用Jersey實現了其余的web服務,並且每當服務器端發生一些異常時,客戶端就會獲得通用的HTTP 500內部服務器錯誤,而不再有真正異常的信息。 我發現人們通常在服務器端捕獲任何異常,然后拋出WebApplicationException,但即使這樣,客戶端仍然會獲得通用HTTP 500內部服務器錯誤。
這是我的網絡服務:
@PUT
@Produces(MediaType.APPLICATION_XML)
@Consumes(MediaType.APPLICATION_XML)
@Path("/transmitir")
public WrapperTransmissaoRetorno receber(WrapperTransmissao wrapperRecepcao) {
WrapperTransmissaoRetorno retorno = new WrapperTransmissaoRetorno();
retorno.setCodigoMaster(new Random().nextInt());
retorno.setDataRetorno(new Date());
if(true){
throw new WebApplicationException("Este pau eh bem graudo");
}
return retorno;
}
這是調用客戶端的代碼:
try {
WsTransmissaoCliente client = new WsTransmissaoCliente();
WrapperTransmissao wrapperRecepcao = new WrapperTransmissao();
Transferencia transferencia = new Transferencia();
transferencia.setCodigoTabela(23);
transferencia.setCodigoTransferencia(56);
transferencia.setDataRetorno(new Date());
transferencia.setDataTransmissao(new Date(System.currentTimeMillis()+3000000));
transferencia.setNomeTabela("CUPOM");
transferencia.setTipoOperacao(TipoOperacao.UPDATE);
wrapperRecepcao.setTransferencia(transferencia);
Jumento jumento = new Jumento();
jumento.setIdade(24);
jumento.setNome("José");
wrapperRecepcao.setObjeto(jumento);
// Cabrito cabrito = new Cabrito();
// cabrito.setAltura(56);
// cabrito.setPeso(120.0);
// wrapperRecepcao.setObjeto(cabrito);
WrapperTransmissaoRetorno retorno = client.transmitir(wrapperRecepcao);
System.out.println("Retorno do WS: "+retorno);
} catch (Exception e) {
WebApplicationException exx = (WebApplicationException) e;
exx.printStackTrace();
}
如何避免這種情況並獲得真正的例外? 或者至少是消息?
更新這是我作為回復發送的對象:
package br.atualy.integracaocheckout.wrappers;
import java.util.Date;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class WrapperTransmissaoRetorno {
private Date dataRetorno;
private Integer codigoMaster;
public Date getDataRetorno() {
return dataRetorno;
}
public void setDataRetorno(Date dataRetorno) {
this.dataRetorno = dataRetorno;
}
public Integer getCodigoMaster() {
return codigoMaster;
}
public void setCodigoMaster(Integer codigoMaster) {
this.codigoMaster = codigoMaster;
}
@Override
public String toString() {
return "WrapperRecepcaoRetorno{" + "dataRetorno=" + dataRetorno + ", codigoMaster=" + codigoMaster + '}';
}
}
更新2這是客戶:
import br.atualy.integracaocheckout.wrappers.WrapperTransmissao;
import br.atualy.integracaocheckout.wrappers.WrapperTransmissaoRetorno;
import javax.ws.rs.ClientErrorException;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.WebTarget;
public class WsTransmissaoCliente {
private final WebTarget webTarget;
private final Client client;
private static final String BASE_URI = "http://localhost:8080/IntegracaoCheckout/webresources";
public WsTransmissaoCliente() {
client = javax.ws.rs.client.ClientBuilder.newClient();
webTarget = client.target(BASE_URI).path("transmissao");
}
// public String receber() throws ClientErrorException {
// WebTarget resource = webTarget;
// resource = resource.path("receber");
// return resource.request(javax.ws.rs.core.MediaType.APPLICATION_XML).get(String.class);
// }
public WrapperTransmissaoRetorno transmitir(WrapperTransmissao requestEntity) throws ClientErrorException {
return webTarget.path("transmitir")
.request(javax.ws.rs.core.MediaType.APPLICATION_XML)
.put(javax.ws.rs.client.Entity.entity(requestEntity, javax.ws.rs.core.MediaType.APPLICATION_XML), WrapperTransmissaoRetorno.class);
}
public void close() {
client.close();
}
}
通常,最好將方法聲明為返回Response
對象而不是用戶定義的類型,並將數據設置為實體。 然后,如果要指示發生了異常,則可以將該異常作為要返回的Response
的實體傳遞。
例如
@GET
@Path("/foo")
public Response getFoo() {
try {
// do stuff
return Response.ok(someData).build();
} catch (Exception e) {
return Response.serverError().entity(e).build();
}
}
您會注意到,這樣您實際上不會從您的方法中拋出異常,而是返回顯式500響應,並將異常作為實體。 這樣你仍然可以從你的代碼中拋出異常,但它們將得到很好的處理。
我不確定您的客戶端包裝器代碼在做什么,但您可以使用正常的REST客戶端將預期的響應數據類型傳遞到您的調用中:
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://foo.com/foo");
String response = target.request().get(String.class);
或者你也可以使用readEntity()
方法將它從Response
拉出來:
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://foo.com/foo");
Response response = target.request().get();
String entity = response.readEntity(String.class);
聽起來你需要做的是檢查返回代碼,然后根據返回的代碼將實體解析為WrapperTransmissaoRetorno
或WebApplicationException
:
Response response = client.transmitir(wrapperRecepcao);
if (response.getStatus() == Response.Status.OK.getStatusCode()) { // 200
WrapperTransmissaoRetorno retorno = response.readEntity(WrapperTransmissaoRetorno.class);
// do stuff
} else if (response.getStatus() == Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()) { // 500
WebApplicationException e = response.readEntity(WebApplicationException.class);
// do stuff
} // etc for other response codes
如果使用jawax.ws.rs.core.Response
對象。
SERVER ::如果發生異常/失敗,請將其設置為:
// do stuff
// here e.getMessage() can be custom failure message too
response = Response.serverError().entity(e.getMessage()).build();
// return response object
return response;
CLIENT ::在客戶端檢查以下內容:
if(response != null && reponse.getStatus() == Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()) {
String serverErrorMsg = response.readEntity(String.class);
throw new Exception(serverErrorMsg);
}
在webapplication excemption中使用響應對象。 它應該工作。
來自java文檔:
WebApplicationException(String message)使用空白消息和默認HTTP狀態代碼500構造新實例。
這是一個空白的消息。 我自己沒試過。 我想這就是問題所在。
https://jersey.java.net/apidocs/2.6/jersey/javax/ws/rs/WebApplicationException.html
即使在所有建議之后我也無法將異常拋給客戶端。 所以我所做的是將一個String屬性放在我的返回類中,所以當服務器端發生異常時,這個String將包含異常消息,我可以在客戶端上獲取它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.