我已经使用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();
}
}
答案 0 :(得分:2)
通常,最好将方法声明为返回Response
对象而不是用户定义的类型,并将数据设置为实体。然后,如果您想表明发生了异常,您可以将该异常作为您要返回的Response
的实体传递。
e.g。
@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);
或者您也可以使用Response
方法将其从readEntity()
中删除:
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
答案 1 :(得分:2)
如果使用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);
}
答案 2 :(得分:1)
在webapplication excemption中使用响应对象。它应该工作。
来自java docs:
WebApplicationException(String message) 使用空白消息和默认HTTP状态代码500构建新实例。
这是一条空白信息。我自己还没试过。我想这就是问题所在。
https://jersey.java.net/apidocs/2.6/jersey/javax/ws/rs/WebApplicationException.html
答案 3 :(得分:-1)
即使在所有建议之后我也无法将异常抛给客户端。 所以我所做的是将一个String属性放在我的返回类中,所以当服务器端发生异常时,这个String将包含异常消息,我可以在客户端上获取它。