Android : Volley를 사용하여 서버의 메시지 오류를 어떻게 처리합니까?
내 Android 앱에 Volley 를 사용하여 내 서버에서 데이터를 가져오고 있습니다. 내 서버에서 오류를 처리 할 때를 제외하고는 잘 작동합니다. 내 서버는 실수가있을 때이 응답을 보냅니다.
{
"status": 400,
"message": "Errors (2): A name is required- Julien is already used. Not creating."
}
내 목표는 메시지를 가져 와서 Toast. 이 작업을 수행하는 방법에 대한 몇 가지 샘플을 따랐지만 작동하지 않습니다.
내 오류 리스너가 있습니다.
public void onErrorResponse(VolleyError error) {
int statusCode = error.networkResponse.statusCode;
NetworkResponse response = error.networkResponse;
Log.d("testerror",""+statusCode+" "+response.data);
// Handle your error types accordingly.For Timeout & No connection error, you can show 'retry' button.
// For AuthFailure, you can re login with user credentials.
// For ClientError, 400 & 401, Errors happening on client side when sending api request.
// In this case you can check how client is forming the api and debug accordingly.
// For ServerError 5xx, you can do retry or handle accordingly.
if( error instanceof NetworkError) {
} else if( error instanceof ClientError) {
} else if( error instanceof ServerError) {
} else if( error instanceof AuthFailureError) {
} else if( error instanceof ParseError) {
} else if( error instanceof NoConnectionError) {
} else if( error instanceof TimeoutError) {
}
showProgress(false);
mPasswordView.setError(getString(R.string.error_incorrect_password));
mPasswordView.requestFocus();
}
그리고 내 디버거의 결과 : testerror ﹕ 400 [B @ 430b8d60
편집 : 또한 내 error.getMessage ()가 null입니다.
그래서 내 변수 response.data가 내 서버의 응답이 아닌 이유를 이해할 수 없습니다.
누군가 내 서버에서 메시지를받을 수있는 방법을 알고 있다면 멋질 것입니다.
고마워,
나는 이와 비슷한 것을 구현했으며 상대적으로 간단합니다. 로그 메시지는은 ( response.data는) 실제로 바이트 배열 이기 때문에 횡설수설처럼 보이는 것을 인쇄 합니다 String. 또한 a VolleyError는 실제로 확장 된 Exception것이므로 확장 클래스 에서 구문 분석을위한 구문 분석 메서드를 재정의하지 않는 한 Exception .getMessage ()는 찾고있는 것을 반환하지 않을 것입니다 . 이것을 처리하는 정말 기본적인 방법은 다음과 같이하는 것입니다.VolleyErrorRequest
//In your extended request class
@Override
protected VolleyError parseNetworkError(VolleyError volleyError){
if(volleyError.networkResponse != null && volleyError.networkResponse.data != null){
VolleyError error = new VolleyError(new String(volleyError.networkResponse.data));
volleyError = error;
}
return volleyError;
}
}
이것을 확장 Request클래스에 추가하면 getMessage()최소한 null을 반환하지 않아야합니다. 나는 당신의 onErrorResponse(VolleyError e)방법 내에서 모든 것을 수행하는 것이 충분히 쉽기 때문에 일반적으로 이것을 정말로 귀찮게하지 않습니다 .
단순화하려면 JSON 라이브러리를 사용해야 합니다. 예를 들어 Gson 을 사용 하거나 JSONObject추가 외부 라이브러리가 필요하지 않은 Apache의 s를 사용할 수 있습니다 . 첫 번째 단계는 서버에서 보낸 응답 JSON을 String(방금 시연 한 것과 비슷한 방식 으로) 가져 오는 것입니다. 다음으로 선택적으로 JSONObject 로 변환 할 수 있습니다 (apache의 JSONObjects 및 JsonArrays 또는 선택한 다른 라이브러리 사용). ) 또는 String자신을 구문 분석 하십시오. 그 후 Toast.
시작하는 데 도움이되는 몇 가지 예제 코드는 다음과 같습니다.
public void onErrorResponse(VolleyError error) {
String json = null;
NetworkResponse response = error.networkResponse;
if(response != null && response.data != null){
switch(response.statusCode){
case 400:
json = new String(response.data);
json = trimMessage(json, "message");
if(json != null) displayMessage(json);
break;
}
//Additional cases
}
}
public String trimMessage(String json, String key){
String trimmedString = null;
try{
JSONObject obj = new JSONObject(json);
trimmedString = obj.getString(key);
} catch(JSONException e){
e.printStackTrace();
return null;
}
return trimmedString;
}
//Somewhere that has access to a context
public void displayMessage(String toastString){
Toast.makeText(context, toastString, Toast.LENGTH_LONG).show();
}
이 클래스를 사용하여 모든 오류를 처리하십시오.
public class VolleyErrorHelper {
/**
* Returns appropriate message which is to be displayed to the user
* against the specified error object.
*
* @param error
* @param context
* @return
*/
public static String getMessage (Object error , Context context){
if(error instanceof TimeoutError){
return context.getResources().getString(R.string.timeout);
}else if (isServerProblem(error)){
return handleServerError(error ,context);
}else if(isNetworkProblem(error)){
return context.getResources().getString(R.string.nointernet);
}
return context.getResources().getString(R.string.generic_error);
}
private static String handleServerError(Object error, Context context) {
VolleyError er = (VolleyError)error;
NetworkResponse response = er.networkResponse;
if(response != null){
switch (response.statusCode){
case 404:
case 422:
case 401:
try {
// server might return error like this { "error": "Some error occured" }
// Use "Gson" to parse the result
HashMap<String, String> result = new Gson().fromJson(new String(response.data),
new TypeToken<Map<String, String>>() {
}.getType());
if (result != null && result.containsKey("error")) {
return result.get("error");
}
} catch (Exception e) {
e.printStackTrace();
}
// invalid request
return ((VolleyError) error).getMessage();
default:
return context.getResources().getString(R.string.timeout);
}
}
return context.getResources().getString(R.string.generic_error);
}
private static boolean isServerProblem(Object error) {
return (error instanceof ServerError || error instanceof AuthFailureError);
}
private static boolean isNetworkProblem (Object error){
return (error instanceof NetworkError || error instanceof NoConnectionError);
}
'Program Club' 카테고리의 다른 글
| Eclipse Kepler에서 코드 지원 (ctrl + space)이 작동하지 않습니다. (0) | 2020.10.31 |
|---|---|
| Visual Studio 2013에서 Sass를 사용하는 방법 (0) | 2020.10.31 |
| DataFrame pandas에서 날짜 사이의 일 수가있는 열 추가 (0) | 2020.10.31 |
| Swift의 사전에서 키 값을 어떻게 얻을 수 있습니까? (0) | 2020.10.31 |
| Time.now를 가짜로 만드는 방법? (0) | 2020.10.31 |