ฉันมีสองคำถาม:
- วิธีแมปรายการของวัตถุ JSON โดยใช้ Spring RestTemplate
- วิธีแมปออบเจ็กต์ JSON ที่ซ้อนกัน
ฉันพยายามที่จะกินhttps://bitpay.com/api/ratesโดยต่อไปนี้การกวดวิชาจากhttp://spring.io/guides/gs/consuming-rest/
ฉันมีสองคำถาม:
ฉันพยายามที่จะกินhttps://bitpay.com/api/ratesโดยต่อไปนี้การกวดวิชาจากhttp://spring.io/guides/gs/consuming-rest/
คำตอบ:
อาจจะด้วยวิธีนี้ ...
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();
โซลูชันอื่น ๆ ด้านบนจะใช้งานได้เช่นกัน แต่ฉันชอบรับรายการที่พิมพ์กลับอย่างแรงแทนที่จะเป็นวัตถุ []
restTemplate.exchange
marshallar แมปค่า json ทั้งหมดกับชื่อคีย์ที่ตรงกันเป็นคุณสมบัติในวัตถุ Rate หวังว่ากระบวนการคิดของฉันจะถูกต้อง
สำหรับฉันมันใช้งานได้
Object[] forNow = template.getForObject("URL", Object[].class);
searchList= Arrays.asList(forNow);
โดยที่ Object คือคลาสที่คุณต้องการ
Coupon[] coupons = restTemplate.getForObject( url, Coupon[].class)
[]
แต่ว่างเปล่าทั้งหมด) ดังนั้นควรระมัดระวังและตรวจสอบ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());
}
ปัญหาใหญ่ของฉันที่นี่คือการสร้างโครงสร้างวัตถุที่ต้องการจับคู่ RestTemplate กับ Class ที่เข้ากันได้ โชคดีที่ฉันพบhttp://www.jsonschema2pojo.org/ (รับการตอบสนอง JSON ในเบราว์เซอร์และใช้เป็นอินพุต) และฉันไม่สามารถแนะนำสิ่งนี้ได้มากพอ!
ฉัน deveopped สิ่งที่ทำงานได้จริงสำหรับหนึ่งในโครงการของฉันก่อนและนี่คือรหัส:
/**
* @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;
}
}
ฉันหวังว่านี่จะช่วยให้ใครบางคน!
หากคุณต้องการ List of Objects วิธีหนึ่งในการทำเช่นนี้คือ:
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 เป็นประเภทส่งคืนของเราใช้เพื่อห่อรายการวัตถุที่เราต้องการจริง ๆ ประการที่สองเราเรียก RestTemplate.exchange () แทน getForObject () .
นี่เป็นวิธีทั่วไปในการใช้ RestTemplate มันต้องการให้เราระบุวิธี HTTP, เนื้อหาคำขอที่เป็นตัวเลือกและประเภทการตอบกลับ ในกรณีนี้เราใช้คลาสย่อยที่ไม่ระบุชื่อของ ParameterizedTypeReference สำหรับประเภทการตอบกลับ
ส่วนสุดท้ายนี้คือสิ่งที่ช่วยให้เราสามารถแปลงการตอบสนอง JSON เป็นรายการของวัตถุที่เป็นประเภทที่เหมาะสม เมื่อเราสร้างคลาสย่อยที่ไม่ระบุชื่อของ ParameterizedTypeReference มันจะใช้การสะท้อนเพื่อบันทึกข้อมูลเกี่ยวกับประเภทของคลาสที่เราต้องการแปลงการตอบสนองของเราเป็น
มันเก็บข้อมูลนี้โดยใช้ประเภทวัตถุของ Java และเราไม่ต้องกังวลเกี่ยวกับการลบประเภทอีกต่อไป "
ลองพิจารณาคำตอบนี้โดยเฉพาะถ้าคุณต้องการใช้ generics ในList
Spring RestTemplate และประเภททั่วไป ParameterizedTypeReference collection เช่น List <T>
คุณสามารถสร้าง POJO สำหรับแต่ละรายการเช่น
class BitPay{
private String code;
private String name;
private double rate;
}
จากนั้นใช้ ParameterizedTypeReference of List ของ BitPay คุณสามารถใช้เป็น:
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 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
ให้ข้อผิดพลาดในการรวบรวม "ประเภทที่เข้ากันไม่ได้"