基于 REST 的简单程序中的 HTTP 500 内部服务器错误。混淆 GET 和 POST 而 receiving/sending 来自服务器的响应
HTTP 500 Internal Server Error in simple REST based program. Confused in GET and POST while receiving/sending response from server
我是第一次使用 REST 服务实现基本的客户端服务器架构。这次我通过包含更多 classes 和服务以及共享 class 对象作为客户端和服务器之间的参数来使它变得更加复杂。我是 ApacheTomcat7 上的 运行 服务器。它正在成功执行。当我是 运行 我的客户时,它给我错误:javax.ws.rs.InternalServerErrorException: HTTP 500 Internal Server Error
我尝试调试我的代码,似乎我没有正确地 receiving/sending 响应。我知道在这里分享所有 classes 是不明智的,但我别无选择,因为它浪费了我很多时间。任何帮助将不胜感激。提前致谢。
以下是我的 ImageProgress class。此 class 存在于服务器和客户端。
@XmlRootElement
public class ImageProgress{
private String name;
public ImageProgress( String image_name){
this.name = image_name;
}
public String getName() {
return name;
}
public void setName( String name ){
this.name = name;
}
}
HPCResponse 是 class 其对象将作为服务器响应 returned 到客户端。 HPCResponse 基本上 return ImageProgress 对象,它将给我预期的结果。
@XmlRootElement
public class HPCResponse
{
private ImageProgress imgProgress;
public ImageProgress getImgProgress() {
return imgProgress;
}
public void setImgProgress(ImageProgress imgProgress) {
this.imgProgress = imgProgress;
}
}
以下是来自名为 HpcService 的服务器的服务 class,它将 return HPCResponse 的对象作为响应。如您所见,方法 startAnalysing 接受 HPCInfo 的对象。下面也给出了 HPCInfo 的说明。
@Path( "/hpc" )
@Consumes( MediaType.APPLICATION_XML )
@Produces( MediaType.APPLICATION_XML )
public class HpcService{
public HPCInfo hpcInfo;
public HPCResponse hpcResponse;
@POST
@Path( "/analyze" )
public HPCResponse startAnalysing(HPCInfo _hpcInfo){
System.out.println( "Started Analyzing..." );
hpcInfo = _hpcInfo;
hpcInfo.getImagePath();
hpcResponse = new HPCResponse();
ImageProgress iProg = new ImageProgress(hpcInfo.getImagePath());
hpcResponse.setImgProgress(iProg);
System.out.println("Returning response...");
return hpcResponse;
}
}
HPCInfo class 也在客户端和服务器上。 HPCInfo class:
@XmlRootElement
public class HPCInfo
{
private String imagePath = "";
public String getImagePath(){
return imagePath;
}
public void setImagePath( String imagePath ){
this.imagePath = imagePath;
}
}
最后是我的客户调用 HPCService。
public class TestClient {
private static String webServiceURI = "http://localhost:8080/TestServer123";
public static void main(String[] args) {
String input = "ABNKidney.scn";
ClientConfig clientConfig = new ClientConfig();
Client client = ClientBuilder.newClient(clientConfig);
URI serviceURI = UriBuilder.fromUri(webServiceURI).build();
WebTarget webTarget = client.target(serviceURI);
HPCInfo info = new HPCInfo();
info.setImagePath(input);
webTarget = webTarget.path("test").path("hpc").path("analyze");
HPCResponse hResponse = webTarget.request().accept(MediaType.APPLICATION_XML).post(Entity.entity(info, MediaType.APPLICATION_XML), HPCResponse.class);
}
}
这是我得到的完整错误描述:
javax.ws.rs.InternalServerErrorException: HTTP 500 Internal Server Error
at org.glassfish.jersey.client.JerseyInvocation.convertToException(JerseyInvocation.java:968)
at org.glassfish.jersey.client.JerseyInvocation.translate(JerseyInvocation.java:795)
at org.glassfish.jersey.client.JerseyInvocation.access0(JerseyInvocation.java:91)
at org.glassfish.jersey.client.JerseyInvocation.call(JerseyInvocation.java:683)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:424)
at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:679)
at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:435)
at org.glassfish.jersey.client.JerseyInvocation$Builder.post(JerseyInvocation.java:338)
at com.TestClient.main(TestClient.java:34)
调试此类问题的一种方法是创建一个简单的 ExceptionMapper
来捕获未映射的异常。当没有映射器时,异常通常会冒泡到容器级别,这只会给我们一般的 500 服务器错误(大多数时候帮助不大)。
@Provider
public class DebugExceptionMapper implements ExceptionMapper<Exception> {
@Override
public Response toResponse(Exception exception) {
exception.printStackTrace();
return Response.serverError().entity(exception.getMessage()).build();
}
}
然后注册映射器。当运行用你的ImageProgress
class进行简单测试时,当抛出异常时,打印堆栈跟踪,你可以看到异常消息
...ImageProgress does not have a no-arg default constructor
因此只需将默认值(无参数构造函数)添加到 ImageProgress
class。这是 JAXB 模型的要求。
在class HPCResponse
之前添加这行代码:
@XmlAccessorType(XmlAccessType.FIELD)
我是第一次使用 REST 服务实现基本的客户端服务器架构。这次我通过包含更多 classes 和服务以及共享 class 对象作为客户端和服务器之间的参数来使它变得更加复杂。我是 ApacheTomcat7 上的 运行 服务器。它正在成功执行。当我是 运行 我的客户时,它给我错误:javax.ws.rs.InternalServerErrorException: HTTP 500 Internal Server Error
我尝试调试我的代码,似乎我没有正确地 receiving/sending 响应。我知道在这里分享所有 classes 是不明智的,但我别无选择,因为它浪费了我很多时间。任何帮助将不胜感激。提前致谢。
以下是我的 ImageProgress class。此 class 存在于服务器和客户端。
@XmlRootElement
public class ImageProgress{
private String name;
public ImageProgress( String image_name){
this.name = image_name;
}
public String getName() {
return name;
}
public void setName( String name ){
this.name = name;
}
}
HPCResponse 是 class 其对象将作为服务器响应 returned 到客户端。 HPCResponse 基本上 return ImageProgress 对象,它将给我预期的结果。
@XmlRootElement
public class HPCResponse
{
private ImageProgress imgProgress;
public ImageProgress getImgProgress() {
return imgProgress;
}
public void setImgProgress(ImageProgress imgProgress) {
this.imgProgress = imgProgress;
}
}
以下是来自名为 HpcService 的服务器的服务 class,它将 return HPCResponse 的对象作为响应。如您所见,方法 startAnalysing 接受 HPCInfo 的对象。下面也给出了 HPCInfo 的说明。
@Path( "/hpc" )
@Consumes( MediaType.APPLICATION_XML )
@Produces( MediaType.APPLICATION_XML )
public class HpcService{
public HPCInfo hpcInfo;
public HPCResponse hpcResponse;
@POST
@Path( "/analyze" )
public HPCResponse startAnalysing(HPCInfo _hpcInfo){
System.out.println( "Started Analyzing..." );
hpcInfo = _hpcInfo;
hpcInfo.getImagePath();
hpcResponse = new HPCResponse();
ImageProgress iProg = new ImageProgress(hpcInfo.getImagePath());
hpcResponse.setImgProgress(iProg);
System.out.println("Returning response...");
return hpcResponse;
}
}
HPCInfo class 也在客户端和服务器上。 HPCInfo class:
@XmlRootElement
public class HPCInfo
{
private String imagePath = "";
public String getImagePath(){
return imagePath;
}
public void setImagePath( String imagePath ){
this.imagePath = imagePath;
}
}
最后是我的客户调用 HPCService。
public class TestClient {
private static String webServiceURI = "http://localhost:8080/TestServer123";
public static void main(String[] args) {
String input = "ABNKidney.scn";
ClientConfig clientConfig = new ClientConfig();
Client client = ClientBuilder.newClient(clientConfig);
URI serviceURI = UriBuilder.fromUri(webServiceURI).build();
WebTarget webTarget = client.target(serviceURI);
HPCInfo info = new HPCInfo();
info.setImagePath(input);
webTarget = webTarget.path("test").path("hpc").path("analyze");
HPCResponse hResponse = webTarget.request().accept(MediaType.APPLICATION_XML).post(Entity.entity(info, MediaType.APPLICATION_XML), HPCResponse.class);
}
}
这是我得到的完整错误描述:
javax.ws.rs.InternalServerErrorException: HTTP 500 Internal Server Error
at org.glassfish.jersey.client.JerseyInvocation.convertToException(JerseyInvocation.java:968)
at org.glassfish.jersey.client.JerseyInvocation.translate(JerseyInvocation.java:795)
at org.glassfish.jersey.client.JerseyInvocation.access0(JerseyInvocation.java:91)
at org.glassfish.jersey.client.JerseyInvocation.call(JerseyInvocation.java:683)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:424)
at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:679)
at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:435)
at org.glassfish.jersey.client.JerseyInvocation$Builder.post(JerseyInvocation.java:338)
at com.TestClient.main(TestClient.java:34)
调试此类问题的一种方法是创建一个简单的 ExceptionMapper
来捕获未映射的异常。当没有映射器时,异常通常会冒泡到容器级别,这只会给我们一般的 500 服务器错误(大多数时候帮助不大)。
@Provider
public class DebugExceptionMapper implements ExceptionMapper<Exception> {
@Override
public Response toResponse(Exception exception) {
exception.printStackTrace();
return Response.serverError().entity(exception.getMessage()).build();
}
}
然后注册映射器。当运行用你的ImageProgress
class进行简单测试时,当抛出异常时,打印堆栈跟踪,你可以看到异常消息
...ImageProgress does not have a no-arg default constructor
因此只需将默认值(无参数构造函数)添加到 ImageProgress
class。这是 JAXB 模型的要求。
在class HPCResponse
之前添加这行代码:
@XmlAccessorType(XmlAccessType.FIELD)