How to send DELETE request using HttpClient - java

how can I send an http DELETE request to this
using HttpClient object or something similar?
This is my code for GET and POST requests:
public class Main {
public static void main(String[] args) throws IOException, InterruptedException {
//jsonGetRequest();
//jsonPostRequest();
}
public static void jsonGetRequest() throws IOException, InterruptedException {
final String URL = "https://vbzrei5wpf.execute-api.us-east-1.amazonaws.com/test/pets";
HttpClient httpClient = HttpClient.newHttpClient();
HttpRequest httpRequest = HttpRequest
.newBuilder()
.GET()
.header("accept", "application/json")
.uri(URI.create(URL))
.build();
HttpResponse<String> httpResponses = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());
//System.out.println(httpResponses.body()); // stampa l'intero file JSON
// Parsing JSON into Objects
ObjectMapper objectMapper = new ObjectMapper();
List<Pet> pets = objectMapper.readValue(httpResponses.body(), new TypeReference<List<Pet>>() {
});
//pets.forEach(System.out::println); oppure
for (Pet pet : pets) {
System.out.println(pet.getId() + ", " + pet.getType() + ", " + pet.getPrice());
}
}
public static void jsonPostRequest() throws IOException, InterruptedException {
final String URL = "https://vbzrei5wpf.execute-api.us-east-1.amazonaws.com/test/pets";
final Map<String, Object> values = new HashMap<>();
values.put("type", "octopus");
values.put("price", 12.99);
ObjectMapper objectMapper = new ObjectMapper();
String requestBody = objectMapper.writeValueAsString(values);
HttpClient httpClient = HttpClient.newHttpClient();
HttpRequest request = HttpRequest
.newBuilder()
.uri(URI.create(URL))
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
HttpResponse<String> response = httpClient.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
public static void jsonDeleteRequest() {
final String URL = "https://vbzrei5wpf.execute-api.us-east-1.amazonaws.com/test/pets";
// TODO...
}
}

A DELETE request is sent the same way as GET, just use the "DELETE" method instead of "GET":
HttpRequest httpRequest = HttpRequest
.newBuilder()
.DELETE()
.uri(URI.create(URL))
.build();

If you want to delete an object use #Joni's answer. If you want to specify the id of the object, add /<id> to your url
https://vbzrei5wpf.execute-api.us-east-1.amazonaws.com/test/pets/1 would be the url to delete the element with the id 1

Related

Conditional Base pass dynamic value inside request body

