2つの質問があります。
- Spring RestTemplateを使用してJSONオブジェクトのリストをマップする方法。
- ネストされたJSONオブジェクトをマップする方法。
http://spring.io/guides/gs/sumption-rest/のチュートリアルに従って、https://bitpay.com/api/ratesを使用しようとしています。
2つの質問があります。
http://spring.io/guides/gs/sumption-rest/のチュートリアルに従って、https://bitpay.com/api/ratesを使用しようとしています。
回答:
多分このように...
ResponseEntity<Object[]> responseEntity = restTemplate.getForEntity(urlGETList, Object[].class);
Object[] objects = responseEntity.getBody();
MediaType contentType = responseEntity.getHeaders().getContentType();
HttpStatus statusCode = responseEntity.getStatusCode();
のコントローラコード RequestMapping
@RequestMapping(value="/Object/getList/", method=RequestMethod.GET)
public @ResponseBody List<Object> findAllObjects() {
List<Object> objects = new ArrayList<Object>();
return objects;
}
ResponseEntity
ステータスコードHttpEntity
を追加する拡張機能HttpStatus
です。RestTemplate
同様に@Controller
メソッドで使用されます。でRestTemplate
、このクラスによって返されるgetForEntity()
とexchange()
。
最初に、配列に戻ってくるエンティティを保持するオブジェクトを定義します。例:
@JsonIgnoreProperties(ignoreUnknown = true)
public class Rate {
private String name;
private String code;
private Double rate;
// add getters and setters
}
次に、サービスを利用して、強く型付けされたリストを取得できます。
ResponseEntity<List<Rate>> rateResponse =
restTemplate.exchange("https://bitpay.com/api/rates",
HttpMethod.GET, null, new ParameterizedTypeReference<List<Rate>>() {
});
List<Rate> rates = rateResponse.getBody();
上記の他のソリューションも機能しますが、Object []ではなく、強く型付けされたリストを取得するのが好きです。
restTemplate.exchange
マーシャラーがすべてのjson値を、Rateオブジェクトのプロパティとして一致するキー名にマッピングしているときです。私の思考プロセスが正しいことを願っています。
私にとってこれはうまくいった
Object[] forNow = template.getForObject("URL", Object[].class);
searchList= Arrays.asList(forNow);
Objectは必要なクラスです。
Coupon[] coupons = restTemplate.getForObject( url, Coupon[].class)
[]
完全に空ではない)場合、NPEが発生する可能性があります。したがって、注意してnull
(if (forNow != null)...
)を確認してください。
Object.class
メソッドで指定されているときに、ジャクソンでどのタイプが使用されているのか疑問に思いましたgetForObject()
。
複数のテストの後、これは私が見つけた最良の方法です:)
Set<User> test = httpService.get(url).toResponseSet(User[].class);
そこに必要なすべて
public <T> Set<T> toResponseSet(Class<T[]> setType) {
HttpEntity<?> body = new HttpEntity<>(objectBody, headers);
ResponseEntity<T[]> response = template.exchange(url, method, body, setType);
return Sets.newHashSet(response.getBody());
}
私は実際に以前に私のプロジェクトの1つのために機能的なものを開発しました、そしてここにコードがあります:
/**
* @param url is the URI address of the WebService
* @param parameterObject the object where all parameters are passed.
* @param returnType the return type you are expecting. Exemple : someClass.class
*/
public static <T> T getObject(String url, Object parameterObject, Class<T> returnType) {
try {
ResponseEntity<T> res;
ObjectMapper mapper = new ObjectMapper();
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
((SimpleClientHttpRequestFactory) restTemplate.getRequestFactory()).setConnectTimeout(2000);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<T> entity = new HttpEntity<T>((T) parameterObject, headers);
String json = mapper.writeValueAsString(restTemplate.exchange(url, org.springframework.http.HttpMethod.POST, entity, returnType).getBody());
return new Gson().fromJson(json, returnType);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* @param url is the URI address of the WebService
* @param parameterObject the object where all parameters are passed.
* @param returnType the type of the returned object. Must be an array. Exemple : someClass[].class
*/
public static <T> List<T> getListOfObjects(String url, Object parameterObject, Class<T[]> returnType) {
try {
ObjectMapper mapper = new ObjectMapper();
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
((SimpleClientHttpRequestFactory) restTemplate.getRequestFactory()).setConnectTimeout(2000);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<T> entity = new HttpEntity<T>((T) parameterObject, headers);
ResponseEntity<Object[]> results = restTemplate.exchange(url, org.springframework.http.HttpMethod.POST, entity, Object[].class);
String json = mapper.writeValueAsString(results.getBody());
T[] arr = new Gson().fromJson(json, returnType);
return Arrays.asList(arr);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
これが誰かを助けることを願っています!
オブジェクトのリストが必要な場合は、次のようにします。
public <T> List<T> getApi(final String path, final HttpMethod method) {
final RestTemplate restTemplate = new RestTemplate();
final ResponseEntity<List<T>> response = restTemplate.exchange(
path,
method,
null,
new ParameterizedTypeReference<List<T>>(){});
List<T> list = response.getBody();
return list;
}
そしてそれを次のように使用します:
List<SomeObject> list = someService.getApi("http://localhost:8080/some/api",HttpMethod.GET);
上記の説明はこちら(https://www.baeldung.com/spring-rest-template-list)にあり、以下で言い換えます。
「上記のコードではいくつかのことが起こります。まず、ResponseEntityを戻り値の型として使用し、それを使用して、本当に必要なオブジェクトのリストをラップします。次に、getForObject()ではなくRestTemplate.exchange()を呼び出します。 。
これは、RestTemplateを使用する最も一般的な方法です。HTTPメソッド、オプションのリクエスト本文、および応答タイプを指定する必要があります。この場合、応答タイプにはParameterizedTypeReferenceの匿名サブクラスを使用します。
この最後の部分により、JSON応答を適切なタイプのオブジェクトのリストに変換できます。ParameterizedTypeReferenceの匿名サブクラスを作成すると、それはリフレクションを使用して、応答を変換するクラスタイプに関する情報を取得します。
JavaのTypeオブジェクトを使用してこの情報を保持しているため、型の消去について心配する必要はありません。」
この回答を参照してください。SpringRestTemplateでジェネリックを使用する場合、およびList <T>などのジェネリック型ParameterizedTypeReferenceコレクションを使用する場合は特にList
注意してください。
次のようなエントリごとにPOJOを作成できます。
class BitPay{
private String code;
private String name;
private double rate;
}
次に、BitPayのリストのParameterizedTypeReferenceを使用して、次のように使用できます。
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<List<Employee>> response = restTemplate.exchange(
"https://bitpay.com/api/rates",
HttpMethod.GET,
null,
new ParameterizedTypeReference<List<BitPay>>(){});
List<Employee> employees = response.getBody();
この投稿https://jira.spring.io/browse/SPR-8263から回避策を見つけました。
この投稿に基づいて、次のような型付きリストを返すことができます。
ResponseEntity<? extends ArrayList<User>> responseEntity = restTemplate.getForEntity(restEndPointUrl, (Class<? extends ArrayList<User>>)ArrayList.class, userId);
getForEntity
。また、(Class<? extends ArrayList<User>>) ArrayList.class
「互換性のない型」コンパイルエラーを与えます。