'Getting java.io.IOException: Server returned HTTP response code: 400 for URL: when using a url which return 400 status code

I am trying to perform a get request using Groovy using the below code:

String url = "url of endpoint" def responseXml = new XmlSlurper().parse(url)

If the endpoint returns status as 200 then everything works good but there is one case where we have to validate the error response like below and status returned is 400:

    <errors>
    <error>One of the following parameters is required: xyz, abc.</error>
    <error>One of the following parameters is required: xyz, mno.</error>
    </errors>

In this case parse method throws :


    java.io.IOException: Server returned HTTP response code: 400 for URL: "actual endpoint throwing error"
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1900)
        at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1498)
        at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(XMLEntityManager.java:646)
        at com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.determineDocVersion(XMLVersionDetector.java:150)
        at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:831)
        at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:796)
        at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:142)
        at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1216)
        at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:644)
        at groovy.util.XmlSlurper.parse(XmlSlurper.java:205)
        at groovy.util.XmlSlurper.parse(XmlSlurper.java:271)
    
Can anyone pls suggest how to handle if server give error message by throwing 400 status code?


Solution 1:[1]

In the question since we are getting 400 status code for GET request. So in built XmlSlurper().parse(URI) method does not work as it throw io.Exception. Groovy also support HTTP methods for api request and response and the below worked for me:

def getReponseBody(endpoint) {     
    URL url = new URL(endpoint)
    HttpURLConnection get = (HttpURLConnection)url.openConnection()
    get.setRequestMethod("GET")
    def getRC = get.getResponseCode()

    BufferedReader br = new BufferedReader(new InputStreamReader(get.getErrorStream()))
    StringBuffer xmlObject = new StringBuffer()
    def eachLine
    while((eachLine = br.readLine()) !=null){
        xmlObject.append(eachLine)
    }
    get.disconnect()
    return new XmlSlurper().parseText(xmlObject.toString())
}

Solution 2:[2]

Getting the response text from the HttpURLConnection class rather than implicitly through XmlSlurper allows you much more flexibility in handling unsuccessful responses. Try something like this:

def connection = new URL('https://your.url/goes.here').openConnection()
def content = { ->
    try {
        connection.content as String
    } catch (e) {
        connection.responseMessage
    }
}()

if (content) {
    def responseXml = new XmlSlurper().parseText(content)
    doStuffWithResponseXml(responseXml)
}

Even better would be to use an actual full-featured HTTP client, like the Spring Framework's HttpClient or RestTemplate classes.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Andronicus
Solution 2 BalRog