I want to pass dynamic value inside request body in my case I pass
thirdpartypaymentGatewayToken in two place inside request body and an
other place requestString as requestBody but I want make single
function and pass values inside request body dynamic. for your
reference I post my old code and new code.
Here my old code
public ThirdPartyPaymentGatewayResponse getThirdPartyPaymentGatewayToken(ThirdPartyPaymentGatewayToken thirdPartyPaymentGatewayToken, String managedBy)
throws AuthenticationException, UnknownHostException, BadRequestException {
String brandwiseBearerToken = getBrandwiseAuthenticationToken();
ThirdPartyPaymentGatewayResponse thirdPartyPaymentGatewayResponse = new ThirdPartyPaymentGatewayResponse();
String thirdPartyPaymentGatewayTokenJson = ow.writeValueAsString(thirdPartyPaymentGatewayToken);
RequestBody body = RequestBody.create(mediaType, thirdPartyPaymentGatewayTokenJson);
Request request = new Request.Builder().url(brandwiseThirdPartypaymentGatewayURL)
.post(body)
.addHeader("Content-Type", "application/json")
.addHeader("Bearer", brandwiseBearerToken)
.build();
Response response = client.newCall(request).execute();
ResponseBody responseBody = response.body();
JsonObject jsonObject = new Gson().fromJson(responseBody.string(), JsonObject.class);
JsonElement error = jsonObject.get("Message");
}
> second function
public ThirdPartyPaymentGatewayResponse getThirdPartyPaymentGatewayToken(ThirdPartyPaymentGatewayToken thirdPartyPaymentGatewayToken, String managedBy)
throws AuthenticationException, UnknownHostException, BadRequestException {
String brandwiseBearerToken = getBrandwiseAuthenticationToken();
String thirdPartyPaymentGatewayTokenJson = ow.writeValueAsString(thirdPartyPaymentGatewayToken);
RequestBody body = RequestBody.create(mediaType, thirdPartyPaymentGatewayTokenJson);
Request request = new Request.Builder().url(brandwiseThirdPartypaymentGatewayURL)
.post(body)
.addHeader("Content-Type", "application/json")
.addHeader("Bearer", brandwiseBearerToken)
.build();
Response response = client.newCall(request).execute();
ResponseBody responseBody = response.body();
JsonObject jsonObject = new Gson().fromJson(responseBody.string(), JsonObject.class);
JsonElement error = jsonObject.get("Message");
/** rest of code*/
}
third function different than other two
private String getBrandwiseAuthenticationToken() throws UnknownHostException, AuthenticationException {
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("application/json");
String requestString = "{\"LoginName\": \"" + brandwiseAuthUsername + "\",\"Password\": \""+ brandwiseAuthPassword + "\"}";
RequestBody body = RequestBody.create(mediaType, requestString);
Request request = new Request.Builder().url(brandwiseAuthenticationURL)
.post(body)
.addHeader("Content-Type", "application/json")
.build();
Response response = client.newCall(request).execute();
ResponseBody responseBody = response.body();
JsonObject jsonObject = new Gson().fromJson(responseBody.string(), JsonObject.class);
}
To overcome from this issue I do this way but I am not able make
request body as dynamic. Here my new code
private JsonObject gateWayToken(String url,String brandwiseBearerToken,
ThirdPartyPaymentGatewayToken thirdPartyPaymentGatewayToken ) throws IOException, AuthenticationException{
ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
String requestString = "{\"LoginName\": \"" + brandwiseAuthUsername + "\",\"Password\": \""+ brandwiseAuthPassword + "\"}";
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body=null;
//dynamic value accept by body
if(!Strings.isNullOrEmpty(requestString)) {
String brandwiseBearerPaymentGatewayTokenJson = ow.writeValueAsString(requestString);
body = RequestBody.create(mediaType,brandwiseBearerPaymentGatewayTokenJson);
}else {
String thirdPartyPaymentGatewayTokenJson = ow.writeValueAsString(thirdPartyPaymentGatewayToken);
body = RequestBody.create(mediaType,thirdPartyPaymentGatewayTokenJson );
}
//if user is authenticated then header part will show
Request request=null;
if (brandwiseBearerToken != null && StringUtils.isNotEmpty(brandwiseBearerToken)) {
request =new Request.Builder().url(url).post(body)
.addHeader("Content-Type", "application/json")
.addHeader("Bearer", brandwiseBearerToken)
.build();
} else {
request=new Request.Builder().url(url).post(body)
.addHeader("Content-Type", "application/json")
.build();
}
Response response = client.newCall(request).execute();
ResponseBody responseBody = response.body();
return new Gson().fromJson(responseBody.string(), JsonObject.class);
}
I want to dynamic exact at this point
if(!Strings.isNullOrEmpty(requestString)) {
String brandwiseBearerPaymentGatewayTokenJson = ow.writeValueAsString(requestString);
body = RequestBody.create(mediaType,brandwiseBearerPaymentGatewayTokenJson);
}else {
String thirdPartyPaymentGatewayTokenJson = ow.writeValueAsString(thirdPartyPaymentGatewayToken);
body = RequestBody.create(mediaType,thirdPartyPaymentGatewayTokenJson );
}
Check Passing values inside ReqestBody

OkHttp implement unit test?

