6 Ağustos 2019 Salı

SpringMVC ResponseEntity Sınıfı - HttpStatus + HttpHeader + Body

Giriş
Açıklaması şöyle.
ResponseEntity is meant to represent the entire HTTP response. You can control anything that goes into it: status code, headers, and body.
Bu sınıf şu işlerde yardımcı oluyor
- HTTP Status and Headers Customization
- Handling Different Response Types : Çünkü sınıf generic
- Error Handling
- Asynchronous Response
- Testing and Mocking

Bu sınıf Rest çağrılarında kullanılır. 
Hem sunucu hem de istemci tarafında kullanılır.  Sunucu bir http cevabı göndermek için kullanır. İstemci ise http cevabını okumak için kullanır.

İstemci tarafında şöyle yaparız.
ResponseEntity<Foo> resp= restTemplate.exchange(url, HttpMethod.POST, foo, Foo.class);
Kullanım Önerisi
ResponseEntity nesne + HttpStatus + HttpHeader taşıyabilir. Nesneyi direkt döndürmek yerine bir mesaj ile zenginleştirerek döndürmek mümkün. 
Örnek
Şöyle yaparız
@GetMapping("/name")
public ResponseEntity<String> getName() {
  return ResponseEntity
    .status(HttpStatus.OK) // .ok() for shortcut
    .header("Custom-Header", "value")
    .body("Ahmet Emre");
}
Örnek
Elimizde şöyle bir kod olsun
public static ResponseEntity<Object> generateResponse(String message, HttpStatus status,
Object responseObj) {
  Map<> map = new HashMap<String, Object>();
  map.put("message", message);
  map.put("status", status.value());
  map.put("data", responseObj);

  return new ResponseEntity<Object>(map,status);
}
Şöyle yaparız
// Get
@GetMapping(value = "/users")
public ResponseEntity<Object> Get() {
  try {
    List<UserEntity> result = userService.Get();
    return ResponseHandler.generateResponse("Successfully retrieved data!",
HttpStatus.OK, result);
  } catch (Exception e) {
    return ResponseHandler.generateResponse(e.getMessage(), HttpStatus.MULTI_STATUS, null);
  }
}
constructor - HttpStatus
Şöyle yaparız
ResponseEntity<Foo> resp (HttpStatus.NOT_ACCEPTABLE);
constructor - Nesne + HttpStatus
Şöyle yaparız
Foo foo = ...
ResponseEntity<Foo> resp (foo, HttpStatus.CREATED);
constructor - Nesne + HttpHeaders + HttpStatus
İmzası şöyle
ResponseEntity(T body, MultiValueMap<String,String> headers, HttpStatus statusCode) 
Şöyle yaparız.
HttpHeaders> headers = ...;
new ResponseEntity<>(new InputStreamResource(...), headers, HttpStatus.OK);
body metodu
OutputStream için kullanılır
Örnek
Elimizde şöyle bir kod olsun. JdbcTemplate kullanarak OutputStream nesnesine yazıyor
public void streamProfilesFromDb(OutputStream outputStream,
Long segmentId, UUID versionId) { DataSource dataSource = Objects.requireNonNull(jdbcTemplate.getDataSource()); try (Connection con = dataSource.getConnection()) { con.setAutoCommit(false); // (!) try (PreparedStatement preparedStatement = con.prepareStatement(SELECT_PROFILES)) { preparedStatement.setLong(1, segmentId); preparedStatement.setObject(2, versionId); preparedStatement.setFetchSize(BATCH_SIZE); writeRowToOutputStream(outputStream, HEADERS); ResultSet resultSet = preparedStatement.executeQuery(); while (resultSet.next()) { List<String> columns = new ArrayList<>(); for (String profileHeader : HEADERS) { columns.add(resultSet.getString(profileHeader)); } writeRowToOutputStream(outputStream, columns); outputStream.flush(); // (!) } } } catch (SQLException | IOException exception) { ... } }
Kullanmak için şöyle yaparız. ResponseEntity.body() metodu
@GetMapping(value = "/stream/{id}")
public ResponseEntity<StreamingResponseBody> streamSegment(@PathVariable("id") 
  Long segmentId) {
  StreamingResponseBody responseBody = out -> {
    streamService.streamProfiles(out, segmentId);
    out.flush();
    out.close();
  };
  HttpHeaders headers = formHeaders(segmentId);
  return ResponseEntity.ok().headers(headers).body(responseBody);
}
getBody metodu
İstemci tarafında kullanılır. Elimizde ResponseEntity<T> nesnesi olsun. T nesnesini döner.
Örnek
Json verisini ham olarak okumak istersek şöyle yaparız.
ResponseEntity<String> response = *api call*
String value = response.getBody();
Bu durumda elimize şöyle bir cevap geçer.
{"value":123456}
Eğer sadece rakama ulaşmak istersek bir veri tipine çevirmek gerekir. Elimizde şöyle bir kod olsun.
public class MyResponse {
  private String value;

  public String getValue () {
    return this.value;
  }

  public void setValue (String value) {
    this.value = value;
  }
}
Şöyle yaparız.
ResponseEntity<MyResponse> response = *api call*
String value = response.getBody().getValue();
Örnek
Şöyle yaparız.
Foo foo= resp.getBody();
Örnek
Şöyle yaparız.
ResponseEntity<String[]> resp= restTemplate
  .getForEntity("localhost:8083/connectors/", String[].class);
List<String> object = Arrays.asList(resp.getBody());
getStatusCode metodu
İstemci tarafında kullanılır.
Örnek
Şöyle yaparız.
if (resp.getStatusCode().value() == 204) {
  ...
}
headers metodu
HttpHeaders nesnesi alır.

ok metodu
Sunucu tarafında kullanılır.
Örnek
Şöyle yaparız.
@GetMapping("/{id}")
public ResponseEntity<Employee> getEmployee(@PathVariable Long id) {
  return ResponseEntity.ok(employeeService.findEmployeeById(id);
}
status metodu
Sunucu tarafında kullanılır.
Örnek
Şöyle yaparız.
HttpHeaders headers = new HttpHeaders();
headers.add("content-Type", MediaType.IMAGE_JPEG_VALUE);
return ResponseEntity.status(...).headers(headers).body(...);

Hiç yorum yok:

Yorum Gönder