我必须使用url在用户访问数据中创建一个休息Web服务。 Url有一个名为format
的查询参数,可以是text
或file
。如果用户选择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
错误。
提前致谢
答案 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标头(没有标头意味着:“我会接受您发送的任何内容”)。