[groovy-user] Custom HTTP Method for HTTPBuilder

181 views
Skip to first unread message

Robert H

unread,
May 25, 2011, 1:16:54 PM5/25/11
to us...@groovy.codehaus.org
Good Day,


I'm trying implement a Custom HTTP Command using HTTPBuilder and can't figure out a way to make HTTPBuilder use my Command.  I've created a Java class that extends org.apache.commons.httpclient.methods.PostMethod, I see that currently HTTPBuilder only supports the following methods through the groovyx.net.http.Method class.

public enum Method {
    GET( HttpGet.class ),
    PUT( HttpPut.class ),
    POST( HttpPost.class ),
    DELETE( HttpDelete.class ),
    HEAD( HttpHead.class );

I can't extend the Method Class to overwrite the enum and I don't want to modify the groovy code to include my method.  Does anyone have an idea on how I can get HTTPBuilder to use my Custom HTTP Post Method?  I would use the regular POST but I need to change the method name in the request and that is a static variable in the HttpPost class.


Thank you for your time,

Robert

Robert H

unread,
May 31, 2011, 5:16:41 PM5/31/11
to us...@groovy.codehaus.org
Bumping this since I didn't get any replies.  Does anyone have any idea how to add a new HTTP method to HTTPBuilder without modifying the base groovy source code?

If not then I'll work on using the base Apache HTTP Libraries.


Thanks,

Robert

Thom Nichols

unread,
May 31, 2011, 9:15:07 PM5/31/11
to us...@groovy.codehaus.org
Sorry for the delayed reply Robert,

I think you can accomplish what you want by extending HTTPBuilder; you don't necessarily have to modify the existing source.  If you note that all of the 'request' calls boil down to doRequest.  You can achieve the same thing by creating a HttpRequestDelegate instance within your own HttpRequestBase subclass, and then call doRequest and pass the delegate.

-Thom

Robert H

unread,
Jun 1, 2011, 1:23:08 PM6/1/11
to us...@groovy.codehaus.org
Thanks for the Reply Thom,

Ok so I believe I figured out what to do, the post convenience method seems to show me how to wire in a custom HTTP method.  I'm guessing in the below code I just need to create a different HTTP method and follow the same process to setup the delegate and call doRequest.

I have one question, why is the groovyx.net.http.Method class marked private final?  It seemed like this would be much easier if I could just extend that class and modify the Enum to include my custom http methods.

FYI I'm not a java programmer so I may be completely off base with my above comment.


Thank you for your help,

Robert

public Object post( Map<String,?> args, Closure responseClosure )
            throws URISyntaxException, ClientProtocolException, IOException {
        RequestConfigDelegate delegate = new RequestConfigDelegate( new HttpPost(),
                this.defaultContentType,
                this.defaultRequestHeaders,
                this.defaultResponseHandlers );
   
        /* by default assume the request body will be URLEncoded, but allow
           the 'requestContentType' named argument to override this if it is
           given */
        delegate.setRequestContentType( ContentType.URLENC.toString() );
        delegate.setPropertiesFromMap( args );
       
        if ( responseClosure != null ) delegate.getResponse().put(
                Status.SUCCESS.toString(), responseClosure );

        return this.doRequest( delegate );

Robert H

unread,
Jun 1, 2011, 6:17:14 PM6/1/11
to us...@groovy.codehaus.org
So this might be a more general question but I'm having difficulty extending HTTPBuilder.  I can extend the HTTPBuilder class and call existing method through the extended class but when I attempt to instantiate the inner class RequestConfigDelegate I get Could not find matching constructor for: groovyx.net.http.HTTPBuilder$RequestConfigDelegate.  I copy and pasted the code from HTTPBuilder into my extended class and I still get that error.  I'm guessing that there is an issue in calling the inner class from the extended class.  Here is a simplified code example I think gets across the problem.

A.groovy
-------------
class A {
    private int classA = 1;
    protected class b {
        private int classb = 2;
        public b(){
            this.classb = 4;
        }
    }
}

Aextend.groovy
---------------------------
class Aextend extends A {
    private int classAE = 0
    public A(){
        this.classAE = 10;
    }
    public callinner(){
 ?????       A.b inner = new b(); ????????
    }
}

main
--------------------------------
Aextend start = new Aextend();
start.callinner();

How would I create an instance of the inner class so I can use it inside the new extended class to call other functions?


Thanks,


Robert

Thom Nichols

unread,
Jun 2, 2011, 8:27:22 AM6/2/11
to us...@groovy.codehaus.org
Hi Robert, your example works for me in groovyConsole, with a slight tweak.

But as soon as I add arguments for the inner class constructor, it doesn't work anymore.  Honestly I'm not sure what the problem is, one of the Groovy experts  can probably help.  Also, it would probably work if you defined your HttpBuilder subclass in Java and just used it from Groovy.  But I'm not sure why it's not working when defined in Groovy.  Here's my code:

Working example --------------------


class A {
    private int classA = 1;
    protected class b {
        private int classb = 2;
        public b(){
            this.classb = 4;
        }
    }
}

class Aextend extends A {
    private int classAE = 0
    public A(){
        this.classAE = 10;
    }
    public callinner(){
       def inner = new b();
       print inner.classb

    }
}

Aextend start = new Aextend();
start.callinner();
// prints 4

Not-working example, inner class has ctor arguments: --------------


class A {
    private int classA = 1;
    protected class b {
        private String a
        private int b
        private Long c
        public b(String a, int b, Long c){
            this.a = a
            this.b = b
            this.c = c

        }
    }
}

class Aextend extends A {
    private int classAE = 0
    public A(){
        this.classAE = 10;
    }
    public callinner(){
       def inner = new b("hi",123,123L);
       print inner.a

    }
}

Aextend start = new Aextend();
start.callinner();

And the exception:

groovy.lang.GroovyRuntimeException: Could not find matching constructor for: A$b(java.lang.String, java.lang.Integer, java.lang.Long)
    at Aextend.callinner(ConsoleScript18:21)
Reply all
Reply to author
Forward
0 new messages