Spring REST Template with SSL

by GarciaPL on Monday 3 September 2012


Very fast guide how to use REST Template in Spring with SSL. It is just a few lines of code, but in some time it was very useful for me. This example is using Telco interfaces which allow to get subscriber location. Unfortunately this one is not available to the public.

public class LocationTelcoAPI {

    private RestTemplate restTemplate = new RestTemplate();
    private String telco_location = "https://api.orange.pl/terminallocation/?msisdn={phone}";

    private void enableSSL() {
        TrustManager[] trustAllCerts = new TrustManager[]{
            new X509TrustManager() {
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return null;
                }

                public void checkClientTrusted(
                        java.security.cert.X509Certificate[] certs, String authType) {
                }

                public void checkServerTrusted(
                        java.security.cert.X509Certificate[] certs, String authType) {
                }
            }
        };

        try {
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        } catch (Exception e) {
        }
    }

    public LocationResponse getLocation(String telephone_number) {

        enableSSL();

        String auth = TelcoAuth.USERNAME + ":" + TelcoAuth.PASSWORD;
        byte[] encodedAuth = Base64.encodeBase64(auth.getBytes());
        String authHeader = "Basic " + new String(encodedAuth);

        HttpHeaders headers = new HttpHeaders();
        headers.set("Accept", "application/json");
        headers.set("Authorization", authHeader);

        Map variables = new HashMap(1);
        variables.put("phone", telephone_number);
        ResponseEntity exchange = restTemplate.exchange(telco_location, HttpMethod.GET, new HttpEntity(headers), LocationResponse.class, variables);

        System.out.println(exchange.getStatusCode());
        System.out.println(exchange.getBody().getResult());
        System.out.println(exchange.getBody().getLongitude());
        System.out.println(exchange.getBody().getLatitude());
        System.out.println(exchange.getBody().getAccuracy());
        System.out.println(exchange.getBody().getAltitude());
        System.out.println(exchange.getBody().getTimestamp());
        
        return exchange.getBody();
    }
}

And class which help to deserialization XML :


@XmlRootElement(name = "response")
public class LocationResponse {

    @XmlElement
    private String result;
    @XmlElement
    private String latitude;
    @XmlElement
    private String longitude;
    @XmlElement
    private String altitude;
    @XmlElement
    private String accuracy;
    @XmlElement
    private String timestamp;

    public LocationResponse() {
    }

    public LocationResponse(String result, String latitude, String longitude, String altitude, String accuracy, String timestamp) {
        this.result = result;
        this.latitude = latitude;
        this.longitude = longitude;
        this.altitude = altitude;
        this.accuracy = accuracy;
        this.timestamp = timestamp;
    }

    public String getResult() {
        return result;
    }

    public String getLatitude() {
        return latitude;
    }

    public String getLongitude() {
        return longitude;
    }

    public String getAltitude() {
        return altitude;
    }

    public String getAccuracy() {
        return accuracy;
    }

    public String getTimestamp() {
        return timestamp;
    }

    @Override
    public String toString() {
        return "LocationResponse{" + "result=" + result + ", latitude=" + latitude + ", longitude=" + longitude + ", altitude=" + altitude + ", accuracy=" + accuracy + ", timestamp=" + timestamp + '}';
    }
}

UPDATE According to Abhijit comment, we can use ClientHttpRequestFactory used as a parameter in RestTemplate constructor. Just implement a ClientHttpRequestFactory and override the prepareConnection method to achieve the same effect as above, but with limiting customers of your system instead of sharing it globally with everyone [3].


Reference :
[1] Source Pastebin Main Class
[2] Source Pastebin XML Deserialization
[3] ClientHttpRequestFactory Example