Retrofit에서 Dynamic JSON을 처리하는 방법
만, 프리픽스 「Dynamic JSON」을 JSON을 할 수 .responseMessage
됩니다.object
으로 같은 프리픽스(responseMessage
는 경우에 따라 String으로 변경됩니다(동적으로).
responseMessage의 Json 형식 개체:
{
"applicationType":"1",
"responseMessage":{
"surname":"Jhon",
"forename":" taylor",
"dob":"17081990",
"refNo":"3394909238490F",
"result":"Received"
}
}
responseMessage
Json j j j j j j j j j j j j j j j j j j j j j
{
"applicationType":"4",
"responseMessage":"Success"
}
되어 있기 입니다.JSON
도 동적 POJO를 .JSON
응답합니다.접두사는 성공(...) 메서드와 실패(...) 메서드 모두에서 문자열에서 개체로 랜덤하게 변경됩니다.
void doTrackRef(Map<String, String> paramsref2) {
RestAdapter restAdapter = new RestAdapter.Builder().setEndpoint("http://192.168.100.44/RestDemo").build();
TrackerRefRequest userref = restAdapter.create(TrackerRefRequest.class);
userref.login(paramsref2,
new Callback<TrackerRefResponse>() {
@Override
public void success(
TrackerRefResponse trackdetailresponse,
Response response) {
Toast.makeText(TrackerActivity.this, "Success",
Toast.LENGTH_SHORT).show();
}
@Override
public void failure(RetrofitError retrofitError) {
Toast.makeText(TrackerActivity.this, "No internet",
Toast.LENGTH_SHORT).show();
}
});
}
뽀조:
public class TrackerRefResponse {
private String applicationType;
private String responseMessage; //String type
//private ResponseMessage responseMessage; //Object of type ResponseMessage
//Setters and Getters
}
POJO TrackerRefResponse. response 되어 있기 할 수 있습니다: ).따라서 다이내믹 Java prefix Response Message stressage string에 대해 동일한 있습니다. 가지는 POJO 를 작성할 수 있기 때문에, 다이나믹용의 같은 솔루션을 찾고 있습니다.JSON
를 가진 일반 이라는 것은 REST-Api의 베스트 는 아닙니다.JSON
해석!퍼포먼스를 보면 항상 Balley 또는 Retrofit을 선택하는 것이 가장 좋지만 다이내믹을 다루는 데 실패했습니다.JSON
가능한 해결 방법
오래된 asyc 태스크를 http 클라이언트 구문 분석과 함께 사용합니다. : (
RESTAPI 백엔드 개발자를 설득합니다.
커스텀 Retrofit 클라이언트 작성 :)
파티에 늦었지만 컨버터를 사용할 수 있어요.
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint("https://graph.facebook.com")
.setConverter(new DynamicJsonConverter()) // set your static class as converter here
.build();
api = restAdapter.create(FacebookApi.class);
그런 다음 개조의 Converter를 구현하는 정적 클래스를 사용합니다.
static class DynamicJsonConverter implements Converter {
@Override public Object fromBody(TypedInput typedInput, Type type) throws ConversionException {
try {
InputStream in = typedInput.in(); // convert the typedInput to String
String string = fromStream(in);
in.close(); // we are responsible to close the InputStream after use
if (String.class.equals(type)) {
return string;
} else {
return new Gson().fromJson(string, type); // convert to the supplied type, typically Object, JsonObject or Map<String, Object>
}
} catch (Exception e) { // a lot may happen here, whatever happens
throw new ConversionException(e); // wrap it into ConversionException so retrofit can process it
}
}
@Override public TypedOutput toBody(Object object) { // not required
return null;
}
private static String fromStream(InputStream in) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder out = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
out.append(line);
out.append("\r\n");
}
return out.toString();
}
}
이 샘플 컨버터는 String, Object, JsonObject 또는 Map < String, Object > 중 하나로 Json 응답을 반환하도록 작성되어 있습니다.모든 반품 타입이 모든 Json에 적용되는 것은 아니므로 개선의 여지가 있습니다.그러나 컨버터를 사용하여 거의 모든 응답을 동적 Json으로 변환하는 방법을 보여 줍니다.
RestClient.java
import retrofit.client.Response;
public interface RestClient {
@GET("/api/foo") Response getYourJson();
}
YourClass.java
RestClient restClient;
// create your restClient
Response response = restClient.getYourJson();
Gson gson = new Gson();
String json = response.getBody().toString();
if (checkResponseMessage(json)) {
Pojo1 pojo1 = gson.fromJson(json, Pojo1.class);
} else {
Pojo2 pojo2 = gson.fromJson(json, Pojo2.class);
}
checkResponseMessage 메서드를 구현해야 합니다.
를 사용하여 커스텀 시도gson-converter
같이 (2.) as((((ret ( Retrofit 2.0에 대한 갱신된 답변).
아래 그림과 같이 3개의 모델을 만듭니다.
응답 래퍼
public class ResponseWrapper {
@SerializedName("applicationType")
@Expose
private String applicationType;
@SerializedName("responseMessage")
@Expose
private Object responseMessage;
public String getApplicationType() {
return applicationType;
}
public void setApplicationType(String applicationType) {
this.applicationType = applicationType;
}
public Object getResponseMessage() {
return responseMessage;
}
public void setResponseMessage(Object responseMessage) {
this.responseMessage = responseMessage;
}
}
응답 메시지
public class ResponseMessage extends ResponseWrapper {
@SerializedName("surname")
@Expose
private String surname;
@SerializedName("forename")
@Expose
private String forename;
@SerializedName("dob")
@Expose
private String dob;
@SerializedName("refNo")
@Expose
private String refNo;
@SerializedName("result")
@Expose
private String result;
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public String getForename() {
return forename;
}
public void setForename(String forename) {
this.forename = forename;
}
public String getDob() {
return dob;
}
public void setDob(String dob) {
this.dob = dob;
}
public String getRefNo() {
return refNo;
}
public void setRefNo(String refNo) {
this.refNo = refNo;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
}
응답 문자열
public class ResponseString extends ResponseWrapper {
}
UserResponseDeserializer(커스텀디시리얼라이저)
public class UserResponseDeserializer implements JsonDeserializer<ResponseWrapper> {
@Override
public ResponseWrapper deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
if (((JsonObject) json).get("responseMessage") instanceof JsonObject){
return new Gson().fromJson(json, ResponseMessage.class);
} else {
return new Gson().fromJson(json, ResponseString.class);
}
}
}
Retrofit 2.0 구현
Gson userDeserializer = new GsonBuilder().setLenient().registerTypeAdapter(ResponseWrapper.class, new UserResponseDeserializer()).create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("base_url")
.addConverterFactory(GsonConverterFactory.create(userDeserializer))
.build();
UserService request = retrofit.create(UserService.class);
Call<ResponseWrapper> call1=request.listAllUsers();
call1.enqueue(new Callback<ResponseWrapper>() {
@Override
public void onResponse(Call<ResponseWrapper> call, Response<ResponseWrapper> response) {
ResponseWrapper responseWrapper=response.body();
Log.i("DYNAMIC RESPONSE", String.valueOf(response.body().getResponseMessage()));
}
@Override
public void onFailure(Call<ResponseWrapper> call, Throwable t) {
}
});
사용된 라이브러리
com을 컴파일합니다.squareup.squarefit 2 : squarefit : 2 . 3 . 0 '
com을 컴파일합니다.squareup.fit 2: square-gson: 2.3.0'
**** 이전 답변 (위의 답변이 권장됩니다)*****
포조를 이렇게 바꾸세요.
public class TrackerRefResponse {
private String applicationType;
private Object responseMessage;
public Object getResponseMessage() {
return responseMessage;
}
public void setResponseMessage(Object responseMessage) {
this.responseMessage = responseMessage;
}
}
retrofit의 onResponse를 이렇게 변경합니다.
@Override
public void onResponse(Response<TrackerRefResponse > response) {
if (response.isSuccess()) {
if (response.getResponseMessage() instanceof String)
{
handleStringResponse();
}
else
{
handleObjectResponse();
}
}
}
동적 json 해석에 대한 자세한 내용은 이 게시물을 참조하십시오.
이치노Retrofit api 인터페이스 반환 유형을 응답으로 전송하는 것도 가능합니다..Inputstream
JSON j j j j j j j j j j j j j j j j j j j j j.
다음 URL을 참조하십시오.http://square.github.io/retrofit/ #api - response object TYPE 。
갱신필
Retrofit 2는 현재 출시되었으며 문서와 라이브러리에 대한 몇 가지 변경 사항이 있습니다.
http://square.github.io/retrofit/ #restadapter-configuration을 참조해 주세요.사용 가능한 요청 및 응답 본문 오브젝트가 있습니다.
받아들여진 답변은 너무 복잡해 보였고, 저는 이렇게 해결했습니다.
Call<ResponseBody> call = client.request(params);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Response<ResponseBody> response) {
if (response.isSuccess()) {
Gson gson = new Gson();
ResponseBody repsonseBody = response.body().string();
if (isEmail) {
EmailReport reports = gson.fromJson(responseBody, EmailReport.class);
} else{
PhoneReport reports = gson.fromJson(repsonseBody, PhoneReport.class);
}
}
}
@Override
public void onFailure(Throwable t) {
Log.e(LOG_TAG, "message =" + t.getMessage());
}
});
이것은 다른 모델을 사용할 수 있는 방법을 보여 주기 위한 예에 불과합니다.
''isEmail
는 적절한 모델을 사용하기 위한 조건의 부울일 뿐입니다.
파티에 많이 늦은 거 알아.저도 비슷한 문제가 있었는데 이렇게 해결했어요.
public class TrackerRefResponse {
private String applicationType;
// Changed to Object. Works fine with String and array responses.
private Object responseMessage;
}
글자 그대로 개체로 바꿨어요.이 방법을 선택한 이유는 응답 중 하나의 필드만 동적이기 때문입니다(내 응답은 훨씬 복잡했습니다). 따라서 변환기를 사용하면 생활이 어려워질 것입니다.Gson을 사용하여 오브젝트 조작(String 값인지 Array 값인지에 따라 다름).
이것이 간단한 답을 찾는 데 도움이 되기를 바랍니다. :)
백엔드 API를 변경할 수 없는 경우에는 다음 변종(Gson을 사용하여 JSON을 변환하는 경우)을 검토하겠습니다.
Gson 타입의 어댑터를 사용해, 다음의 커스텀 어댑터를 작성할 수 있습니다.
ResponseMessage
JSON을(inoming JSON 등).if (reader.peek() == JsonToken.STRING)
를 참조해 주세요.응답 유형을 설명하는 메타 정보를 HTTP 헤더에 삽입하고 이를 사용하여 Gson 인스턴스에 공급해야 하는 유형 정보를 결정합니다.
kotlin 개발자의 경우 변수 유형을 Any로 선언한 후 gson 컨버터를 사용하여 Gson 클래스로 변환할 수 있습니다.
data class SomeClass(
...somevariables,
val respnseMessage : Any
)
그런 다음 작업 또는 조각에서 해석하여 사용할 위치를 지정합니다. 사용 사례에 따라 다음과 같은 작업을 수행할 수 있습니다.
val gson = Gson()
val data = gson.fromJson<YourDesireClass>
(response.responseMessage.toString() , YourDesireClass::class.java)
당신이 말한 것 외에...
콜백 사용 일반 get 메서드를 사용하여 필드를 가져올 수 있습니다.자세한 내용은 gson의 javadoc을 참조하십시오.
http://google-gson.googlecode.com/svn/tags/1.2.3/docs/javadocs/com/google/gson/JsonObject.html
늦은 건 알지만 내 생각을 공유하고 싶어.저는 메서드를 작성하는 프로젝트를 하고 있었습니다.이 메서드는 서버로부터 데이터를 가져오기 위해 개조를 사용합니다.우리 회사의 다른 개발자들이 이 방법을 사용할 것이기 때문에, 저는 이 방법을 사용할 수 없었습니다.POJO
class (이 예에서는TrackerRefResponse
클래스)그래서 저는JsonObject
/Object
다음과 같습니다.
인터페이스 APIS 서비스자바
public class APIService{
@FormUrlEncoded
@POST
Call<JsonObject> myPostMethod(@Url String url, @Field("input") String input);
}
그리고 제 방법으로는 이렇게 썼어요.
Model1 model1 = null;
Model2 model2 = null;
Call<JsonObject> call = RetrofitClient.getAPIService().establishUserSession(post_request_url, someParameter);
call.enqueue(new Callback<JsonObject>() {
@Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
JsonObject jsonObject = response.body();
// then do your stuff. maybe something like this
try{
model1 = new Gson().fromJson(jsonObject, Model1.class);
}catch(Exception x){}
try{
model2 = new Gson().fromJson(jsonObject, Model2.class);
}catch(Exception x){}
if(model1 != null) { /*handle model1 */}
if(model2 != null) { /*handle model2*/}
// rest of the code
}
특정 Attribute가 어떤 유형의 응답인지 알 수 있는 경우 JsonObject를 사용하여 해당 Atribute를 읽은 후 다음과 같이 모델을 캐스팅할 수 있습니다.
// ... retrofit codes
@Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
int number = jsonObject.get("applicationType").getAsInt();
if(number == 1) {
model1 = new Gson().fromJson(jsonObject, Model1.class);
}
}
// ... rest of the code
를 사용할 수도 있습니다.Object
'Json Object'가 아닌 'JsonObject.나중에 어떤 종류의 응답인지 알게 되면 원하는 오브젝트에 넣을 수 있습니다.
나도 이 문제를 다루었다.하지만 이것이 당신의 경우인지 잘 모르겠습니다.(Retrofit2를 사용하고 있습니다)
제 경우 오류와 성공 메시지를 처리해야 합니다.
성공 시
{
"call_id": 1,
"status": "SUCCESS",
"status_code": "SUCCESS",
"result": {
"data1": {
"id": "RFP2UjW7p8ggpMXzYO9tRg==",
"name": "abcdef",
"mobile_no": "96655222",
"email": ""
},
"data2": [
{
"no": "12345"
},
{
"no": "45632"
}
]
}
}
오류 발생 시,
{
"call_id": 1,
"status": "FAILED",
"status_code": "NO_RECORDS",
"error": {
"error_title": "xxx",
"error_message": "details not found"
}
}
이것 때문에 나는 다른 POJO를 만들었다.Error
,
public class ValidateUserResponse {
@SerializedName("call_id")
public String callId;
@SerializedName("status")
public String status;
@SerializedName("status_code")
public String statusCode;
@SerializedName("result")
public ValidateUserResult result;
@SerializedName("error")
public Error error;
}
Error.java
public class Error {
@SerializedName("error_title")
public String errorTitle;
@SerializedName("error_message")
public String errorMessage;
}
ValidateUser.java
public class ValidateUserResult {
@SerializedName("auth_check")
public String authCheck;
@SerializedName("data1")
public Data1 data1;
@SerializedName("data2")
public List<Data2> data2;
}
의 .result
json에는 data1,되어 있고, 그 에 json에는 data1, data2가 포함되어 있습니다.ValidateUserResult.java
가 나면 에러가다Error.java
클래스가 초기화됩니다.
다른 옵션도 검토해 주세요.
제이슨
1.
{
"applicationType":"1",
"responseMessage":
{
"surname":"Jhon",
"forename":" taylor",
"dob":"17081990",
"refNo":"3394909238490F",
"result":"Received"
}
}
2.
{
"applicationType":"4",
"responseMessage":
{
"forename":" taylor",
"dob":"17081990",
}
}
3.
{
"applicationType":"5",
"responseMessage":
{
"refNo":"3394909238490F",
"result":"Received"
}
}
Pojo 클래스는 다음과 같습니다.
public class ResponseMessage
{
private String surname;
private String forename;
private String dob;
private String refNo;
private String result;
public void setSurname(String surname){
this.surname = surname;
}
public String getSurname(){
return this.surname;
}
public void setForename(String forename){
this.forename = forename;
}
public String getForename(){
return this.forename;
}
public void setDob(String dob){
this.dob = dob;
}
public String getDob(){
return this.dob;
}
public void setRefNo(String refNo){
this.refNo = refNo;
}
public String getRefNo(){
return this.refNo;
}
public void setResult(String result){
this.result = result;
}
public String getResult(){
return this.result;
}
}
public class Root
{
private String applicationType;
private ResponseMessage responseMessage;
public void setApplicationType(String applicationType){
this.applicationType = applicationType;
}
public String getApplicationType(){
return this.applicationType;
}
public void setResponseMessage(ResponseMessage responseMessage){
this.responseMessage = responseMessage;
}
public ResponseMessage getResponseMessage(){
return this.responseMessage;
}
}
now final code(최종코드)
if(responseMessage.getSurname() !=null){
---do something---
}
if(responseMessage.getForename !=null){
----do something
}
if(responseMessage.getDob() !=null){
---do something---
}
if(responseMessage.getRefNo() !=null){
---do something---
}
if(responseMessage.getResult() !=null){
---do something---
}
언급URL : https://stackoverflow.com/questions/24279245/how-to-handle-dynamic-json-in-retrofit
'bestsource' 카테고리의 다른 글
Wordpress 썸네일 생성에 연결하는 방법 (0) | 2023.03.05 |
---|---|
Apache 웹 서버에 React App을 배포하는 방법 (0) | 2023.03.05 |
Json에서 get-only 속성을 무시하는 방법이 있습니까?JsonIgnore 속성을 사용하지 않음NET? (0) | 2023.03.05 |
AJAX에서 WordPress 페이지 지정이 작동하지 않음 (0) | 2023.03.05 |
Firefox 또는 Chrome 브라우저에서 HTTP POST 요청을 수동으로 보내는 방법 (0) | 2023.03.05 |