have a .properties file and need to use it in grails?
Stick in the the src/java directory and it will automagically get copied over to the web-inf directory in project directory of your .grails folder.
Posted in: Uncategorized
Stick in the the src/java directory and it will automagically get copied over to the web-inf directory in project directory of your .grails folder.
Posted in: Uncategorized
So I found this blog post which describes how to change the deployment context of an app in grails.
Essentially you add app.context = /yourcontext to the application.properties file which is located in the root directory. Pretty easy eh?
Posted in: Uncategorized
So yesterday I had a phone interview with Rally. Overall, I think the interview went good, but one question he asked me was about polymorphism – “What is polymorphism?” to be exact.
We all learn about polymorphism in college along with things like multiple inheritance, weak/strong typing, and object oriented design. But I have always found questions involving these concepts have really funky answers that are sometimes hard to articulate. My first reaction was to say that polymorphism is having a class Foo that can act like class Bar. Well that’s not technically the right answer, but I am not sure its necessarily the wrong answer as well.
Polymorphism is defined in my CS3410 book (Data Structures and Problem Solving using Java – second edition by Mark Weiss) as the following –
A reference type can refence objects of several different types. When methods are applied to the polymorphic type, the operation that is appropriate to the actual referenced object is automatically selected. In Java, this is implemented as part of inheritance. Polymorphism allows us to implement classes that share common logic.
So if Student and Faculty both extend Person and you assign a newly created Student object to a Person reference and then call toString(), it will use the Student’s toString method and not the Person class method (that is unless the Student toString calls super.toString()). The appropriate implementation of the method is called at run-time through dynamic binding.
So that means that a Person class can indeed act like a Student class and vice-versa depending on the methods called.
Oh and another question he asked was what is the difference between a list and a set? This one always screws me up, I get them backwards 9 times out of 10. So here are the answers:
List – Can have duplicates and has a defined order.
Set – Cannot have duplicates and does not have a defined order.
Posted in: Uncategorized
So I have a drop down list of Applications… Well the Applications domain object specifies that it should presort all returns by the appName field. This works great when doing something like user.applications. Yet when I did my normal Application.findAll() the list it returned was not sorted by appName. I instead had to use Application.list().
Posted in: grails
The monthly assignment over on the Fred Miranada forums is “New” well here is my take on new. Oh the retail price of this bad boy is about $300,000.


Posted in: photography
Ok so we purchased a new template from Theme Forest this week for our “ASM” system. So while I was reskinning the login box I started having issues outputting the html dynamically using jquery (the old box as you can see was rather simple). So I decided to iframe the entire modal window of the login box. The reason I ended up not doing this last time was because redirecting once authenticated was a bit of pain for some reason. But alas I have conquered that beast.
So what you end up with is something like this:
This is the page which needs to display a login box
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <!-- To change this template, choose Tools | Templates and open the template in the editor. --> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>FDLE:AppHub</title> <script src="/AppHub/login/script"></script> <script type="text/javascript" src="/AppHub/js/jquery-1.3.2.min.js"></script> <script type="text/javascript" src="/AppHub/js/jquery-ui-1.7.2.custom.min.js"></script> <script> loadIFrameModal('local', window.location.protocol+"//"+window.location.host+"/AppHub/login/show/"); </script> </head> <body> </body> </html> |
The javascript (which is a GSP page)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | function loadIFrameModal(env, targetUrl) { $(window).load(function() { var flag = ${flag}; if(flag == false) { if(env == 'dev' || env == 'development') { $("body").append("<div id=\"modal\"></div>"); $("#modal").append("<iframe src=\"http://162.143.99.200:8080/AppHub/login/?targetUrl="+targetUrl+"\" height=\"500\" width=\"400\" frameborder=\"0\" />"); } if(env == 'local') { $("body").append("<div id=\"modal\"></div>"); $("#modal").append("<iframe src=\"http://66869-irm:8080/AppHub/login/?targetUrl="+targetUrl+"\" height=\"475\" width=\"400\" frameborder=\"0\" />"); } //open dialog $("#modal").dialog({ autoOpen: true, height: 525, width: 475, modal: false, resizable: false, position: 'center', draggable: false, closeOnEscape: false }); //hide the title bar $(".ui-dialog-titlebar").hide(); $("#modal > iframe").attr("style", "overflow:hidden;"); } else { $("body").append("<form id=\"form\" method=\"POST\" action=\""+targetUrl+"\"></form>"); $("#form").append("<input type=\"hidden\" name=\"id\" value=\"${id}\" />"); $("#form").append("<input type=\"hidden\" name=\"ip\" value=\"${request.getRemoteAddr()}\" />"); $("#form").submit(); } }); } |
The iframe content:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | <body> <!-- Start Wrap --> <div id="wrap" class="login"> <div id="content"> <div class="inner"> <noscript> <!-- Show message when javascript is not enabled --> <div class="message error"> <p>Javascript is needed for this template to work properly. <br />Please <a href="http://browsehappy.com/" title="Upgrade to a better browser">upgrade</a> your browser or <a href="http://www.google.com/support/bin/answer.py?answer=23852" title="Enable Javascript in your browser">enable</a> Javascript to navigate the interface properly.</p> </div> </noscript> <!-- Start Content Box #1 --> <div class="title"> <h3>fdle:Connect</h3> <div class="selector" title="content_box"> <a class="tab active" href="tab-login">Login</a> <a class="tab" href="tab-password">Forgotten Password</a> </div> </div> <div class="box"> <div class="txt"> <div id="content_box"> <div class="tab-login"> <!-- Start Message --> <g:eachError bean="${loginCmd}"> <div class="message error"> <p><g:message error="${it}" /></p> </div> </g:eachError> <!-- End Message --> <!-- Start Login Form --> <g:form action="signIn"> <fieldset> <p><label>Username</label> <input type="text" class="txt-input large" name="username" /> </p> <p><label>Password</label> <input type="password" class="txt-input large" name="password" /> </p> <p style="float:left;"><input type="submit" class="button" name="submit" value="Login" /> <input type="reset" class="reset" name="reset" value="Reset" /></p> <input type="hidden" name="targetUrl" value="${targetUrl}" /> <input type="hidden" name="ip" value="${request.getRemoteAddr()}" /> </fieldset> </g:form> <!-- End Login Form --> </div> <div class="tab-password"> <!-- Start Password Form --> <form method="post" action="index.html"> <fieldset> <p><label>Email</label> <input type="text" class="txt-input large" /> <small>Please enter the email address of your account</small></p> <input type="submit" class="button" name="submit" value="Request Password" /> </fieldset> </form> <!-- End Password Form --> </div> </div> </div> </div> <!-- End Content Box #1 --> </div> </div> </div> <!-- End Wrap --> </body> |
And the page that redirects once authenticated:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | <!-- To change this template, choose Tools | Templates and open the template in the editor. --> <%@ page contentType="text/html;charset=UTF-8" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>FDLE:Connect</title> <script src="http://www.google.com/jsapi"></script> <script> // Load jQuery google.load("jquery", "1.3.2"); google.load("jqueryui", "1.7.2"); google.setOnLoadCallback(function() { $(document).ready(function() { self.parent.location = '${targetUrl}'; }); }); </script> </head> <body> <span style="color:#000; font-size:14px; font-family:verdana;">If this page does not redirect please click the following <a href="${targetUrl}" target="_top">link</a>.</span </body> </html> |
Posted in: grails, javascript
So when I set out to rewrite our ASM system, I knew I had to find some selling points to the architecture I was pitching. One of them was the ability to write an SSO system that was easy and efficient and most of all did not require much code for implementing applications (JSSO and the like were out of the question).
So here’s what I came up with (everything is written in Grails)… I first created an AuthController which would handle the authentication and return back a user id for the person if they were a valid user (either in our custom user store or our AD system). This controller had a login action which displayed the login prompt and would return all the necessary error back to the user if something was wrong.
I then wrote another action whose corresponding GSP stored my javascript for creating the needed iframes on the page. This meant that when someone loaded the action I could access all of their cookies (which I needed for SSO) even if their application was on another domain. In the action I would process the cookies and either send them the login page or return the user id back to the browser which would then be processed by the application.
In the end the only code the implementing applications need to have is the follow:
1 2 3 4 5 6 7 8 9 10 11 12 | <script src="http://www.google.com/jsapi"></script> <script src="http://localhost:8080/AppHub/auth/script"></script> <script> // Load jQuery google.load("jquery", "1.3.2"); google.load("jqueryui", "1.7.2"); google.setOnLoadCallback(function() { loadModal('local', window.location.protocol+"//"+window.location.host+"/LoginApplication/login/show/", window.location.protocol+"//"+window.location.host+window.location.pathname); }); </script> |
And here is how I process the script action:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | def script = { def cookie = request.cookies.find { it.name == 'session_id' } if (!cookie) { render(view: "script", contentType: "text/javascript", model: [flag: 'false']) } else { def id = Session.findBySessionIdAndKey(cookie.value, "id") if (id && cookie.value == id.sessionId) { render(view: "script", contentType: "text/javascript", model: [flag: 'true', id: id.value]) } else { cookie.maxAge = 0 response.addCookie(cookie) render(view: "script", contentType: "text/javascript", model: [flag: 'false']) } } } |
And here is the script.gsp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | function loadModal(env, targetUrl, returnUrl) { var flag = ${flag}; $(window).load(function() { if(flag == false) { if(env == 'dev' || env == 'development') { $("head").append("<link rel=\"stylesheet\" href=\"http://162.143.99.200:8080/AppHub/css/ui-darkness/jquery-ui-1.7.2.custom.css\" type=\"text/css\" media=\"screen\" />"); $("head").append("<link rel=\"stylesheet\" href=\"http://162.143.99.200:8080/AppHub/css/login.css\" type=\"text/css\" media=\"screen\" />"); $("head").append("<link rel=\"stylesheet\" href=\"http://162.143.99.200:8080/AppHub/css/form.css\" type=\"text/css\" media=\"screen\" />"); $("body").append("<div id=\"modal\"></div>"); $("#modal").append("<div id=\"box\"></div>"); $("#box").append("<h2 style=\"color:#666666;\">AppHub:<span class=\"light\">Connect</span></h2>"); if(hasError('user.username.invalid')) { $("#box").append("<p class=\"class\" style=\"color:#f00;\"><strong>Error:</strong><g:message code="user.username.invalid" /></p>"); } if(hasError('user.username.blank')) { $("#box").append("<p class=\"class\" style=\"color:#f00;\"><strong>Error:</strong><g:message code="user.username.blank" /></p>"); } if(hasError('user.password.blank')) { $("#box").append("<p class=\"class\" style=\"color:#f00;\"><strong>Error:</strong><g:message code="user.password.blank" /></p>"); } if(hasError('user.password.invalid')) { $("#box").append("<p class=\"class\" style=\"color:#f00;\"><strong>Error:</strong><g:message code="user.password.invalid" /></p>"); } if(hasError('user.adproblem')) { $("#box").append("<p class=\"class\" style=\"color:#f00;\"><strong>Error:</strong><g:message code="user.adproblem" /></p>"); } if(hasError('user.kerberos.6')) { $("#box").append("<p class=\"class\" style=\"color:#f00;\"><strong>Error:</strong><g:message code="user.kerberos.6" /></p>"); } if(hasError('user.kerberos.18')) { $("#box").append("<p class=\"class\" style=\"color:#f00;\"><strong>Error:</strong><g:message code="user.kerberos.18" /></p>"); } if(hasError('user.kerberos.23')) { $("#box").append("<p class=\"class\" style=\"color:#f00;\"><strong>Error:</strong><g:message code="user.kerberos.23" /></p>"); } if(hasError('user.kerberos.24')) { $("#box").append("<p class=\"class\" style=\"color:#f00;\"><strong>Error:</strong><g:message code="user.kerberos.24" /></p>"); } $("#box").append("<form id=\"form\" method=\"POST\" action=\"http://162.143.99.200:8080/AppHub/auth/signIn\"></form>"); $("#form").append("<input type=\"hidden\" name=\"targetUrl\" value=\""+targetUrl+"\" />"); $("#form").append("<input type=\"hidden\" name=\"returnUrl\" value=\""+returnUrl+"\" />"); $("#form").append("<input type=\"hidden\" name=\"ip\" value=\"${request.getRemoteAddr()}\" />"); $("#form").append("<ul></ul>"); $("#form > ul").append("<li><label for=\"username\">Username</label><div><input type=\"text\" name=\"username\" class=\"max text\" /></div></li>"); $("#form > ul").append("<li><label for=\"password\">Password</label><div><input type=\"password\" name=\"password\" class=\"max text\" /></div></li>"); $("#form > ul").append("<li><input type=\"submit\" name=\"submit\" class=\"button\" value=\"Sign In\" /></li>"); $("#form > ul").append("<li><a style=\"color:#0088CC;\" href=\"#\">Forgot Password</a><span style=\"color:#0088CC;\"> | </span><a style=\"color:#0088CC;\" href=\"#\">Register</a><span style=\"color:#0088CC;\"> | </span><a style=\"color:#0088CC;\" href=\"#\">Unlock Account</a></li>"); } if(env == 'local') { $("head").append("<link rel=\"stylesheet\" href=\"http://localhost:8080/AppHub/css/ui-darkness/jquery-ui-1.7.2.custom.css\" type=\"text/css\" media=\"screen\" />"); $("head").append("<link rel=\"stylesheet\" href=\"http://localhost:8080/AppHub/css/login.css\" type=\"text/css\" media=\"screen\" />"); $("head").append("<link rel=\"stylesheet\" href=\"http://localhost:8080/AppHub/css/form.css\" type=\"text/css\" media=\"screen\" />"); $("body").append("<div id=\"modal\"></div>"); $("#modal").append("<div id=\"box\"></div>"); $("#box").append("<h2 style=\"color:#666666;\">AppHub:<span class=\"light\">Connect</span></h2>") if(hasError('user.username.invalid')) { $("#box").append("<p class=\"class\" style=\"color:#f00;\"><strong>Error:</strong><g:message code="user.username.invalid" /></p>"); } if(hasError('user.username.blank')) { $("#box").append("<p class=\"class\" style=\"color:#f00;\"><strong>Error:</strong><g:message code="user.username.blank" /></p>"); } if(hasError('user.password.blank')) { $("#box").append("<p class=\"class\" style=\"color:#f00;\"><strong>Error:</strong><g:message code="user.password.blank" /></p>"); } if(hasError('user.password.invalid')) { $("#box").append("<p class=\"class\" style=\"color:#f00;\"><strong>Error:</strong><g:message code="user.password.invalid" /></p>"); } if(hasError('user.adproblem')) { $("#box").append("<p class=\"class\" style=\"color:#f00;\"><strong>Error:</strong><g:message code="user.adproblem" /></p>"); } if(hasError('user.kerberos.6')) { $("#box").append("<p class=\"class\" style=\"color:#f00;\"><strong>Error:</strong><g:message code="user.kerberos.6" /></p>"); } if(hasError('user.kerberos.18')) { $("#box").append("<p class=\"class\" style=\"color:#f00;\"><strong>Error:</strong><g:message code="user.kerberos.18" /></p>"); } if(hasError('user.kerberos.23')) { $("#box").append("<p class=\"class\" style=\"color:#f00;\"><strong>Error:</strong><g:message code="user.kerberos.23" /></p>"); } if(hasError('user.kerberos.24')) { $("#box").append("<p class=\"class\" style=\"color:#f00;\"><strong>Error:</strong><g:message code="user.kerberos.24" /></p>"); } $("#box").append("<form id=\"form\" method=\"POST\" action=\"http://localhost:8080/AppHub/auth/signIn\"></form>"); $("#form").append("<input type=\"hidden\" name=\"targetUrl\" value=\""+targetUrl+"\" />"); $("#form").append("<input type=\"hidden\" name=\"returnUrl\" value=\""+returnUrl+"\" />"); $("#form").append("<input type=\"hidden\" name=\"ip\" value=\"${request.getRemoteAddr()}\" />"); $("#form").append("<ul></ul>"); $("#form > ul").append("<li><label for=\"username\">Username</label><div><input type=\"text\" name=\"username\" class=\"max text\" /></div></li>"); $("#form > ul").append("<li><label for=\"password\">Password</label><div><input type=\"password\" name=\"password\" class=\"max text\" /></div></li>"); $("#form > ul").append("<li><input type=\"submit\" name=\"submit\" class=\"button\" value=\"Sign In\" /></li>"); $("#form > ul").append("<li><a style=\"color:#0088CC;\" href=\"#\">Forgot Password</a><span style=\"color:#0088CC;\"> | </span><a style=\"color:#0088CC;\" href=\"#\">Register</a><span style=\"color:#0088CC;\"> | </span><a style=\"color:#0088CC;\" href=\"#\">Unlock Account</a></li>"); } //open dialog $("#modal").dialog({ autoOpen: true, height: 450, width: 500, modal: true, resizable: false, position: 'center', draggable: false, closeOnEscape: false }); //hide the title bar $(".ui-dialog-titlebar").hide(); } else { $("body").append("<form id=\"form\" method=\"POST\" action=\""+targetUrl+"\"></form>"); $("#form").append("<input type=\"hidden\" name=\"id\" value=\"${id}\" />"); $("#form").append("<input type=\"hidden\" name=\"ip\" value=\"${request.getRemoteAddr()}\" />"); $("#form").submit(); } }); } function getParameters() { var vars = [], hash; var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&'); for(var i = 0; i < hashes.length; i++) { hash = hashes[i].split('='); vars.push(hash[0]); vars[hash[0]] = hash[1]; } return vars; } function getParameter(name) { return getParameters()[name]; } function getErrors() { if(getParameter('error') != null) { return getParameter('error').split(';'); } else { return null } } function hasError(code) { var errors = getErrors(); if(getErrors() != null) { for(var i = 0; i < getErrors().length; i++) { if(errors[i] == code) { return true; } } } else { return false; } } |
Could it be cleaner? Sure and when I hone in my JQuery skills I will definitely clean it up, but for now it works. =)
Posted in: REST, grails, javascript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | import java.net.HttpURLConnection; class RESTClient { String url String method = "GET" String body //I want the String representation of the object you want to send (either JSON or XML) String data //This is where the response data is stored Node xml //Store the processed response for xml in here Integer status //Where the status code is held, like 200, 201, 404, 400, etc... Map headers = ["Content-Type":"text/xml", "Accept":"text/xml"] Map params HttpURLConnection request def makeRemoteCall() { request = new URL(url).openConnection() //This is set to GET by default request.setRequestMethod(method) //Use the each closure to set all the requestHeader values headers.each { name, value -> request.setRequestProperty(name, value) } //Check to see what method you are performing, if post or put then you need to write out to the stream. if(method in ['POST', 'PUT']) { request.doOutput = true request.outputStream.withWriter("ASCII") { stream -> stream << body //Hopefully your body is well formatted xml or json =D } } request.connect() status = request.getResponseCode() if(status == 200 || status == 201) { if(method in ['GET', 'POST', 'PUT']) { data = request.content.text if(headers["Content-Type"] in ["text/xml", "application/xml"] && data) { xml = new XmlParser().parseText(data) } } } return this } } |
So I have just finished the first class of my rest client:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | import groovy.xml.StreamingMarkupBuilder import java.net.HttpURLConnection; import apphub.util.RESTClient /** * Created by IntelliJ IDEA. * User: Chauncey-JL * Date: Jan 13, 2010 * Time: 11:59:39 AM * To change this template use File | Settings | File Templates. */ class AccessLevel { String appCode String accessTypeCode String accessLevelCode String displayName def static list(appId, accessTypeCode) { def accessLevels = [] def client = new RESTClient(url:"http://localhost:8080/AppHub/accessLevel/${appId}/${accessTypeCode}").makeRemoteCall() if(client.status == HttpURLConnection.HTTP_OK) { client.xml.children().each { list -> def accessLevel = new AccessLevel() list.children().each { child -> accessLevel.setProperty(child.name(), child.text()) } accessLevels.add(accessLevel) } } return accessLevels } def static get(appId, accessTypeCode, accessLevelCode) { def client = new RESTClient(url:"http://localhost:8080/AppHub/accessLevel/${appId}/${accessTypeCode}/${accessLevelCode}").makeRemoteCall() if(client.status == HttpURLConnection.HTTP_OK) { def accessLevel = new AccessLevel() client.xml.children().each { child -> accessLevel.setProperty(child.name(), child.text()) } return accessLevel } } def save() { def client = new RESTClient(url:"http://localhost:8080/AppHub/accessLevel", method:"POST", body:this.toXML().toString()).makeRemoteCall() if(client.status == HttpURLConnection.HTTP_CREATED) { return true } else { return false } } def update() { def client = new RESTClient(url:"http://localhost:8080/AppHub/accessLevel/${this.appCode}/${this.accessTypeCode}/${this.accessLevelCode}", method:"PUT", body:this.toXML().toString()).makeRemoteCall() if(client.status == HttpURLConnection.HTTP_OK) { return true } else { return false } } def delete() { def client = new RESTClient(url:"http://localhost:8080/AppHub/accessLevel/${this.appCode}/${this.accessTypeCode}/${this.accessLevelCode}", method:"DELETE", body:this.toXML().toString()).makeRemoteCall() if(client.status == HttpURLConnection.HTTP_OK) { return true } else { return false } } private toXML() { StreamingMarkupBuilder builder = new StreamingMarkupBuilder(); def accessLevel = { mkp.xmlDeclaration() accessLevel { appCode(this.appCode) accessTypeCode(this.accessTypeCode) accessLevelCode(this.accessLevelCode) displayName(this.displayName) } } builder.bind(accessLevel) } def String toString() { this.toXML() } } |
And the test class:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | package apphub.client //def accessLevel = new AccessLevel(appCode:'LEGALDOC', accessTypeCode:'ACCESS_LVL', accessLevelCode:'TEST', displayName:'TEST') //accessLevel.save() AccessLevel.list('LEGALDOC', 'ACCESS_LVL').each { println "APPCODE:${it.appCode}" } println "AccessLevel.get().displayName:"+AccessLevel.get('LEGALDOC', 'ACCESS_LVL', 'USER').displayName def lvl = new AccessLevel(appCode:'LEGALDOC', accessTypeCode:'ACCESS_LVL', accessLevelCode:'TEST', displayName:'TEST') println "AccessLevel.save():${lvl.save()}" lvl.displayName = 'Updated Display Name' println "AccessLevel.update():${lvl.update()} --- Display Name:${lvl.displayName}" |
Ok here is the rough version I came up with this afternoon. It will definitely get better as I move deeper into my API.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | package apphub.util; import java.net.HttpURLConnection; class RESTClient { String url String method = "GET" String body //I want the String representation of the object you want to send (either JSON or XML) String data //This is where the response data is stored Node xml //Store the processed response for xml in here Integer status //Where the status code is held, like 200, 201, 404, 400, etc... Map headers = ["Content-Type":"application/xml", "Accept":"text/xml"] Map params HttpURLConnection request def makeRemoteCall() { request = new URL(url).openConnection() //This is set to GET by default request.setRequestMethod(method) //Use the each closure to set all the requestHeader values headers.each { name, value -> request.setRequestProperty(name, value) } //Check to see what method you are performing, if post or put then you need to write out to the stream. if(method in ['POST', 'PUT']) { request.doOutput = true request.outputStream.withWriter("ASCII") { stream -> stream << body //Hopefully your body is well formatted xml or json =D } } else { } request.connect() data = request.content.text if(headers["Content-Type"] in ["text/xml", "application/xml"] && data) { xml = new XmlParser().parseText(data) } status = request.getResponseCode() return this } } |
And here is how I am using it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | def static list(appId, accessTypeCode) { def accessLevels = [] def client = new RESTClient(url:"http://localhost:8080/AppHub/accessLevel/${appId}/${accessTypeCode}").makeRemoteCall() if(client.status == HttpURLConnection.HTTP_OK) { client.xml.children().each { list -> def accessLevel = new AccessLevel() list.children().each { child -> accessLevel.setProperty(child.name(), child.text()) } accessLevels.add(accessLevel) } } return accessLevels } def static get(appId, accessTypeCode, accessLevelCode) { def client = new RESTClient(url:"http://localhost:8080/AppHub/accessLevel/${appId}/${accessTypeCode}/${accessLevelCode}").makeRemoteCall() if(client.status == HttpURLConnection.HTTP_OK) { def accessLevel = new AccessLevel() client.xml.children().each { child -> accessLevel.setProperty(child.name(), child.text()) } return accessLevel } } |
Pretty simple =D