I have a function using OkHttp to get data from third party api
public List<AuditData> getAuditData(OkHttpClient client, int retLabelId, int countryId, int periodId, int versionNo, String URL, String token) throws IOException {
DefaultGraphQLClient graphQLClient = new DefaultGraphQLClient(URL);
String query = QueryUtils.getAuditDataQuery(retLabelId, countryId, periodId, versionNo, PartitionUtil.getReadPartition(token));
GraphQLResponse response = graphQLClient.executeQuery(query, new HashMap<>(), "", (url, headers, body) -> {
Request request = new Request.Builder()
.header("Authorization", "Bearer " + token)
.url(url)
.post(RequestBody.create(okhttp3.MediaType.parse("text/x-markdown"), body))
.build();
try {
Response responseOkHttp = client.newCall(request).execute();
return new HttpResponse(responseOkHttp.code(), responseOkHttp.body().string());
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
);
return response.extractValueAsObject("data.auditData[*]", new TypeRef<List<AuditData>>() {
});
}
I want to write unit test for the function above. I have tried with MockWebServer and it doesn't work.
MockResponse response = new MockResponse()
.addHeader("Content-Type", "application/json; charset=utf-8")
.addHeader("Cache-Control", "no-cache")
.setBody(jsonResponse);
server.enqueue(response);
OkHttpClient client = new OkHttpClient();

Okhttp Interceptor issue

I'm trying to add a header to a simple okhttp (Get) request. How do I add the HttpHeader properly? Can I debug to ensure that my Header is actually sent to the server?
Request request = new Request.Builder()
.url("URL")
.build();
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(new Interceptor() {
#Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
Request newRequest = originalRequest.newBuilder()
.addHeader("Header", "123")
.build();
return chain.proceed(newRequest);
}
})
.build();
okHttpClient.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
}
I've looked for basic simple examples but they are with Retrofit, GSON, Interfaces, or in Kotlin. Need to understand it codewise.
You can use by method addHeader send chain as param and add headers.
Request getRequest = chain.request();
Request.Builder requestBuilder = getRequest.newBuilder()
.addHeader("Header", "123");
Request request = requestBuilder.build();
return chain.proceed(request);
You can also visit and look at the answers link1 and link2.
Here is the all-request Structure you can use.
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(new Interceptor() {
#Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request original = chain.request();
Request request = original.newBuilder()
.method(original.method(), original.body())
.build();
return chain.proceed(request);
}
};
OkHttpClient client = httpClient.build();
Request request = new Request.Builder()
.url("URL")
.addHeader("Header", "123")
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
Log.d("OKHTTP3", e.getMessage());
// You get this failure
runOnUiThread(() -> {
});
}
#Override
public void onResponse(Call call, Response response) throws IOException {
try {
final String _body = response.body().string();
Log.d("OKHTTP3", _body);
runOnUiThread(() -> {
});
} catch (InterruptedIOException e) {
runOnUiThread(() -> {
// Or this exception depending when timeout is reached
});
}
}
});
To check your request and to add headers, you can use interceptors.
To add headers, (copied from gist):
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(new Interceptor() {
#Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request original = chain.request();
Request request = original.newBuilder()
.header("User-Agent", "Your-App-Name")
.header("Accept", "application/vnd.yourapi.v1.full+json")
.method(original.method(), original.body())
.build();
return chain.proceed(request);
}
}
OkHttpClient client = httpClient.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
To see your headers, you can use sample example provided here:
class LoggingInterceptor implements Interceptor {
#Override public Response intercept(Interceptor.Chain chain) throws IOException {
Request request = chain.request();
long t1 = System.nanoTime();
logger.info(String.format("Sending request %s on %s%n%s",
request.url(), chain.connection(), request.headers()));
Response response = chain.proceed(request);
long t2 = System.nanoTime();
logger.info(String.format("Received response for %s in %.1fms%n%s",
response.request().url(), (t2 - t1) / 1e6d, response.headers()));
return response;
}
}
Use addHeader() to add headers. header() sets the already added header name to the value.
Request newRequest = originalRequest.newBuilder()
.addHeader("Header", "123")
.build();
And to verify it's working correctly, you can use HttpLoggingInterceptor to log your network requests.

okHttp 3.x authenticator is not getting called

