I am trying to send a POST request to a Restful WS with the request originally being xml and so is the response.
I need to have basic authentication sent as well. At first I was having issues with Classes not being defined and thankfully it took 6 jars to resolve that.
Now I keep getting the following: Caught: groovyx.net.http.HttpResponseException: Bad Request
Sounds like it doesn't like the POST request. I have tried different ways including RESTClient, I have tried to delegate the request in its raw xml format by passing a file or as a string var. I don't fully understand the difference between post or request methods in httpBuilder.
If anyone can help point me in what I did wrong would be very thankful
def http = new HTTPBuilder('http://some_IP:some_Port/')
http.auth.basic('userName','password')
http.post(path:'/path/ToServlet')
http.post(POST,XML)
{
delegate.contentType="text/xml"
delegate.headers['Content-Type']="text/xml"
//delegate.post(getClass().getResource("/query.xml"))
// body = getClass().getResource("/query.xml")
body =
{
mkp.xmlDeclaration()
Request{
Header{
Command('Retrieve')
EntityIdentifiers
{
Identifier(Value:'PhoneNumber', Type:'TelephoneNumber')
}
EntityName('Subscriber')
}
}
}
}
Now in case I translated the XML wrong in my request here is the XML version of it:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Provisioning xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <Request> <Header> <Command>Retrieve</Command> <EntityIdentifiers> <Identifier Value="phoneNumber" Type="TelephoneNumber" /> </EntityIdentifiers> <EntityName>Subscriber</EntityName> </Header> </Request> </Provisioning>
okay so after sometime I have gathered the solution was in upgrading groovy library to 2.4 and httpClient4.0.1 and httpBuilder 4.x
That seems to have done the trick as I was originally working with groovy 1.5.5 The other option you have is to user Java and Groovy together Java to establish the connection using URL and HttpURLConnection classes hopefully there are enough examples there. Be mindful that this is not SSL and may need to take extra steps if you want to do this with SSL and https
import groovy.xml.*
import groovy.util.XmlSlurper.*
import groovy.util.slurpersupport.GPathResult.*
import groovyx.net.http.HTTPBuilder
import groovyx.net.http.EncoderRegistry
import java.net.URLEncoder
import java.net.URLEncoder.*
import org.apache.http.client.*
import org.apache.http.client.HttpResponseException
import org.apache.http.protocol.ResponseConnControl;
import org.apache.http.conn.ssl.*
import org.apache.http.conn.ssl.TrustStrategy
import static java.net.URLEncoder.encode
import static groovyx.net.http.ContentType.*
import static groovyx.net.http.HTTPBuilder.request
import static groovyx.net.http.Method.POST
//import static groovyx.net.http.RESTClient.*
def SMSCmirrorServerTor = "http://IP:PORT"
def SMSCmirrorServerMntrl = "http://IP:PORT"
def msisdn = args[0]
//Connect to method HTTP xml URL encoded request, XML response
def connectSMSC(server, MSISDN)
{
// Variables used for the response
def result = ""
//Variables used for request
// one way is to use raw xml
def rawXML = """
<Provisioning xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
<Request>
<Header>
make sure your <xml> is well formatted use xml formatter online if need be
</Header>
</Request>
</Provisioning>"""
def http = new HTTPBuilder(server)
http.auth.basic('username','password')
http.contentType = TEXT
http.headers = [Accept: 'application/xml', charset: 'UTF-8']
http.request(POST)
{
uri.path = 'Servlet or WS/Path'
requestContentType = URLENC
body = "provRequest=" + encode(rawXML,"UTF-8")
response.success = { resp, xml ->
def xmlParser = new XmlSlurper().parse(xml)
//Helps if you know in advance the XML response tree structure at this point it's only xmlSlurper doing the work to parse your xml response
def ResponseStatus = xmlParser.Response.Header.ResponseStatus
result += "Response Status: " + ResponseStatus.toString() + "\n================\n"
def ResponseHeader = xmlParser.Response.Header.Errors.Error
ResponseHeader.children().each
{
result += "\n${it.name()}: " + it.text().toString() + "\n"
}
def xmlDataRootNode = xmlParser.Response.Data.Subscriber
xmlDataRootNode.children().each
{
if (it.name() == 'UserDevices')
{
result += "\n" + it.UserDevice.name() + " :" + "\n-----------------\n"
it.UserDevice.children().each
{
result += it.name() + " :" + it.text().toString() + "\n"
}
}
else
{
result += "\n${it.name()}: " + it.text().toString() + "\n"
}
}//End of each iterator on childNodes
if (ResponseStatus.text().toString() == "Failure")
{
def ErrorCode = resp.status
result += "Failed to process command. Bad request or wrong input"
//result += "\nHTTP Server returned error code: " + ErrorCode.toString()
// Note this error is for bad input server will still return status code 200 meaning o.k. unlike err 401 unathorized or err 500 those are http errors so be mindful of which error handling we're talking about here application layer vs http protocol layer error handling
}
}//End of response.success closure
}//End of http.request(POST) method
result
}//end of connectSMSC method
//the following is only in case server A is down we can try server B
def finalResponse=""
try
{
finalResponse += connectSMSC(SMSCmirrorServerTor,msisdn)
}
catch(org.apache.http.conn.HttpHostConnectException e)
{
finalResponse += "Encountered HTTP Connection Error\n ${e}\n Unable to connect to host ${SMSCmirrorServerTor}\n Trying to connect to mirror server ${SMSCmirrorServerMntrl} instead\n"
finalResponse += connectSMSC(SMSCmirrorServerMntrl,msisdn)
}
catch (groovyx.net.http.HttpResponseException ex)
{
finalResponse += "Encountered HTTP Connection Error Code: ${ex.statusCode}\n"
finalResponse += connectSMSC(SMSCmirrorServerMntrl,msisdn)
}
/*
*
* java.lang.IllegalArgumentException: port out of range:
*/
catch(java.lang.IllegalArgumentException e)
{
finalResponse += "Error: " + e
}
catch(java.io.IOException e)
{
finalResponse += "IO Error: " + e
finalResponse += connectSMSC(SMSCmirrorServerMntrl,msisdn)
}
catch(java.io.FileNotFoundException e)
{
finalResponse += "IO Error: " + e
finalResponse += connectSMSC(SMSCmirrorServerMntrl,msisdn)
}
println finalResponse.toString()