1

I am trying to post payload to ClientApp RESTAPI via PATCH as HTTP_METHOD in Java.

There are lot of similar ERROR found in google and got suggestion to use X-HTTP-Method-Override header.

I followed this blog code base to achieve the same.

Java Version: 1.8.0_171

Code:

package com.in.Test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class ConnectToCorbion {
    
    
    
    public static void main(String[] args) throws IOException {
        
         String PATCH_PARAMS = "[ { \"op\": \"replace\", \"path\": \"/optionalFields1/text1\", \"value\": \"SR234568\", \"from\" : \"string\" }]";
        String my_url = "https://uat.clientapp.com/api/ChangeActivities";
        byte[] patchData       = PATCH_PARAMS.getBytes( StandardCharsets.UTF_8 );
        URL obj = null;
        
            System.out.println("BEFORE");
            obj = new URL(my_url);
            System.out.println("AFTER");
    
        
        String username = "username";
        String password = "password";

        HttpURLConnection patchConnection = null;
    
            System.out.println("BEFORE openConnection");
            try {
                patchConnection = (HttpURLConnection) obj.openConnection();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println("AFTER openConnection");
            patchConnection.setRequestMethod("PATCH");
        //patchConnection.setRequestProperty("X-HTTP-Method-Override", "PATCH");
        
        
        
        patchConnection.setRequestProperty("Accept", "application/json");
        patchConnection.setRequestProperty("Content-Type", "application/json-patch+json");
        patchConnection.setRequestProperty("messageType", "application/json-patch+json");

        // connection code if you are using java 8 or above
        patchConnection.setRequestProperty("Authorization",
            "Basic " + Base64.getEncoder().encodeToString(
              (username + ":" + password).getBytes()
            )
        );
        // connection code if you are using java 8 or above ends here

        

        patchConnection.setDoOutput(true);
        OutputStream os = null;
        
            System.out.println("BEFORE getOutputStream");
            os = patchConnection.getOutputStream();
            System.out.println("AFTER getOutputStream");
        
    
            os.write(PATCH_PARAMS.getBytes());
        
    
            os.flush();
        
            os.close();
        

        int responseCode = 0;
        
            responseCode = patchConnection.getResponseCode();
        
        System.out.println("Response Code :  " + responseCode);

        if (responseCode == HttpURLConnection.HTTP_CREATED) { //success
            BufferedReader in = null;
        
                in = new BufferedReader(new InputStreamReader(
                        patchConnection.getInputStream()));
            
            String inputLine;
            StringBuffer response = new StringBuffer();

           
                while ((inputLine = in .readLine()) != null) {
                    response.append(inputLine);
                }
            
                in .close();
            
            System.out.println(response.toString());
        } else {
            System.out.println("PATCH NOT WORKING");
        }
        
    }

}

ERROR LOG:

BEFORE
AFTER
BEFORE openConnection
AFTER openConnection
Exception in thread "main" java.net.ProtocolException: Invalid HTTP method: PATCH
    at java.net.HttpURLConnection.setRequestMethod(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.setRequestMethod(Unknown Source)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.setRequestMethod(Unknown Source)
    at com.in.Test.ConnectToCorbion.main(ConnectToCorbion.java:44)

Note: Not able to upgrade Java version as it depends on Organization infra setup.

How can i able to achieve this PATCH Request ? Kindly suggest me what went wrong or some other way to achieve the same

Justin
  • 855
  • 2
  • 11
  • 30
  • If you got error 405, or any other HTTP status code, it means there is no problem with your client code. The server rejected the verb PATCH. That's where you need to look. NB "please ignore multiple try/catch block added in above code since it is just TEST code" is not any kind of an excuse. Test code needs to be just as good as production code. Otherwise you're only testing bugs in the test code. There is no point in writing rubbish in the first place, let alone debugging the rubbish to remove the rubbish that you shouldn't have written in the first place. – user207421 Jun 14 '23 at 10:41
  • As @xerx593 says: What happened when you actually used PATCH? And are you certain that the URL you are hitting supports that method? – tgdavies Jun 14 '23 at 10:58
  • Hi @tgdavies Please see updated code by using PATCH method directly and corresponding ERROR Logs too. yes client API only accept PATCH method (works via curl/postman). Let me know if you need anymore info – Justin Jun 14 '23 at 11:59
  • Hi @user207421 As you suggested remodified code by removing multiple try/catch blocks. That client API only accepts PATCH, not sure why this PATCH request rejected , so after googling added below mentioned lined in code to overcome issue, unfortunately not working even after added below lines... patchConnection.setRequestMethod("POST");patchConnection.setRequestProperty("X-HTTP-Method-Override", "PATCH"); – Justin Jun 14 '23 at 12:04
  • I can only repeat. You need to investigate the server. The error message shows that the PATCH got through, so the problem isn't at the client. – user207421 Jun 14 '23 at 12:32
  • 1
    Correct, this jdk version client unfortunately (due to an [outdated restriction](https://github.com/frohoff/jdk8u-jdk/blob/master/src/share/classes/java/net/HttpURLConnection.java#L314)) doesn't support this (PATCH) http method. i would not try to hack (method-override), but (with java8) look for an alternative (/3rd party) client or try to upgrade java... – xerx593 Jun 14 '23 at 13:53
  • Hi @xerx593 Thanks for your valuable response. Even tried with "X-HTTP-Method-Override" , seems like not working, what other 3rd party libraries available to send PATCH request?can you suggest some other way in java 8 itself? Note: As told earlier Java upgrade is not possible in my case since there is dependency with Infra – Justin Jun 14 '23 at 14:02
  • you tried [this fix](https://stackoverflow.com/a/32503192/592355) (without considering the "server part":) ...when the server is not under your control (and it doesn't work out of box), it is waste of time. Alternatively (staying on java8): https://hc.apache.org/index.html seems an "approved oss" choice, as confirmed by [1](https://stackoverflow.com/a/25163132/592355), [2](https://stackoverflow.com/a/46907921/592355). "Hacking client" though seems also quite popular [3](https://stackoverflow.com/a/46323891/592355), [4](https://stackoverflow.com/a/40606633/592355) – xerx593 Jun 14 '23 at 14:23

1 Answers1

0

"PATCH" is not supported with Java 8 for setRequestedMethod within HttpURLConnection. You can use "POST" instead and set "X-HTTP-Method-Override" header attribute to "PATCH" as a work-around solution.

patchConnection.setRequestMethod("POST");
patchConnection.setRequestProperty("X-HTTP-Method-Override", "PATCH");
evren
  • 130
  • 5
  • Hi @evren I tired above mentioned way also, still getting "405 Method Not Allowed" error response. no luck – Justin Jun 16 '23 at 08:20
  • have you tried from some other rest client like postman or soap ui. where you can easily change the http method and header and test the API. As it might be that the service endpoint is not excepting some other http method for the operation you are trying – techprat Jun 16 '23 at 12:11
  • Hi @techprat Yes tried via postman with PATCH method, which gives desired results, the same endpoint trying to invoke via programming which resulted "405 Method Not Allowed" error. – Justin Jun 16 '23 at 12:27