HTTPBuilder is a wrapper of Apache famous HttpClient. However, job done in Groovy is like a breathe of fresh air compared to Java.
Here is an example, using HTTPBuilder make a REST service call, getting JSON response, plus the integration test. Implemented in Grails 1.3.5. Maybe you don’t fully understand why do this, why do that, but just look and feel codes at first.
- in Config.groovy define web service URI in location.service.uri:
[groovy]
import grails.plugins.springsecurity.SecurityConfigType
…
environments {
production {
grails.config.locations = [ "classpath:production.properties"]
}
development {
grails.serverURL = "http://localhost:8080/${appName}"
location.service.uri = "http://somewhere.over.the.rainbow:10080"
}
test {
grails.serverURL = "http://localhost:8080/${appName}"
location.service.uri = "http://dummyURI/"
}
}
…
/——————————————————————————
// Security configuration
//——————————————————————————
grails.plugins.springsecurity.providerNames = [‘preauthAuthProvider’]
grails.plugins.springsecurity.auth.loginFormUrl = ‘/login’
grails.security.rolePrefix = ""
grails.plugins.springsecurity.filterChain.stripQueryStringFromUrls = false
// WARNING: if you use the following "InterceptUrlMap" it will override the default
// framework setting of "Annotation" where the security is driven at the controller
// class level
grails.plugins.springsecurity.securityConfigType = SecurityConfigType.InterceptUrlMap
grails.plugins.springsecurity.interceptUrlMap = [
‘/*/adminHome/**’: [‘ROLE_SUPER_ADMIN’, ‘IS_AUTHENTICATED_FULLY’],
‘/adminHome/**’: [‘ROLE_SUPER_ADMIN’, ‘IS_AUTHENTICATED_FULLY’],
‘/*/workCentre/**’: [‘ROLE_SUPER_ADMIN’, ‘IS_AUTHENTICATED_FULLY’],
‘/workCentre/**’: [‘ROLE_SUPER_ADMIN’, ‘IS_AUTHENTICATED_FULLY’],
‘/*/user/**’: [‘ROLE_SUPER_ADMIN’, ‘ROLE_WC_ADMIN’, ‘IS_AUTHENTICATED_FULLY’],
‘/user/**’: [‘ROLE_SUPER_ADMIN’, ‘ROLE_WC_ADMIN’, ‘IS_AUTHENTICATED_FULLY’],
‘/*/parcel/**’: [‘ROLE_WC_USER’, ‘ROLE_WC_ADMIN’, ‘IS_AUTHENTICATED_FULLY’],
‘/parcel/**’: [‘ROLE_WC_USER’, ‘ROLE_WC_ADMIN’, ‘IS_AUTHENTICATED_FULLY’]
]
[/groovy]
- in resources.xml define HTTPBuilder bean:
[xml]
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
…
<bean id="httpBuilder" class="groovyx.net.http.HTTPBuilder">
<constructor-arg value="${location.service.uri}" />
</bean>
…
</beans>
[/xml]
- in resources.groovy file:
[groovy]
import grails.util.GrailsUtil
import org.codehaus.groovy.grails.orm.hibernate.HibernateEventListeners
import org.paradise.manhattan.AuditListener
// Place your Spring DSL code here
beans = {
/**************************************
* Auditing wiring for all data updates
**************************************/
auditListener(AuditListener)
hibernateEventListeners(HibernateEventListeners) {
listenerMap = [‘pre-insert’:auditListener, ‘pre-update’:auditListener]
}
/************************
* Spring Security wiring
************************/
authenticationManager = { authenticationProvider = ref(‘preauthAuthProvider’) }
developmentSecurityFilter(org.paradise.manhattan.security.DevelopmentSecurityFilter) { authenticationManager = ref(‘authenticationManager’) }
preauthAuthProvider(org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider) {
preAuthenticatedUserDetailsService = ref("userProfileService")
throwExceptionWhenTokenRejected = true
}
transformerService(org.paradise.manhattan.integration.TransformerService)
switch(GrailsUtil.environment) {
case "test":
integrationService(test.MockIntegrationService)
break
case "functional":
integrationService(test.MockIntegrationService)
break
case "production":
integrationService(org.paradise.manhattan.integration.DefaultIntegrationService) {
transactionTemplate = ref("transactionTemplate")
manhattanWebServiceTemplate = ref("manhattanWebServiceTemplate")
jmsTemplate = ref("jmsTemplate")
transformerService = ref("transformerService")
httpBuilder = ref("httpBuilder")
}
break
default:
integrationService(org.paradise.manhattan.integration.DefaultIntegrationService) {
transactionTemplate = ref("transactionTemplate")
plisWebServiceTemplate = ref("plisWebServiceTemplate")
jmsTemplate = ref("jmsTemplate")
transformerService = ref("transformerService")
httpBuilder = ref("httpBuilder")
}
break
}
}
[/groovy]
- In DefaultIntegrationService.groovy:
[groovy]
class DefaultIntegrationService implements IntegrationService {
…
// inject HTTPBuilder bean
def httpBuilder
…
void updateLocation(Location location) {
JAXBContext jaxbContext = JAXBContext.newInstance(CustomerCollectionPoints.class)
Marshaller marshaller = jaxbContext.createMarshaller()
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true)
StringResult stringResult = new StringResult()
marshaller.marshal(transformerService.mapLocationToCustomerCollectionPoints(location, Constants.MODIFICATION_TYPE_UPDATE), stringResult)
publishLocation(stringResult)
}
private void publishLocation (StringResult stringResult) {
log.debug (stringResult.toString())
httpBuilder.request(Method.POST) {
// uri.path = "update.xml"
requestContentType = ContentType.URLENC
body = stringResult.toString()
response.success = { resp, reader ->
assert resp.statusLine.statusCode == 200
println "Request succeed with status: ${resp.statusLine}"
println "Response headers:"
resp.headers.each { h ->
println " ${h.name} : ${h.value}"
}
println "Response Data:"
println " " + reader
if (reader[‘success’] == true) {
println "Publish location(s) succeed"
} else {
println "Failed to publish location(s) due to a problem"
throw new LocationServiceException(reader.toString())
}
}
response.failure = { resp ->
log.error "Request failed with status ${resp.status}"
}
}
}
}
[/groovy]
- In Integration test DefaultIntegrationServiceTests.groovy:
[groovy]
class DefaultIntegrationServiceTests extends GrailsUnitTestCase {
def defaultIntegrationService
void testUpdateLocation() {
def httpBuilder = new MockFor(HTTPBuilder)
def result
def requestDelegate = [response: [‘statusLine’: [‘protocol’: ‘HTTP/1.1′,’statusCode’: 200, ‘status’: ‘OK’]], uri: [:]]
httpBuilder.demand.request { Method method, Closure body ->
body.delegate = requestDelegate
body.setResolveStrategy(Closure.DELEGATE_FIRST)
body.call()
requestDelegate.response.success(requestDelegate.response, [‘success’: true]) // or failure depending on what’s being tested
}
httpBuilder.use {
result = ‘200’ // Example response handler that you set in your request closure parameter
defaultIntegrationService.updateLocation(createLocation())
}
}
…
}
[/groovy]
Reference
- HTTPBuilder Overview, http://groovy.codehaus.org/modules/http-builder/home.html
- Unable to mock HTTPBuilder , http://jira.grails.org/browse/GRAILS-8617