HTTP 500 Внутренняя ошибка сервера в простой программе на основе REST. Confused в GET и POST во время приема/отправки ответа от сервера

Я реализую базовую архитектуру клиентского сервера, используя службы REST в первый раз. На этот раз я усложнил задачу включения нескольких классов и сервисов с использованием объектов класса в качестве параметров между клиентом и сервером. Я запускаю сервер на ApacheTomcat7. Он успешно выполняется. Когда я запускаю свой клиент, он дает мне ошибку: javax.ws.rs.InternalServerErrorException: HTTP 500 Internal Server Error Я пробовал отлаживать свой код, похоже, что я неправильно получаю/отправляю ответ. Я знаю его неразумную идею делиться всеми классами здесь, но у меня нет выбора, так как он потратил много времени. Любая помощь будет оценена. Заранее спасибо.

Ниже приведен мой класс ImageProgress. Этот класс присутствует как на сервере, так и на клиенте.

@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 - это класс, объект которого будет возвращен клиенту в качестве ответа сервера. HPCResponse будет в основном возвращать объект ImageProgress, который даст мне предполагаемый результат.

@XmlRootElement
public class HPCResponse
{
    private ImageProgress imgProgress;

    public ImageProgress getImgProgress() {
        return imgProgress;
    }

    public void setImgProgress(ImageProgress imgProgress) {
        this.imgProgress = imgProgress;
    }
}

Ниже приведен класс обслуживания с сервера с именем HpcService, который вернет объект 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 также доступен как на клиенте, так и на сервере. Класс HPCInfo:

    @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.access$500(JerseyInvocation.java:91)
    at org.glassfish.jersey.client.JerseyInvocation$2.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)

Ответ 1

Один из способов отладки подобных вещей - создать простой 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, когда выдается исключение, выводится отпечаток стека, и вы можете увидеть сообщение об исключении

... ImageProgress не имеет конструктора по умолчанию без аргументов

Поэтому просто добавьте стандартное значение (конструктор без аргументов) в класс ImageProgress. Это требование к моделям JAXB.

Ответ 2

Добавьте эту строку кода до class HPCResponse:

@XmlAccessorType(XmlAccessType.FIELD)