I need to make a request through a proxy that needs authentication.
public class WebClient {
private final OkHttpClient httpClient;
private static WebClient webClient;
private WebClient() {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
if (Configurator.getInstance().useProxy()) {
builder.proxySelector(new CustomProxySelector());
builder.authenticator((Route route, Response response) -> {
String credential = Credentials.basic("MYUSER", "MYPSW");
return response.request().newBuilder().header("Authorization", credential).build();
});
} else
builder.proxy(Proxy.NO_PROXY);
httpClient = builder
.connectTimeout(60, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.build();
}
}
But using a debugger i see that the authenticator method never gets called and i receive 407 as response for any request.
However, when i use HttpURLConnection with Authenticator.setDefault, it works just fine and i can use my proxy authentication:
public boolean hasInternetConnection() throws IOException {
Request httpRequest = new Request.Builder().url("http://www.google.com/").build();
// This fails with 407
Response httpResponse = httpClient.newCall(httpRequest).execute();
java.net.Authenticator authenticator = new java.net.Authenticator() {
public PasswordAuthentication getPasswordAuthentication() {
return (new PasswordAuthentication("MYUSER", "MYPSW".toCharArray()));
}
};
java.net.Authenticator.setDefault(authenticator);
URL obj = new URL("http://www.google.com/");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
// This works with 200
int responseCode = con.getResponseCode();
return false;
}
So i think the question is: why OkHttpClient.Builder.authenticator method is not getting called?
As Gimby pointed, one of the issues was that i was calling the wrong method. What confused me was that sometimes the proxyAuthenticator was not getting called and i was trying to figure why.
The application i develop needs to access resources inside and outside my job network. Therefore, when i need external access, i must use a proxy with authentication. It works like this:
A request to an internet host is made;
The ProxySelector decides that the HTTP client should use the proxy for this
request, since it is an internet host;
Since the proxy is set, the ProxyAuthenticator gets called to send
the authorization header in the request.
However, when a request is made to an internal host, the ProxySelector decides that there is no need to use a proxy. Therefore, the ProxyAuthenticator does not get called, since there is no active proxy.
Here is my implementation to anyone interested:
WebClient.java
public class WebClient {
private final OkHttpClient httpClient;
private static WebClient webClient;
private WebClient() {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
if (Configurator.getInstance().useProxy()) {
CodeUtils.setProxy();
builder.proxySelector(new CustomProxySelector());
builder.proxyAuthenticator(new CustomProxyAuthenticator());
} else {
builder.proxy(Proxy.NO_PROXY);
CodeUtils.removeProxy();
}
httpClient = builder
.connectTimeout(10, TimeUnit.SECONDS)
.writeTimeout(10, TimeUnit.SECONDS)
.readTimeout(10, TimeUnit.SECONDS)
.build();
}
public static WebClient getInstance() {
return webClient != null ? webClient : (webClient = new WebClient());
}
public static void reload() {
webClient = null;
}
public String doGet(String url) throws IOException {
Request httpRequest = new Request.Builder().url(url).build();
Response httpResponse = httpClient.newCall(httpRequest).execute();
if (httpResponse.code() != 200) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("success", false);
jsonObject.put("msg", httpResponse.body().string());
jsonObject.put("httpCode", httpResponse.code());
return jsonObject.toString();
}
return httpResponse.body().string();
}
public String doPost(String url, JSONObject body) throws IOException {
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), body.toString());
Request request = new Request.Builder()
.header("Accept", "application/json")
.header("Content-type", "application/json; charset=UTF-8")
.url(url)
.post(requestBody).build();
Response response = httpClient.newCall(request).execute();
return response.body().string();
}
}
CustomProxyAuthenticator.java
public class CustomProxyAuthenticator implements Authenticator {
#Override
public Request authenticate(Route route, Response response) throws IOException {
String username = Configurator.getInstance().getProxyUser();
String password = Configurator.getInstance().getProxyPassword();
String credential = Credentials.basic(username, password);
return response.request().newBuilder()
.header("Proxy-Authorization", credential)
.build();
}
}
CustomProxySelector.java
public class CustomProxySelector extends ProxySelector {
private Configurator configurator = Configurator.getInstance();
private List<String> nonProxyHosts = Arrays.asList(configurator.getNonProxyHosts().split("\\|"));
private String proxyHost = configurator.getProxyHost();
private int proxyPort = configurator.getProxyPort();
#Override
public List<Proxy> select(URI uri) {
final List<Proxy> proxyList = new ArrayList<>(1);
String host = uri.getHost();
if (host.startsWith("127.0.0.1") || nonProxyHosts.contains(host))
proxyList.add(Proxy.NO_PROXY);
else
proxyList.add(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort)));
return proxyList;
}
#Override
public void connectFailed(URI arg0, SocketAddress arg1, IOException arg2) {
}
}

