返回文件或纯文本

时间:2014-05-08 09:01:50

标签: java rest jax-rs

我必须使用url在用户访问数据中创建一个休息Web服务。 Url有一个名为format的查询参数,可以是textfile。如果用户选择text作为format,则必须将文本数据返回给浏览器,或者如果用户选择file作为format,则返回文件供用户下载。我怎样才能做到这一点?

到目前为止我尝试过的(不工作):

@GET
@Produces({MediaType.TEXT_PLAIN, MediaType.APPLICATION_OCTET_STREAM})
@Path("/some_path")
public Response some_path (@Context HttpServletRequest request) {
    String format = null;
    if(request.getParameterValues("format") != null && request.getParameterValues("format")[0] != null) {
        format = request.getParameterValues("format")[0].toString(); 
    }
    else {
        format = "text";
    }
    File file = new File("/some/file/path.txt");
    if(format.equals("text")) {
        return Response.status(200).entity("sending some text").build();
    } else {
        return Response.ok(file, MediaType.APPLICATION_OCTET_STREAM).header("content-disposition","attachment; filename = result.txt").build();
    }
}

上面的代码format=text正常运行但format=file引发HTTP Status 406 null错误。

提前致谢

2 个答案:

答案 0 :(得分:0)

您获得的HTTP状态是

406 Not Acceptable

引用Wikipedia

  

请求的资源只能根据请求中发送的Accept标头生成不可接受的内容。

因此,您的客户端不会发送

的HTTP标头
Accept: text/plain

Accept: application/octet-stream

或任何组合。检查您的客户端及其发送的标头。

答案 1 :(得分:0)

你正在混合方法。第一个,非常流行但不标准化,通过使用format参数提供请求路径中的预期结果的提示(顺便说一下,您可以使用@QueryParam("format") String format而不是从ServletRequest中提取它)。第二种方法是HTTP内容协商机制,在这种情况下使用Accept/Content-Type标头。此机制由基于@Produces注释和提供者类的JAX-RS实现处理。

现在,您的用户不仅需要设置format,还需要设置Accept标头。您似乎正在使用设置Accept的客户端,其中一个值为text/plain。这就是为什么第一种情况正常,但没有application/octet-stream*/*(全部),所以JAX-RS期望客户端无法处理这样的内容而是发送他错了406 Not Acceptable

此处的解决方案是删除@Produces注释(您是负责响应格式的注释),或删除format参数并让JAX-RS执行他的操作工作(可能你需要注册自己的提供者)。但是,如果您继续使用您的解决方案,那么请确保在请求中发送正确或不发送的Accept标头(没有标头意味着:“我会接受您发送的任何内容”)。