简体   繁体   中英

Unable to run curl command from a java program

From my linux machine when I execute the following curl command, I'm able to get the response without any problem.

curl -X POST -H "Content-Type: text/xml"  -H 'SOAPAction: "someAction"' -d '<soapenv:Envelope xmlns:soapenv="http://somenamespace/">   <soapenv:Header/>   <soapenv:Body> DATA</soapenv:Body></soapenv:Envelope>' https://somewebservice/

     

But when I'm trying to execute the same command from a java program, it's throwing error. Below is my code snippet.

    try {
                    String xmlInut = "'<soapenv:Envelope xmlns:soapenv=\"http://somenamespace/\">   <soapenv:Header/>   <soapenv:Body> DATA</soapenv:Body></soapenv:Envelope>'"
                    String curlCommand = "curl -X POST -H \"Content-Type: text/xml\"  -H 'SOAPAction: \"GenerateToken\"' -d "+xmlInput+" https://somewebservice/";
                    System.out.println(curlCommand);
                    Process process = Runtime.getRuntime().exec(curlCommand);
                    BufferedReader input = new BufferedReader(new     InputStreamReader(process.getInputStream()));
                    outputString = "";
                    String line=null;
                    while((line=input.readLine())!=null)
                    {
                        outputString+=line;
                    }
                    System.out.println(outputString);

This is the error I am getting

    <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<soapenv:Fault>
<faultcode/>
<faultstring>com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character ''' (code 39) in prolog; expected '&lt;' at [row,col {unknown-source}]: [1,1]
</faultstring></soapenv:Fault></soapenv:Body></soapenv:Envelope>

How do I resolve this error? I have tried various combination of single quotes and double quotes around the namespace and the data but none of them work. I need to execute the same curl command from my java code.

Don't use curl. You don't need it. You have Java:

String xmlInput =
    "<soapenv:Envelope xmlns:soapenv=\"http://somenamespace/\">" +
    "    <soapenv:Header/>" +
    "    <soapenv:Body> DATA</soapenv:Body>" +
    "</soapenv:Envelope>";

URL url = new URL(https://somewebservice/");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "text/xml");
conn.setRequestProperty("SOAPAction", "GenerateToken");

conn.setDoOutput(true);
try (Writer requestBody =
    new OutputStreamWriter(conn.getOutputStream(), StandardCharsets.UTF_8)) {

    requestBody.write(xmlInput);
}

int responseCode = conn.getResponseCode();
if (responseCode >= 400) {
    throw new IOException("Service at " + url + " returned " + responseCode);
}

Starting in Java 11, you can use the superior java.net.http package instead:

String xmlInput =
    "<soapenv:Envelope xmlns:soapenv=\"http://somenamespace/\">" +
    "    <soapenv:Header/>" +
    "    <soapenv:Body> DATA</soapenv:Body>" +
    "</soapenv:Envelope>";

URI uri = new URI("https://somewebservice/");

HttpRequest request = HttpRequest.newBuilder(uri)
    .setHeader("Content-Type", "text/xml");
    .setHeader("SOAPAction", "GenerateToken");
    .POST(HttpRequest.BodyPublishers.ofString(xmlInput))
    .build();

String outputString =
    HttpClient.newHttpClient().send(request,
        HttpResponse.BodyHandlers.ofString());

Your original attempt was failing because the single-argument Runtime.exec is trying to parse your command as if in a shell. I hope it's now clear that you shouldn't rely on curl, but if you must, use ProcessBuilder , not Runtime.exec:

ProcessBuilder builder = new ProcessBuilder("curl", "-X", "POST",
    "-H", "Content-Type: text/xml", "-H", "SOAPAction: GenerateToken",
    "-d", xmlInput, "https://somewebservice/");

builder.redirectError(ProcessBuilder.Redirect.INHERIT);

Process process = builder.start();

String outputString;
try (InputStream processOutput = process.getInputStream()) {
    outputString = new String(processOutput.readAllBytes());
}

int exitCode = process.waitFor();
if (exitCode != 0) {
    throw new IOException("Exit code " + exitCode + " was returned by "
        + builder.command());
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM