Thursday, July 25, 2013

Groovy RESTClient, headers and authentication

I recently wanted to write some REST API calls with groovy and was using groovyx.net.http.RESTClient that is part of the HTTP Builder library (http://groovy.codehaus.org/modules/http-builder/doc/rest.html). There's not a ton of documentation on it and I was struggling to find out how to do basic authentication with it, as well as how to set headers. I finally tracked some code down on the groovy mailing list and I thought I'd detail how to do it here to help anyone else who may be looking for direct instructions how to do it. I will use the basecamp API (https://github.com/37signals/bcx-api) as an example since that's the API I was writing against (https://github.com/37signals/bcx-api). The authentication is passed by simply setting restClientInstance.auth.basic with your username and password, e.g.
def restClient = new RESTClient(...)
restClient.auth.basic "me", "password"
Headers can be set in 2 ways: by passing a map of headers when running a request, e.g.
def restClient = new RESTClient(...)
def response = restClient.get(
                   path: "projects.json",
                   headers: ["User-Agent": "My basecamp application (myemail@domain.com)"]
                )
And if you want to set a header to use on every request to the REST service, you can set default headers on the RESTClient instance, e.g.
def restClient = new RESTClient(...)
restClient.defaultRequestHeaders.'User-Agent' = "My basecamp application (myemail@domain.com)"
def response = restClient.get(path: "projects.json")
Here is a full script demonstrating how to call the projects endpoint on the basecamp api using RESTClient:
#! /usr/bin/env groovy

@Grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder', version='0.5.2' )

import static groovyx.net.http.ContentType.JSON

import groovyx.net.http.RESTClient
import groovy.util.slurpersupport.GPathResult
import static groovyx.net.http.ContentType.URLENC


def accountId = "yourAccountId" // this is the number after http://basecamp.com when logged into the basecamp website e.g. http://basecamp.com/1234567
def userName = "basecampUserName"
def password = "basecampPassword"

def basecamp = new RESTClient( "https://basecamp.com/${accountId}/api/v1/".toString() )
basecamp.auth.basic userName, password

def response = basecamp.get(
                   path: "projects.json",
                   headers: ["User-Agent": "My basecamp application (myemail@domain.com)"]
                )
println response.data.toString(2)

Wednesday, February 27, 2013

Symbolic links in Windows 7

This is just a quick note on how to create symbolic directory links in Windows 7. I like to use this for development languages/frameworks (e.g. groovy, grails) so that I can easily change the version of the language that I'm using. For example, I'll have the following setup C:\dev\lang\groovy C:\dev\lang\groovy\groovy-2.0.0 C:\dev\lang\groovy\groovy-2.1.1 C:\dev\lang\groovy\groovy-latest Where groovy-latest is a symlink to the version of groovy I want to use. I found the full directions on how to create a symbolic link in Windows here: http://www.howtogeek.com/howto/16226/complete-guide-to-symbolic-links-symlinks-on-windows-or-linux/ Here is the quick version using my above example. The command for making symlinks is called "mklink":
cd c:\dev\lang\groovy
mklink /D  groovy-latest groovy-2.1.1
The /D flag indicates this is a directory link. If the link exists already you have to remove it first:
cd c:\dev\lang\groovy
rmdir groovy-latest
mklink /D  groovy-latest groovy-2.1.1

Friday, February 22, 2013

Grails pretty print using deep JSON Converter

Here's a simple little Grails code sample to enable pretty printing on your JSON Converter when using the deep option:
def index() {
    def all = Product.list()
    withFormat {
        json {
            JSON.use("deep"){
                def c = all as JSON
                c.prettyPrint = true
                render c
            }
        }
        xml {
            XML.use("deep"){  
                render all as XML 
            }
        }
    }
}
After figuring this out I also discovered the JSON View extension for Chrome, which negated my need for pretty printing JSON.

Tuesday, October 23, 2012

Jeditable Custom Type Using Bootstrap Datepicker

I've been exploring some ajax UI techniques lately, specifically inline editing via ajax.  I came across a nice JQuery plugin called jeditable (https://github.com/tuupola/jquery_jeditable) that is working quite well for me for basic String properties. Out of the box it supports text and textarea type inputs when editing.  However, when editing a Date property, it makes more sense to use a datepicker rather than typing in dates. I've been using Twitter bootstrap for my UI and found a nice bootstrap based datepicker here:  https://github.com/eternicode/bootstrap-datepicker. In order to use the datepicker along with Jeditable, you have to extend Jeditable with a custom type.  This post will detail how to create a custom type using the Bootstrap datepicker.


JS Fiddle illustrating this integration:
fiddle: http://jsfiddle.net/4zJ7w/9/
fullscreen: http://jsfiddle.net/4zJ7w/9/embedded/result/

Step 1: Setup

First add all the js libraries/css you need and create the html to hold the date you want to edit.

<link rel="stylesheet" type="text/css" href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.1.1/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.1.1/css/bootstrap-responsive.min.css">
<link rel="stylesheet" type="text/css" href="http://vitalets.github.com/bootstrap-datepicker/bootstrap-datepicker/css/datepicker.css">

<script type='text/javascript' src='http://code.jquery.com/jquery-1.8.2.js'>
<script type='text/javascript' src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.1.1/js/bootstrap.min.js"></script>
<script type='text/javascript' src="http://www.appelsiini.net/download/jquery.jeditable.js"></script>
<script type='text/javascript' src="http://vitalets.github.com/bootstrap-datepicker/bootstrap-datepicker/js/bootstrap-datepicker.js"></script>


Step 2: The custom input type


$.editable.addInputType('datepicker', {
    element: function(settings, original) {
        var input = $('<input/>');
        $(this).append(input);
        return (input);
    },
    plugin: function(settings, original) {
        settings.onblur = 'ignore';
        $(this).find('input').datepicker({
            'autoclose': false,
            format: 'dd-mm-yyyy'
        });
    }
});

What is this doing:

Using the documentation from this Jeditable blog post: http://www.appelsiini.net/2007/8/custom-input-types we are creating a custom input type.  Jeditable has several methods you can implement to build your custom input type but in this case we are just implementing 2: element() and plugin().

The element() method is where we create the input element that will be used to edit the property.
The plugin() method is where we attach any 3rd party plugins to the input, in this case bootstrap datepicker.

Step 3:  Make it Editable

$('.editable').editable(
    function(value, settings) {
        return (value);
    }, {
        type: 'datepicker',
        indicator: 'Saving...',
        tooltip: 'Double-click to edit...',
        placeholder: '<span class="muted">Double-click to edit...</span>',
        cancel: '<button class="btn btn-mini btn-forced-margin" type="cancel" >Cancel</button>',
        submit: '<button class="btn btn-mini btn-primary btn-forced-margin" type="submit" >Save</button>',
        style: 'display: inline;',
        width: 'none',
        event: 'dblclick',
    }
);

Monday, January 14, 2008

Java Mail Encoding Problems

Well, my first blog entry is related to a programming problem I had. I figured I needed a place to store information about problems I've had to solve, that way if I run into them again, I don't have to hunt around for the solution.

The problem:

I am attempting to send email through Java and the content contains French characters. This content comes from another system, so I don't have any control over the content (i.e. don't have the ability to swap out the French characters with Unicode entity references). I am quite certain that the content I want to send is encoded in UTF-8.I'm also using Spring to help send the email (using MimeMessageHelper and JavaMailSenderImpl).

Originally the email was coming through and displaying garbage characters in place of the French characters in the email client. After some digging around, I discover that the email client thinks the content is ISO-8859-1. If I change the encoding in the client to UTF-8, the characters are displayed correctly.

So with this in mind, I realize I just need to figure out how to tell the email client that the content is UTF-8. Looking at the Spring API I see that I can set the character encoding on the MimeMessageHelper in the constructor. So I do this. The email client is now being told that the content is UTF-8, but now it seems like some kind of encoding translation is happening, because now I'm seeing the garbage characters even though the email client is set to UTF-8.

I then found this post on Java Ranch that seems related. I tried the technique found in that post to set the content - here's the code:


try{
mimeMessageHelper.setText(
new String(extendedMail.getText().getBytes(),"UTF-8"),
extendedMail.isHtml());
} catch (UnsupportedEncodingException e) {
throw new WawanesaException(e.getMessage(), e);
}




And now the content shows up correctly in my email client.