[JAVA] Gekitsuyo RestTemplate should be used for REST communication

RestTemplate

What is RestTemplate?

RestTemplate is a class that provides methods for calling REST API (Web API). HTTP client provided by Spring Framework (wrapping HttpClient).

In summary, a convenient component that enables easy REST communication.

It converts DTO to Json format request and binds Json format response to DTO. In addition to Json, various data formats such as Xml and Form are supported and can be customized !!

DTO => Json

DTO


@Getter // (1)
@Setter // (1)
public class SomeRequestResource {
    private String message; // (2)
}

(1) Getters and Setters are automatically generated using the library lombock (2) Fields that reflect Json conversion later

Json


{
  "messsage": "test message"
}

DTO field names and values are converted to Json format

Json => DTO

Json


{
  "messsage": "test message"
}

DTO


@Getter
@Setter
public class SomeRequestResource {
    private String message; // (1)
}

(1) Field to which Json value is bound

How to use RestTemplate

"Kihon" no Ki

Injection for the time being

@Service
public class XxxxServiceImpl implements XxxxService {

    @Autowired
    RestTemplate restTemplate;

    // ...

}

This time's main Rest Template is injected. This RestTemplate is packed with parts used for REST communication.

Try sending GET

@Getter
@Setter
public class TestResponseResource {
    private String id;      // (1)
    private String message; // (1)
}

(1) Field to bind the response

@Service
public class XxxxServiceImpl implements XxxxService {

    @Autowired
    RestTemplate restTemplate;

    public static final String URL = "http://com.example.rest/test";

    public TestResponseResource getTestResponse() {
      // (1)
      return restTemplate.getForObject(URL, TestResponseResource.class);
    }

}

(1) Send GET. (1) Argument of getForObject

Argument order Mold Description
1 String Destination URL
2 Class<T> Returned from the destinationResponseBodyClass to bind

Try to send POST

@Getter
@Setter
public class TestRequestResource {
    private String message;  // (1)
}

(1) Value to be sent

@Getter
@Setter
public class TestResponseResource {
    private String id;      // (1)
    private String message; // (1)
}

(1) Field to bind the response

@Service
public class XxxxServiceImpl implements XxxxService {

    @Autowired
    RestTemplate restTemplate;

    public static final String URL = "http://com.example.rest/test";

    public TestResponseResource getTestResponse() {
      // (1)
      TestRequestResource request = new TestRequestResource();
      request.setMessage("test message");

      // (2)
      return restTemplate.postForObject(URL,request,TestResponseResource.class);
    }

}

(1) Set the transmission data (2) POST transmission (2) Argument of postForObject

Argument order Mold Description
1 String Destination URL
2 Object Value to send
3 Class<T> Returned from the destinationResponseBodyClass to bind

"Kihon"

Dynamically change the sending URL

In the case of REST communication, Resource ʻidinformation may be obtained from the URL. Example)http://com.example.rest/book/1`

In the case of RestTemplate, it can be implemented in multiple patterns.

In order PathParameter claw pattern
@Getter
@Setter
public class BookResponseResource {
    private String id;
    private String message;
}
@Service
public class XxxxServiceImpl implements XxxxService {

    @Autowired
    RestTemplate restTemplate;

    // (1)
    public static final String URL = "http://com.example.rest/book/{id}";

    public TestResponseResource getTestResponse() {
      // (2)
      return restTemplate.getForObject(URL, BookResponseResource.class, "1");
    }

}

(1) Parameters are bound to {id} (2) Pass the character string you want to bind to the parameter at the end of the argument. Since it is taken with a variable length argument, multiple specifications can be specified.

Explicit claw pattern
@Getter
@Setter
public class BookResponseResource {
    private String id;
    private String message;
}
@Service
public class XxxxServiceImpl implements XxxxService {

    @Autowired
    RestTemplate restTemplate;

    // (1)
    public static final String URL = "http://com.example.rest/book/{id}";

    public BookResponseResource getTestResponse() {
      // (2)
      Map<String, String> params = new HashMap<String, String>();
      params.put("id", "1");
      // (3)
      return restTemplate.getForObject(URL, BookResponseResource.class, params);
    }
}

(1) Parameters are bound to {id} (2) Set the value to be bound to the parameter (2) Pass the Map <String, String> of the value you want to bind to the parameter at the end of the argument.

Change the Header information to be sent

It can be changed flexibly when the data format to be sent is changed such as XML, when the character code is changed, or when you want to send a special Header.

Change Content-Type

When changing only Content-Type
public BookResponseResource getTestResponse(BookRequestResource request) {
    RequestEntity<BookRequestResource> requestEntity = 
        RequestEntity
          .post(new URI(URL))
          .contentType(MediaType.APPLICATION_XML) // (1)
          .body(request);

    return restTemplate.getForObject(requestEntity, BookResponseResource.class);
}

(1) Change Content-Type

When changing charset
public BookResponseResource getTestResponse(BookRequestResource request) {
    // (1)
    Map<String, String> prop = new HashMap<String, String>();
    prop.put("charset", "shift_jis");
    // (2)
    MediaType mediaType = new MediaType(MediaType.APPLICATION_XML, param);

    RequestEntity<BookRequestResource> requestEntity = 
        RequestEntity
          .post(new URI(URL))
          .contentType(mediaType)
          .body(request);

    return restTemplate.getForObject(requestEntity, BookResponseResource.class);
}

(1) Set the property (charset) of MediaType (2) Generate MediaType based on the property

"Kihon"

Handle errors at the communication destination

public TestResponseResource getTestResponse() {
    // (1)
    try {
        return restTemplate.getForObject(URL, TestResponseResource.class);
    }
    catch (HttpClientErrorException e) { // (1)
        logger.error("400 series error occurred");
        throw e;
    }
    catch (HttpServerErrorException e) { // (2)
        logger.error("500 series error occurred");
        throw e;
    }
}

(1) Occurs when the HttpStatus code of the response is 400 series. (2) Occurs when the HttpStatus code of the response is 500 series.

Recommended Posts

Gekitsuyo RestTemplate should be used for REST communication
[RubyOnRails] What kind of data should active_hash be used for?
Map keySet, values should not be used
[Java] When var should be used and when it should not be used
Introduction of jQuery-until it can be used (record executed in preparation for asynchronous communication) haml