简体   繁体   English

JAX-RS,当 POST 失败时,如何获取原始 JSON

[英]JAX-RS, When POST fails, how to get raw JSON

my code uses an external API.我的代码使用外部 API。 When I call it with a correct parameter, I get the expected answer.当我用正确的参数调用它时,我得到了预期的答案。

When I call it with a wrong parameter (wrong in the sense of incorrect job's data, technical is OK), my code throws an Exception.当我用错误的参数调用它时(从不正确的工作数据的意义上来说是错误的,技术上是可以的),我的代码会抛出一个异常。 I was expecting a String containing the data's validation error "sex='3' is wrong".我期待一个包含数据验证错误“sex='3' 错误”的字符串。

The API uses JSON and return JSON. API 使用 JSON 并返回 JSON。 I call it with javax.ws.rs我用 javax.ws.rs 调用它

Here is my method where I call the API这是我调用 API 的方法

    public final String API_URL= "http://sv-t-vtl-pgih-vidal:9900/solfeges/api/v0";

    private void test(String json)
    {
        // The proxy for calling the API.
        SolfegesServices proxy = ProxyFactory.create(SolfegesServices.class, API_URL);

        // 
        try
        {
            // Call the API
            String retourBrut = proxy.callfactureapi(json);

            System.out.println(retourBrut);
        }
        catch (RuntimeException e)
        {
            e.printStackTrace();
        }
    }

Here an other class I use to declare the API这是我用来声明 API 的另一个类

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

import fr.pgih.ope.act.dim.gestionfides.utils.RetourSolfegesException;

@Produces("application/json")
@Consumes("application/json")
public interface SolfegesServices
{
    @POST
    @Path("/factures")
    public String callfactureapi(String json) throws RetourSolfegesException;
}

Those both classes are enought to call the API.这两个类都足以调用 API。

When the API is called with incorrect data, the API returns a JSON with a 422 status.当使用不正确的数据调用 API 时,该 API 会返回状态为 422 的 JSON。 When it happens, the code throws a runtimeException that does not contains API's info about the error.发生这种情况时,代码会抛出一个 runtimeException 异常,其中不包含 API 的错误信息。

How can I get the JSON returned by the API in case of error?如果出现错误,如何获取 API 返回的 JSON?

NB.注意。 In case of success, the JSON looks like如果成功,JSON 看起来像

{
statut:200,
message:"succes",
b2:"some content"
}

In case of failure, I'm expecting something like如果失败,我期待类似

{
statut:422, (or 400)
message:"fail to...",
reason:"sexe='3' is incorrect"
}

I've already dig the whole stackoverflow website and some other without finding a solution to my problems, despite of the amount of similar cases.尽管有很多类似的案例,但我已经挖掘了整个 stackoverflow 网站和其他一些网站,但没有找到解决我的问题的方法。

Everything looks fine if I try to call the API with Postman (external tool to execute web requests).如果我尝试使用 Postman(执行 Web 请求的外部工具)调用 API,一切看起来都很好。

You can return the ResponseEntity from your controller.您可以从控制器返回 ResponseEntity。 The response entity can be based on the validation failure you mention and this json message should be part of the body.响应实体可以基于您提到的验证失败,并且此 json 消息应该是正文的一部分。

ResponseEntity response = ResponseEntity.status(HttpStatus.UNPROCESSABLE_ENTITY).body(jsonMessage).build();

Finally, I integrated API's tool to call it (using Swagger).最后,我集成了 API 的工具来调用它(使用 Swagger)。 And it ... works ... almost perfectly.它......工作......几乎完美。

Finally (the comeback).最后(复出)。 I've surcharged the exception filter to catch them (http statut 400 or 422).我对异常过滤器进行了额外收费以捕获它们(http statut 400 或 422)。

ClientResponseFilter.filter(ClientRequestContext reqCtx, ClientResponseContext resCtx) ClientResponseFilter.filter(ClientRequestContext reqCtx, ClientResponseContext resCtx)

public class ClientResponsesExceptionFilter implements ClientResponseFilter
{

    @Override
    public void filter(ClientRequestContext reqCtx, ClientResponseContext resCtx)
            throws ApiSolfegesException, IOException
    {
        if (resCtx.getStatus() == Response.Status.BAD_REQUEST.getStatusCode() || resCtx.getStatus() == 422)
        {
            ...
        }
    }
}

I use it here我在这里用

@Override
    public ModelApiResponse facturesPost(DossiersPmsi body)
    {

        CustomResteasyJackson2Provider resteasyJacksonProvider = new CustomResteasyJackson2Provider();

        // Ajout d'un Mapper pour gérer la sérialisation et désrialisation json des dates proprement
        ObjectMapper mapper = new ObjectMapper();
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer());
        javaTimeModule.addSerializer(new LocalDateSerializer());
        mapper.registerModule(javaTimeModule);
        resteasyJacksonProvider.setMapper(mapper);

        // ajout d'un filtre pour les exception
        ClientResponsesExceptionFilter filter = new ClientResponsesExceptionFilter();

        // appel de l'api solfeges
        ResteasyClient client = new ResteasyClientBuilder().register(resteasyJacksonProvider)
                .register(filter).build();
        ResteasyWebTarget target = client.target(UriBuilder.fromPath(URL_SOLFEGE));
        FacturesApi proxy = target.proxy(FacturesApi.class);
        return proxy.facturesPost(body);
    }

I also use these to get the JSON from : https://www.codota.com/code/java/methods/javax.ws.rs.client.ClientResponseContext/getEntityStream我还使用这些从以下位置获取 JSON: https : //www.codota.com/code/java/methods/javax.ws.rs.client.ClientResponseContext/getEntityStream

private String getResponseBody(ClientResponseContext context) throws IOException
    {
        // La variable qui contient la description de l'erreur dans un fichier JSON.
        String jsonEchec = null;

        // Essayer de récupérer le JSON
        try (InputStream entityStream = context.getEntityStream())
        {
            if (entityStream != null)
            {
                byte[] bytes = IOUtils.toByteArray(entityStream);
                context.setEntityStream(new ByteArrayInputStream(bytes));
                jsonEchec = new String(bytes);
            }
        }

        // Retour du JSON descriptif de l'erreur
        return jsonEchec;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM