【问题标题】:restful web services: HTTP Status 500.The server encountered an internal error that prevented it from fulfilling this request errorRESTful Web 服务:HTTP 状态 500。服务器遇到内部错误,阻止它完成此请求错误
【发布时间】:2015-08-21 13:10:57
【问题描述】:

我编写了一个带有 formParam 并返回一个列表的 rest ful web 服务。我在 postman 中测试它。但我收到此错误。HTTP 状态 500。服务器遇到内部错误,阻止它完成此请求错误。 这是我的服务:

@Path("/report")
public class weightingResource {

@POST
@Path("/loadWeightingByPlate")
//@Produces(MediaType.APPLICATION_XML)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public List<Weighting> LoadWeightingInSpecTimeInSpecPlate(
        @FormParam("plate") String plate,
        @FormParam("startTime") String _startTime,
        @FormParam("endTime") String _endTime,
        @Context HttpServletRequest req) {
    Long startTime = new Long(_startTime);
    Long endTime = new Long(_endTime);
    try {
        List<Weighting> weightings = Weighting.LoadWeightingInSpecTimeInSpecPlate(startTime, endTime, plate);
        System.out.println("no error");
        return weightings;
    } catch (Exception ex) {
        System.out.println("Exception = " + ex);
        return null;
    }
}
}

我测试了Weighting.LoadWeightingInSpecTimeInSpecPlate(startTime, endTime, plate) 并且这个工作正常。谁能帮帮我?

堆栈跟踪:

Blockquote21-Aug-2015 17:44:31.133 警告 [http-nio-8084-exec-197] org.glassfish.jersey.servlet.WebComponent.filterFormParameters 对 URI http://127.0.0.1:8084/fsc-access/rest/report/loadWeightingByPlate 的 servlet 请求在请求正文,但请求正文已被 servlet 或访问请求参数的 servlet 过滤器使用。只有使用 @FormParam 的资源方法才能按预期工作。通过其他方式消耗请求正文的资源方法将无法按预期工作。 2015 年 8 月 21 日 17:44:31.210 严重 [http-nio-8084-exec-197] org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo MessageBodyWriter not found for media type=application/xml, type=类 java.util.ArrayList,genericType=java.util.List。

现在我的服务运行良好并且 我编写了一个客户端来使用此服务,但出现错误:HTTP 400 Bad Request :javax.ws.rs.BadRequestException

        String webserviceURI = "http://localhost:8084/fsc-access";

    ClientConfig clientConfig = new ClientConfig();
    Client client = ClientBuilder.newClient(clientConfig);
    URI serviceURI = UriBuilder.fromUri(webserviceURI).build();
    WebTarget webTarget = client.target(serviceURI);
    MultivaluedMap formData = new MultivaluedMapImpl();
    formData.add("plate", plate);
    formData.add("startTime", start.toString());
    formData.add("endTime", end.toString());
    Weightings weightings = new Weightings();
     weightings.getWeightings().addAll((Collection<? extends Weighting>) webTarget.path("rest").path("report").path("loadWeightingByPlate").
            request().accept(MediaType.APPLICATION_XML).post(javax.ws.rs.client.Entity.form(formData), Weightings.class));

我该如何解决?

【问题讨论】:

  • 如果有 500 响应,这通常意味着您的日志中会有堆栈跟踪。请在此处发布堆栈跟踪,以便我们更好地帮助您。
  • 是的,有些事情:我提出了警告

标签: java web-services http post restful-url


【解决方案1】:

首先,以下消息告诉您获得 500 的原因:

2015 年 8 月 21 日 17:44:31.210 严重 [http-nio-8084-exec-197] org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo 未找到媒体类型 = 应用程序/xml、类型 = 类的 MessageBodyWriter java.util.ArrayList, genericType=java.util.List.

这表明 Jersey,即您的 servlet,没有注册的 MessageBodyWriter,它从 isWritable() 返回 true,并带有以下参数

media type=application/xml, 
type=class java.util.ArrayList, 
genericType=java.util.List

AFAIK Jersey 通常可以访问 JAXB 实现,但某些 JAXB 实现无法正确处理像 List 这样的泛型。我建议您创建一个名为Weightings 的新类,它是Weighting 对象集合的列表包装器。这在 JAXB 模型中很常见。

@XmlRootElement
public class Weightings {
    @XmlElement
    private final List<Weighting> weightings = new ArrayList<Weighting>();

    public List<Weighting> getWeightings() {
        return weightings;
    }
}

然后修改你的资源以返回新类型:

@POST
@Path("/loadWeightingByPlate")
@Produces(MediaType.APPLICATION_XML)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Weightings LoadWeightingInSpecTimeInSpecPlate(
        @FormParam("plate") String plate,
        @FormParam("startTime") String _startTime,
        @FormParam("endTime") String _endTime,
        @Context HttpServletRequest req) {
    Long startTime = new Long(_startTime);
    Long endTime = new Long(_endTime);
    try {
        Weightings weightings = new Weightings();
        weightings.getWeightings().addAll( Weighting.LoadWeightingInSpecTimeInSpecPlate(startTime, endTime, plate));
        System.out.println("no error");
        return weightings;
    } catch (Exception ex) {
        System.out.println("Exception = " + ex);
        return null;
    }
}

这应该可以解决您的 500 响应。您的另一个选择是环顾四周并测试可能更好地支持泛型的其他 JAXB 或 application/xml MessageBodyWriter 实现。

您收到的另一个警告:

2015 年 8 月 21 日 17:44:31.133 警告 [http-nio-8084-exec-197] org.glassfish.jersey.servlet.WebComponent.filterFormParameters A 对 URI 的 servlet 请求 http://127.0.0.1:8084/fsc-access/rest/report/loadWeightingByPlate 请求正文中包含表单参数,但请求正文有 被 servlet 或访问请求的 servlet 过滤器使用 参数。只有使用 @FormParam 的资源方法才能作为 预期的。通过其他方式消耗请求正文的资源方法 将无法按预期工作。

如果您有兴趣修复警告,我会查看this question

【讨论】:

  • 非常感谢塞缪尔,这很好。现在我写了一个客户端来使用这个服务。但是当我使用它时,我收到一个 HTTP 400 错误请求:javax.ws.rs.BadRequestException。我把我的客户来源放在我的问题中。你能帮我吗?
  • Fatemeh,你应该为你的新问题打开一个新问题,以便它得到更多关注并且更有可能得到回答
  • 好的,塞缪尔。我在以下位置创建了一个新问题:stackoverflow.com/questions/32147028/…
猜你喜欢
  • 2020-09-26
  • 1970-01-01
  • 2016-08-29
  • 1970-01-01
  • 1970-01-01
  • 2015-03-24
  • 2019-02-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多