Design pattern for retrofit interface

I have trouble with the design of my Retrofit interface creator. I want to be able to instanciate the API interface in a generic way and update the corresponding instance whenever a token is passed. Currently, when I update the token, I have to call createService() method again to get the new instance that used the token in the generation of the Interface...
Somebody asked for a similar question but never got an answer here
public class RetrofitCreator {
private static String TAG = "RetrofitCreator";
private static String WSSE = null;
private static String AmzToken = null;
static HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
private static AmazonAPI amazonAPI = null;
private static VanishAPI cobaltAPI = null;
//static OkHttpClient client = new OkHttpClient.Builder().build();
static OkHttpClient.Builder httpClient = new OkHttpClient.Builder().addInterceptor(interceptor.setLevel(HttpLoggingInterceptor.Level.BODY));
private static Retrofit.Builder builder =
new Retrofit.Builder();
public static <S> S createService(Class<S> serviceClass) {
S mAPI = null;
if(serviceClass.getSimpleName().equals("VanishAPI")){
if(VanishAPI==null){
VanishAPI = (VanishAPI) createVanishAPI(serviceClass);
}
mAPI = (S) VanishAPI;
}else if(serviceClass.getSimpleName().equals("AmazonAPI")){
if(amazonAPI==null){
amazonAPI = (AmazonAPI) createAmazonAPI(serviceClass);
}
mAPI = (S) amazonAPI;
}
return mAPI;
}
public static void setWSSE(String WSSE) {
RetrofitCreator.WSSE = WSSE;
vanishAPI = createVanishAPI(VanishAPI.class);
}
public static void setAmzToken(String token) {
RetrofitCreator.AmzToken = token;
amazonAPI = createAmazonAPI(AmazonAPI.class);
}
private static <S> S createAmazonAPI(Class<S> serviceClass){
httpClient = getUnsafeOkHttpClient();
builder = new Retrofit.Builder()
.baseUrl(Constants.URL_AMAZON)
.addConverterFactory(JacksonConverterFactory.create());
if (AmzToken != null) {
Log.w(TAG, "WSSE not null!");
Interceptor interceptorSecure = new Interceptor() {
#Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request original = chain.request();
// Request customization: add request headers
Request.Builder requestBuilder = original.newBuilder()
.header("Cache-Control", "no-cache")
.header("Accept", "application/json")
.header("Authorization", "Bearer " + AmzToken)
.method(original.method(), original.body());
Request request = requestBuilder.build();
return chain.proceed(request);
}
};
httpClient.addInterceptor(interceptorSecure);
}
OkHttpClient client = httpClient.build();
Retrofit retrofit = builder.client(client).build();
return retrofit.create(serviceClass);
}
(...)
}
To get it in each Activity I use :
amazonApi = RetrofitCreator.createService(AmazonAPI.class);
Make your interceptor look like this:
public class TokenInterceptor implements Interceptor {
private String token;
public String getToken() {
return token;
}
#Override
public Response intercept(Chain chain) throws IOException {
Request original = chain.request();
// Request customization: add request headers
Request.Builder requestBuilder = original.newBuilder()
.header("Cache-Control", "no-cache")
.header("Accept", "application/json")
.method(original.method(), original.body());
if (getToken() != null) {
requestBuilder.header("Authorization", "Bearer " + AmzToken);
}
Request request = requestBuilder.build();
return chain.proceed(request);
}
public void setToken(String token) {
this.token = token;
}
}
Add it to you OkHttp client and keep reference to this interceptor.
Now you don't have to call createService() after each token change. Just change token in interceptor via interceptor.setToken()

Categories

Resources