gpt4 book ai didi

java - 如何在 Java Android Spring 中接收验证错误

转载 作者:行者123 更新时间:2023-11-29 18:58:00 24 4
gpt4 key购买 nike

我在 Android (Java) 中使用 Spring 向后端 API 发送 API 请求。我的问题是如何在 ex 400 错误请求响应中将验证错误接收到错误处理程序。这是我的代码:

 class RestTask extends AsyncTask<String,Void,ResponseEntity<ExpectedReturn>>
{
protected ResponseEntity<ExpectedReturn> doInBackground(String... uri)
{
try{
final String url = uri[0];
RestTemplate restTemplate = new RestTemplate();
restTemplate.setErrorHandler(subscriber.getErrorHandler());
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
// set authentication tokens:
ResponseEntity<ExpectedReturn> response = restTemplate.exchange(url,callMethod,httpEntity, expectedReturnClass);
return response;
}catch(Exception e)
{
System.out.println(e.getMessage());
}
return null;
}

@Override
protected void onPostExecute(ResponseEntity<ExpectedReturn> result) {
if(result !=null && result.getBody() !=null)
{
subscriber.getSubscriber().onComplete(result.getBody(),result.getStatusCode());
}
}
}

我的问题是,如果 post 数据验证失败(不正确),API 将作为带有错误的 JSON 错误对象返回,例如: enter image description here

如果出现验证错误,将调用错误处理程序,并使用 ClientHttpResponse 对象作为参数。调用 response.getBody() 返回一个 InputStream。我的问题是,是否有任何方法可以接收从 JSON 错误响应(如上所示)映射到错误处理程序的对象,或者可能将输入流转换为可读的内容(如 HashMap ),以便我可以显示返回的错误API(例如:“需要名称”等...)?

最佳答案

我已经测试了您的代码,如果出现 400 次错误请求,catch block 会收到一个 HttpClientErrorException 实例,该实例具有将错误主体获取为字符串的方法:

private class HttpRequestTask extends AsyncTask<Void, Void, String> {
@Override
protected String doInBackground(Void... params) {
try {
final String url = "https://reqres.in/api/login";
RestTemplate restTemplate = new RestTemplate();
//Same result with restTemplate.exchange() too
return restTemplate.postForObject(url, "{\n" +
" \"email\": \"peter@klaven\"\n" +
"}", String.class);

} catch (Exception e) {
Log.e(TAG, e.getMessage());
if (e instanceof HttpClientErrorException) {
String responseBodyAsString = ((HttpClientErrorException) e).getResponseBodyAsString();
Log.e(TAG, "Validation error" + responseBodyAsString);
//You can parse this with gson or jackson here
return responseBodyAsString;
}
}

return null;
}

@Override
protected void onPostExecute(String result) {
Log.d(TAG, "onPostExecute() called with: result = [" + result + "]");
}

}

打印在:

W/RestTemplate: POST request for "https://reqres.in/api/login" resulted in 
400 (Bad Request); invoking error handler
E/MainActivity: 400 Bad Request
E/MainActivity: Validation error{"error":"Missing email or username"}
D/MainActivity: onPostExecute() called with: result = [{"error":"Missing email or username"}]

如果您想使用无默认错误处理程序并设置您的自定义错误处理程序,您可以通过这种方式将错误消息作为字符串获取:

restTemplate.setErrorHandler(new ResponseErrorHandler() {
@Override
public boolean hasError(ClientHttpResponse response) throws IOException {
return response.getStatusCode().is4xxClientError();
}

@Override
public void handleError(ClientHttpResponse response) throws IOException {
String errorResponse = new String(getResponseBody(response), getCharset(response).name());
Log.e(TAG, "handleError: called with: " + errorResponse);
}
});

private byte[] getResponseBody(ClientHttpResponse response) {
try {
InputStream responseBody = response.getBody();
if (responseBody != null) {
return FileCopyUtils.copyToByteArray(responseBody);
}
} catch (IOException ex) {
// ignore
}
return new byte[0];
}

private Charset getCharset(ClientHttpResponse response) {
HttpHeaders headers = response.getHeaders();
MediaType contentType = headers.getContentType();
return contentType != null ? contentType.getCharSet() : Charset.defaultCharset();
}

然后您可以使用 Jackson 或 Gson 来解析错误响应,如下所示:

new Gson().fromJson(responseBodyAsString, ExpectedResponse.class);

请注意,我刚刚做了与 DefaultResponseErrorHandler

中实现的相同的事情

编辑:整个 AsyncTask 和 Spring Android API 都太过时了,下面是 Retrofit 的同一个例子:

        api.login(new BodyModel("peter@klaven"))
.enqueue(new Callback<ExpectedModel>() {
@Override
public void onResponse(@NonNull Call<ExpectedModel> call, @NonNull Response<ExpectedModel> response) {
if (response.isSuccessful()) {
//Do what you got to do
} else {
Converter<ResponseBody, ErrorModel> converter = MainActivity.this.retrofit.responseBodyConverter(ErrorModel.class, new Annotation[0]);
ErrorModel errorModel = null;
try {
errorModel = converter.convert(response.errorBody());
Toast.makeText(MainActivity.this, errorModel.toString(), Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
}

}

@Override
public void onFailure(@NonNull Call<ExpectedModel> call, @NonNull Throwable t) {
t.printStackTrace();
}
})

您可以找到完整的 gist in my github repo

关于java - 如何在 Java Android Spring 中接收验证错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49588515/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com