Display byte array in gsp - grails

I want to loop through this class and display in a table. what is the easiest way to display the image?
class Crop {
static hasMany = [diseases: Disease]
int id
String commonName
String scientificName
byte[] image
}
static mapping = {
table: 'Crops'
commonName length : 100
scientificName length: 100
image sqlType: "longblob"
}

You can if you don't mind the lack of browser compatablity use data: uri encoding:
<img src="data:image/png;base64,${crop.image.encodeBase64()}"/>
see the Wikipedia page on Data URI encoding scheme
#Xeon suggest the more conventional approach, ie create a controller that returns an image response with the correct mime type and the byte array as the body.

You could do the same thing as in this answer.
Or you can create controller which provide image data stream from your entity. On GSP you could write:
<img src="${request.contextPath}/imageController/actionName?id=${entity.id}" ...
But this is unusual - storing images in entities as byte[]. You should consider changing it to String which would indicate a path/filename of the image.

Related

URL Mapping - Replacing characters in a parameter pulled from a database

I am currently trying to figure out, how to modify the parameter being integrated into the URL Mapping I am using.
static mappings =
{
"/$controller/$action?/$id?/(.$format)?"
{
constraints {
// apply constraints here
}
}
name test1: "/.../$title/..."{
controller = "study"
action = "st_show"
}
name test2: "/.../$title/..."{
controller = "search"
action = "se_show"
}
The parameter $title is pretty much a dataset, which is pulled from a database and which will get transmitted in the following format [ this is a title ]. So there are square brackets in front and behind the string and words are seperated through blanks.
If I am creating a link through g:link now with the params nested in, it gets put into the url as it is pulled from the database. What I am attempting is to create SEO-URLs, which will present a certain title of a publication devided by hyphens instead of url-encoded "%20".
Until now, I was able to generate dynamic urls looking like this:
http://localhost:8080/projectname/show/%5BAllgemeine%20Bevölkerungs[...]/782/...PARAMS...
Furthermore I already implemented it through JQuery, though it should be static and users should be able to copy the link to open up the page themselves - that wouldn't be possible when changing the url client-side while loading up the page.
Is there a way to define a function with something like replaceAll.(' ', '-'), which can be invoked onto the parameter in the mapping to replace blanks with hyphens and f.e. square brackets with an empty character?
That's pretty much, what I wasn't able to come by through the documentation.
Thank you already in advance for your help!
I managed to solve my problem by creating a service with a function containing a regex and executing this function onto the parameter title in my g:link, which I firstly converted to a string, which gets passed to the function.
<g:link controller="study" action="st_show" params="[data: data, ... title: ConversionService.convert(fieldValue(bean: path).toString(), ... data: data)]"></g:link>
And the function in the ConversionService
public static String convert(String title){
title = title.replaceAll("\\s", "-").replaceAll("[^0-9a-zA-Z\\-]", "");
return title;
}

Anyway can I extract filter segment from EntityQuery?

I am building EntityQuery.
Now I would like to get filter segment out of it? I know toString() will give me human readable string, but I want actual filter string that will be sent to fetch data along with URL.
The following should do it:
var queryString: string = this._manager.metadataStore.toQueryString(query);
manager being your EntityManager and query being the EntityQuery.
Result
SomeEntity?$filter=FirstFilter%2Fany(x1%3A%20x1%2FLicenseTypeId%20ne%2016730)&$expand=FirstFilter%2CFirstFilter%2FPartners%2CAddresses&$inlinecount=allpages
and here is an alternative that I don't quite like as much:
var anotherway = query._toUri(manager.metadataStore);

Unable to decode Base-64 URLs

I have an application that builds an HTML email. Included in the content is an encoded URL parameter that might, for example, contain a promotional code or product reference. The email is generated by a Windows service (essentially a console application) and the link, when clicked is handled by an MVC web site. Here is the code for creating the email link:
string CreateLink(string domain, string code) {
// code == "xyz123"
string encrypted = DES3Crypto.Encrypt(code); // H3uKbdyzrUo=
string urlParam = encrypted.EncodeBase64(); // SDN1S2JkeXpyVW890
return domain + "/" + urlParam;
}
The action method on the MVC controller is constructed as follows:
public ActionResult Index(string id) {
string decoded = id.DecodeBase64();
string decrypted = DES3Crypto.Decrypt(decoded);
...
}
In all our testing, this mechanism has worked as expected, however, now we have gone live we are seeing around a 4% error rate where the conversion from base-64 fails with the following exception:
The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or a non-white space character among the padding characters.
The id parameter from the url 'looks' OK. The problem appears to be with the EncodeBase64/DecodeBase64 methods that are failing as DecodeBase64 method returns a 'garbled' string such as "�nl����□��7y�b�8�sJ���=" on the failed links.
Furthermore, most of the errors are from IE6 user agents leading me to think this is a character encoding problem but I don't see why.
For reference, here is the code for my base-64 URL encoding:
public static string EncodeBase64(this string source)
{
byte[] bytes = Encoding.UTF8.GetBytes(source);
string encodedString = HttpServerUtility.UrlTokenEncode(bytes);
return encodedString;
}
public static string DecodeBase64(this string encodedString)
{
byte[] bytes = HttpServerUtility.UrlTokenDecode(encodedString);
string decodedString = Encoding.UTF8.GetString(bytes);
return decodedString;
}
Any advice would be much appreciated.
To recap, I was creating a URL that used a base-64 encoded parameter which was itself a Triple DES encrypted string. So the URL looked like http://[Domain_Name]/SDN1S2JkeXpyVW890 The link referenced a controller action on an MVC web site.
The URL was then inserted into an HTML formatted email. Looking at the error log, we saw that around 5% of the public users that responded to the link were throwing an "invalid base-64 string error". Most, but not all, of these errors were related to the IE6 user agent.
After trying many possible solutions based around character and URL encoding, it was discovered that somewhere in the client's process the url was being converted to lower-case - this, of course, broke the base-64 encoding (as it is uses both upper and lower case encoding characters).
Whether the case corruption was caused by the client's browser, email client or perhaps local anti-virus software, I have not been able to determine.
The Solution
Do not use any of the standard base-64 encoding methods, instead use a base-32 or zBase-32 encoding instead - both of which are case-insensitive.
See the following links for more details
Base-32 - Wikipedia
MyTenPennies Base-32 .NET Implementation
The moral of the story is, Base-64 URL encoding can be unreliable in some public environments. Base-32, whilst slightly more verbose, is a better choice.
Hope this helps.
It looks like you were really close. You had an extra zero coming back from your encyrpted.EncodeBase64() function.
Try this:
string data = "H3uKbdyzrUo=";
string b64str = Convert.ToBase64String(UTF8Encoding.UTF8.GetBytes(data));
string clearText = UTF8Encoding.UTF8.GetString(Convert.FromBase64String(b64str));
This is an interesting issue. My guess is that IE 6 is eating some of the characters.
For example, the length of the string that you included "ywhar0xznxpjdnfnddc0yxzbk2jnqt090" is not a multiple of four (which is a requirement for FromBase64 to work http://msdn.microsoft.com/en-us/library/system.convert.frombase64string.aspx)
But if you were to pad that string until it's length is a multiple of four ("ywhar0xznxpjdnfnddc0yxzbk2jnqt090" + "a12") then that works.
The MSDN documentation says that one ("=") or two ("==") equal characters are used for padding to/fromBase64 methods and I suspect IE 6 is truncating that from the string that you send.
This is total speculation but I hope it helps.

Alter GORM database column

I have a ImageController function that takes input data from a form.gsp file and adds it to a Profile class. The Profile class has a byte[] photo field, and using a MultiPart HTTP Request transferTo() method, the file is replicated in the database if size is < 200KB.
My issue is each time I try to upload, I get a SQLException stating that the input value is too large for a PHOTO_BINARY(255) column.
First, why is a byte[] array mapped to a column limiter? To move around this, would byte[] photo= new byte[200*1024] work?
Second, what is necessary to alter said column to a medium blob of 16777215 characters?
Use the maxSize constraint, e.g.
static constraints = {
photo maxSize: 16777215
}
Try setting the type of the column to blob in the mappings.
static mapping = {
photo type: "binary" // or "blob"
}
Hope that helps

Sending javaMail attachement of any type from database

I'm have domain class with property that represents files uploaded on my GSP. I've defined that file as byte array (byte [] file). When some specific action happens I'm sending mail with attachments from. This is part of my SendMail service:
int i = 1;
[requestInstance.picture1, requestInstance.picture2, requestInstance.picture3].each(){
if(it.length != 0){
DataSource image = new ByteArrayDataSource(it, "image/jpeg");
helper.addAttachment("image" + i + ".jpg", image);
i++;
}
}
This works fine with image files. But now I want to be able to work with all file types and I'm wondering how to implement this. Also, I want to save real file name in database. All help is welcomed.
You can see where the file name and MIME type are specified in your code. It should be straightforward to save and restore that information from your database along with the attachment data.
If you're trying to figure out from the byte array of data what the MIME type is and what a good filename would be, that's a harder problem. Try this.

Resources