Spring Rest Service基于逻辑返回不同的媒体类型

时间:2015-02-13 13:32:01

标签: java spring rest spring-mvc jax-rs

HELP!我已尽力而为,似乎没有任何工作。我的问题如下:

我有一个Spring REST服务,它进行REST调用,接收base64编码的PDF。然后我解码PDF,并在浏览器中显示它。我可以让这部分完美地运作!但!我有处理404s,500s等问题。错误消息。

不幸的是,错误消息在API中作为消息发送给我,如下面的逻辑所示。

我曾尝试创建PDF,但我无法将其转换为文件对象,我试图直接将字节流式传输到浏览器,但无论我做什么,它都不适合我。

有没有办法根据逻辑更改响应标头?如果成功,返回pdf,并在错误时将文本文件返回给浏览器?

我在这里已经筋疲力尽了,不知道该去哪儿。任何建议或指示都将非常感激。

我还试过向浏览器抛出404,但它期待一个pdf文件,我得到了MIME错误。

@Controller
@Path("/mon")
public class WSController {

    @Autowired
    Service service;

    @GET
    @Produces("application/pdf")
    @Path("/ws")
    public File getWs(@QueryParam("vin") String vin) throws IOException, URISyntaxException {
        Map response = service.getWs(vin);
        if (response == null) {
            return createErrorFile("Server Error, please try again later.");
        } else if (response.get("ErrorCode") != null && response.get("ErrorCode").equals("E")) {
            return createErrorFile((String) response.get("ErrorDescription"));
        } else {
            return decodeBase64(((String) response.get("Base64String")).replace("\n",""));
        }
    }

    private File decodeBase64(String encodedFile) throws IOException {
        byte[] decodedBytes = DatatypeConverter.parseBase64Binary(encodedFile);

        File file = new File("wS.pdf");
        FileOutputStream fop = new FileOutputStream(file);

        fop.write(decodedBytes);
        fop.flush();
        fop.close();

        return file;
    }

    private File createErrorFile(String errorDescription) throws IOException {
        //Not sure what to do here
        return null;
    }
编辑:这是最终为我工作的东西。非常感谢您的建议。这是一次很棒的学习经历。

@GET
@Path("/ws")
public Response getWS(@QueryParam("vin") String vin) throws IOException, URISyntaxException {
    Map results = Service.getWS(vin);
    if (results == null) {
        Response.ResponseBuilder rBuild = Response.status(Response.Status.BAD_REQUEST);
        return rBuild.type(MediaType.TEXT_PLAIN)
                .entity("Server error, please try again later.")
                .build();
    } else if (results.get("ErrorCode") != null && results.get("ErrorCode").equals("E")) {
        Response.ResponseBuilder rBuild = Response.status(Response.Status.BAD_REQUEST);
        return rBuild.type(MediaType.TEXT_PLAIN)
                .entity(results.get("ErrorDescription"))
                .build();
    } else {
        File responseData = decodeBase64(((String) results.get("Base64String")).replace("\n", ""));
        Response.ResponseBuilder rBuild = Response.ok(responseData, "application/pdf");
        return rBuild.build();
    }
}

2 个答案:

答案 0 :(得分:1)

不要惊慌:-)您可以通过向Spring请求HttpServletResponse对象来完全控制响应。您可以设置响应的mime类型或设置错误代码:

@GET
@Produces("application/pdf")
@Path("/ws")
public void getWs(@QueryParam("vin") String vin, HttpServletRequest request) {
...
...
request.setContentType("text/html");
...

答案 1 :(得分:1)

我看到你在帖子中提到的一些问题,但我只读了这些实际的问题

  

有没有办法根据逻辑更改响应标头?如果成功,返回pdf,并在错误时将文本文件返回给浏览器?

所以我会解决他们。我自己,我更喜欢总是返回Response。您可以在那里设置所有标题,以及更多内容。例如

@GET
public Response getSomething() {
    ...
    Response.ResponseBuilder builder = Response.status(200);
    Response response = builder.entity(file)
                               .header("Content-Type", "someType")
                               .build();
    return response;
}

entity(...)是您通常作为实体主体返回的内容。

  • 另请参阅Response.ResponseBuilder的API。 Response中的大多数静态方法返回Response.ResponseBuilder,这就是构建请求的许多选项。

对于您的方法中未处理的异常,您可以使用ExceptionMapper(s)来处理不同的异常。见here。您可以从映射器返回Response

您可以编写自定义WebApplicationException(s),以免在响应构建异常时使代码混乱。然后抛出那个例外。 JAX-RS已经有一个内置机制来处理异常。您可以使用内置Response创建例外。该链接有一个例外。处理异常有很多不同的选择。