How to make patch http request in groovy - http

Why its not works ?
def post = new URL(url).openConnection();
post.setRequestMethod("PATCH");
post.setDoOutput(true);
post.setRequestProperty("Content-Type", "application/json");
post.getOutputStream().write(body.getBytes("UTF-8"));
def postRC = post.getResponseCode();
logger.info("Status code = ${postRC}");
returns error = java.net.ProtocolException: Invalid HTTP method: PATCH

old java HttpUrlConnection.setRequestMethod() does not support patch method:
https://docs.oracle.com/javase/10/docs/api/java/net/HttpURLConnection.html#setRequestMethod(java.lang.String)
public void setRequestMethod​(String method) throws ProtocolException
Set the method for the URL request, one of:
GET
POST
HEAD
OPTIONS
PUT
DELETE
TRACE
however there is a trick - in groovy you could set protected property value and there is a property method
https://docs.oracle.com/javase/10/docs/api/java/net/HttpURLConnection.html#method
so you could change the code:
def body = [test:123]
def post = new URL("http://httpbin.org/patch").openConnection();
post.method ="PATCH";
post.setDoOutput(true);
post.setRequestProperty("Content-Type", "application/json");
post.getOutputStream().withWriter("UTF-8"){ it << new groovy.json.JsonBuilder(body) }
def postRC = post.getResponseCode();
println "Status code = ${postRC}"
println post.getInputStream().getText("UTF-8")

Related

how to update the incoming request in pact jvm requestFilter?

I have a spring boot API in java which is using pact-jvm for pact verification.
We have a new client who wants to use the same API using a new path, which the gateway will take care of, but this causes issue for pacts, I want to intercept the request and modify the path of the request for new pacts to point to old path.
I was trying to refer some material online and found this :
https://medium.com/dazn-tech/pact-contract-testing-dealing-with-authentication-on-the-provider-51fd46fdaa78
The below code prints the updated value of the request, but the pact still fails with 404 error as if it is still using new path
requestFilter = { req ->
println "incoming request : $req"
if ("$req".contains('/new-context') ) {
req = "$req".replace('/new-context', '/old-context')
println "updated request : $req"
}
}
The problem in the above code was I was treating req as string and doing manipulations, but it is an HttpRequest object and the below code solved the issue for me:
requestFilter = { req ->
def uriText = req.getURI()
println "incoming request uri : $uriText"
if ("$uriText".contains('/new-context') ) {
def uriTextNew = "$uriText".replace('/new-context', '/old-context')
println "updated request uri : $uriTextNew"
URI newURI = new URI(uriTextNew)
req.setURI(newURI)
}
}

Consume Html response using restTemplate

I want to consume html response using restTemplate and rerun that response to my html so i can add those content to my html page but getting below error tried so many alternatives but not luck
I want to consume every type of response and return that as it is to my html/jsp via ajax and render that content in a div.
HTML (ajax call) --- Spring MVC (rest call to 3rd party) --- application returns html
Code
#RequestMapping(value = "/xyz-service/**", method = {RequestMethod.GET, RequestMethod.PUT},produces="application/json;charset=UTF-8")
public Object mirrorRest(HttpServletRequest request) {
String url = request.getRequestURI();
return restTemplate.getForObject("http://xyz-service:8080"+url , String.class);
}
I am able to invoke my serive method that retuning html as respose but getting error
"Could not extract response: no suitable HttpMessageConverter found for response type [class java.lang.String] and content type [text/html;charset=UTF-8]"
]
The exception seem to have occurred because your request was missing the header parameters.
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Bearer " + apikey);
headers.set("Charset", "utf-8");
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<Request> entity = new HttpEntity<Request>(
req, headers); //incase if your request have a request body
try {
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, entity, String.class); //if no request body you could simply use headers parameter directly
logger.info(response.toString());
return response.getBody().toString();
} catch (HttpStatusCodeException exception) {
logger.info("API failed"+exception);
return null;
}
No you can't. An HTML page is not a json object: REST template is designed to consume RestServices.
You should use a URLConnection from jdk

HttpPost request including spaces fails

When using a HttpPost request I use UTF-8 for proper encoding. When I use a space in one of the parameters, I still get the following error:
Caused by: org.apache.http.ProtocolException: Invalid redirect URI: /seek/nearest.aspx?key=Miami vice&ex=0&cFilter=9a79e6ce-3344-409c-bbe9-496530baf758&children=n
The invalid character in the URL is the space between the "Miami" and "vice".
Hmmm, I thought that the POST request is not put in the URL string.
These are the steps I take to build the HttpPost request. In the "mKeyword" is the string with "Miami vice".
1 - put the request in the NameValue list:
List<NameValuePair> kwNvP = new ArrayList<NameValuePair>();
kwNvP.add(new BasicNameValuePair("ctl00$ContentBody$LocationPanel1$OriginText", mKeyword));
2 - build the URI
String search_url = "http://www.example.com/seek/nearest.aspx";
try {
theUri = new URI( search_url);
} catch ( URISyntaxException e) { etc.
3 - build the post request
HttpPost method = new HttpPost( theUri);
method.addHeader("User-Agent", "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0) Firefox/7.0");
method.addHeader("Pragma", "no-cache");
method.addHeader("Content-Type", "application/x-www-form-urlencoded");
method.addHeader("Accept-Language", "en");
4 - build the content entity
HttpEntity entity = null;
try {
entity = new UrlEncodedFormEntity( kwNvP, HTTP.UTF_8);
}
catch ( UnsupportedEncodingException e) { etc
5 - executing the request
method.setEntity( entity);
HttpResponse res2 = null;
try {
Thread.sleep( (int) (1000 * GeoTools.random( 0.1, 0.3)));
res2 = client2.execute(method);
Log.v( WaypointActivity.TAG, "Status line = " + String.valueOf(res2.getStatusLine()));
} catch (Exception e) {
// --> Coming here ... see the exception trace
Can you help me solving this problem?
Without seeing the complete program or the real target URL I'm not 100% sure ... but this part of the error stands out:
Invalid redirect URI
That implies that your original POST request is not returning a 200 but a 301, and whatever server is handling the redirect is creating the malformed URL, not your code.

400 Bad request in J2me

I am trying to hit .svc service from my JME application using POST method. but getting 'bad request'. Following is my code.
HttpConnection hc = (HttpConnection) Connector.open(url, Connector.READ_WRITE);
hc.setRequestMethod(HttpConnection.POST);
hc.setRequestProperty("User-Agent", "Profile/MIDP-1.0 Configuration/CLDC-1.0" );
hc.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
hc.setRequestProperty("Content-Length", ""+(postMsg.getBytes().length));
out = hc.openOutputStream();
out.write(postMsg.getBytes());
System.out.println("hc.getResponseCode() = "+hc.getResponseCode()+ " hc.getResponseMessage() = "+hc.getResponseMessage());
Please tell me what is wrong with the code.
Instead of http, I used Ksoap2-j2me-core jar with following code that i found -
SoapObject request = new SoapObject("namespace", "login");
request.addProperty("username", "pranav");
request.addProperty("password", "gangan");
//create the SOAP envelope
final SoapSerializationEnvelope env = new SoapSerializationEnvelope(SoapEnvelope.VER11);
env.setOutputSoapObject(request);
//create the transport and then call
final HttpTransport httpTransport = new HttpTransport("http://URL");
httpTransport.call("\"login\"", env);
SoapObject body = (SoapObject) env.bodyIn;
//body.getProperty(0) will return the content of the first tag inside body
Object response = body.getProperty(0);
System.out.println(response.toString);

Groovy/Grails posting XML over HTTP (using REST plugin)

I am trying HTTP Post an XML string to a WebMethods server using basic auth. I was trying to use the REST plugin which sits on top of HTTP Builder. I've tried a few things all resulting in a 0 length response. Using Firefox poster I have used the exact same XML and user auth and the WebMethods response is to echo back the request with some extra info, so it is something I am doing in the code below that is wrong. Hope someone has a pointer for doing a HTTP Post of XML.
string orderText = "<item>
<item>1</item>
<price>136.000000</price>
</item>"
def response = withHttp(uri: "https://someserver.net:4433") {
auth.basic 'user', 'pass'
// have tried body: XmlUtil.serialize(orderText)
def r = post(path: '/invoke/document', body: orderText, contentType: XML, requestContentType: XML)
{ resp, xml ->
log.info resp.status
log.info resp.data
resp.headers.each {
log.info "${it.name} : ${it.value}"
}
}
log.info r
return r
}
Logs say:
04-02-2011 14:19:39,894 DEBUG HTTPBuilder - Response code: 200; found handler: OrdersService$_closure1_closure2_closure3_closure4#36293b29
04-02-2011 14:19:39,895 INFO HTTPBuilder - Status: 200
04-02-2011 14:19:39,896 INFO HTTPBuilder - Data: null
04-02-2011 14:19:39,896 INFO HTTPBuilder - XML: null
04-02-2011 14:19:39,913 INFO HTTPBuilder - Content-Type : application/EDIINT; charset=UTF-8
04-02-2011 14:19:39,913 INFO HTTPBuilder - Content-Length : 0
Cheers,
Steve
Here is what I ended up with. It is quite standard use of common HTTP Client
For basic auth over SSL you can simply have your url like: https://user:pass#www.target.com/etc
Grails remember to copy the HTTPClient jar to the lib folder or in my case I installed the REST plugin which includes HTTPClient anyway.
There are good docs on the HTTPClient site: http://hc.apache.org/httpcomponents-client-ga/
import org.apache.http.HttpEntity
import org.apache.http.HttpResponse
import org.apache.http.client.HttpClient
import org.apache.http.client.methods.HttpPost
import org.apache.http.entity.StringEntity
import org.apache.http.impl.client.DefaultHttpClient
def sendHttps(String httpUrl, String data) {
HttpClient httpClient = new DefaultHttpClient()
HttpResponse response
try {
HttpPost httpPost = new HttpPost(httpUrl)
httpPost.setHeader("Content-Type", "text/xml")
HttpEntity reqEntity = new StringEntity(data, "UTF-8")
reqEntity.setContentType("text/xml")
reqEntity.setChunked(true)
httpPost.setEntity(reqEntity)
log.info "executing request " + httpPost.getRequestLine()
response = httpClient.execute(httpPost)
HttpEntity resEntity = response.getEntity()
log.info response.getStatusLine()
if (resEntity != null) {
log.with {
info "Response content length: " + resEntity.getContentLength()
if (isDebugEnabled()) {
debug "Response Chunked?: " + resEntity.isChunked()
debug "Response Encoding: " + resEntity.contentEncoding
debug "Response Content: " + resEntity.content.text
}
}
}
// EntityUtils.consume(resEntity);
}
finally {
// When HttpClient instance is no longer needed,
// shut down the connection manager to ensure
// immediate deallocation of all system resources
httpClient.getConnectionManager().shutdown()
}
return response.getStatusLine()
}
try it this way:
HTTPBuilder builder = new HTTPBuilder( url )
builder.request( Method.POST ) {
// set uriPath, e.g. /rest/resource
uri.path = uriPath
requestContentType = ContentType.XML
// set the xml body, e.g. <xml>...</xml>
body = bodyXML
// handle response
response.success = { HttpResponseDecorator resp, xml ->
xmlResult = xml
}
}
I guess there's no need to get it done that difficult, I use a simpler approach (by the way you don't need extra plugins). So consider the next piece of code, and of course I'm ommiting the authentication part
class YourController{
static allowedMethods = [operation:['POST','GET']]
def operation(){
def xmlRequest = request.reader.text
println xmlRequest
//TODO: XML postprocessing, here you might use XmlParser.ParseText(xmlRequest)
}
}
I know this might be out of context because you are asking for the REST plugin, yet I wanted to share this since there's another alternative.
I'm using grails 2.3.2 and Firefox RESTClient to test the webservice.

Resources