Extending JBoss Data Virt ws translator to handle JSONP - java

What is the best way to extend org.teiid.translator.ws to connect to a webservice that returns JSONP (whose mediatype is usually application/javascript)? The existing ws translator can read only JSON or XML. In general, was the translator designed to facilitate the injection of transformation logic to handle any webpage structure/format (e.g., JSONP, plaintext, html, etc.)?
For JSONP, I am leaning towards creating my own implementation of org.teiid.core.types.InputStreamFactory, say com.acme.JsonpToJsonInputStreamFactory, in which I define my own JsonpToJsonReaderInputStream (extending ReaderInputStream) that skips the leading
randomFunctionName(
and trailing
)
of a JSONP payload, and modify ClobInputStreamFactory.getInputStream to return that, instead of ReaderInputStream. Then I replace both instances of
ds = new InputStreamFactory.ClobInputStreamFactory(...);
in translator-ws-jsonp.BinaryWSProcedureExecution (where translator-ws-jsonp is based on translator-ws) with
ds = new JsonpToJsonInputStreamFactory.ClobInputStreamFactory(...);

WS translator returns the results in Blob form, how you unpack the results is up to you. IMO, you do not really need to build another translator.
Currently, the typical use case in JDV is to read blob and use JSONTOXML function to convert into XML such that the results can be then parsed into a tabular structure using constructs like XMLTABLE. So, you can write a UDF like JSONPTOJSON which does above like you mention then use JSONTOXML(JSONPTOJSON(blob)) as input to XMLTABLE.

Related

Apache Camel: How to look inside body to determine file format

We receive .csv files (both via ftp and email) each of which can be one of a few different formats (that can be determined by looking at the top line of the file). I am fairly new to Apache Camel but want to implement a content based router and unmarshal each to the relevant class.
My current solution is to break down the files to a lists of strings, manually use the first line to determine the type of file, and then use the rest of the strings to create relevant entity instances.
Are there a cleaner and better way?
You could use a POJO to implement the type check in whatever way works best for your files.
public String checkFileType(#Body File file) {
return determineFileType(file);
}
private String determineFileType(File file) {...}
Like this you can keep your route clean by separating the filetype check and any other part of processing. Because the filetype check is just metadata enrichment.
For example you could just set the return value as a message header by calling the bean)
.setHeader("fileType", method(fileTypeChecker))
Then you can route the files according to type easily by using the message header.
.choice()
.when(header("fileType").isEqualTo("foo"))
...

How to post a big string/json using AJAX on Play Framework 1.4.x

I have a JSON that looks more or less like this:
{"id":"id","date":"date","csvdata":"csvdata".....}
where csvdata property is a big amount of data in JSON format too.
I was trying to POST this JSON using AJAX in Play! Framework 1.4.x so I sended just like that, but when I receive the data in the server side, the csvdata looks like [object Object] and stores it in my db.
My first thought to solve this was to send the csvdata json in string format to store it like a longtext, but when I try to do this, my request fails with the following error:
413 (Request Entity Too Large)
And Play's console show me this message:
Number of request parameters 3623 is higher than maximum of 1000, aborting. Can be configured using 'http.maxParams'
I also tried to add http.maxParams=5000 in application.conf but the only result is that Play's console says nothing and in my database this field is stored as null.
Can anyone help me, or maybe suggest another solution to my problem?
Thanks you so much in advance.
Is it possible that you sent "csvdata" as an array, not a string? Each element in the array would be a separate parameter. I have sent 100KB strings using AJAX and not run into the http.maxParams limit. You can check the contents of the request body using your browser's developer tools.
If your csvdata originates as a file on the client's machine, then the easiest way to send it is as a File. Your controller action would look like:
public static void upload(String id, Date date, File csv) {
...
}
When Play! binds a parameter to the File type, it writes the contents of the parameter to a temporary file which you can read in. (This avoids running out of memory if a large file is uploaded.) The File parameter type was designed for a normal form submit, but I have used it in AJAX when the browser supported some HTML5 features (File API and Form Data).

Jackson JSON Handling of Unicode symbols

I'm calling a webservice that returns text including the ascii symbols representing the ® symbol. For example:
ACME Corp® Services
I use spring to return this textual data directly as a JSON object, and by the time it gets into the browser the json data remains correct:
"service": "ACME Corp® Services"
But upon being rendered via a Handlebars template and written into the page I get:
ACME Corp® Services
Do I need to sanitize the JSON data before using it? If so, what are the best practices for doing that? Otherwise, perhaps there is a change I should make on the back-end but I am not sure what that would be.
You do not need to sanitize content, but you must make sure it uses valid encoding allowed by JSON specification: typically UTF-8 (alternatives being UTF-16 and UTF-32).
If content is not encoded as UTF-8 but something else (like ISO-8859-1 aka "Latin-1"), you will need to construct Reader to decode it properly:
Reader r = new InputStreamReader(in, StandardCharset.ISO_8859_1);
MyPOJO pojo = mapper.readValue(r, MyPOJO.class);
Problem you seem to be having is that encoding used is incorrect.

how to pass pameters with brackets to restemplate

I am connecting to a third party tool that uses brackets inside their url parameters. I'm proxying someone else parameters, so I'm not building these parameters up and don't want to have to parse them exactly.
I've tried a basic encoding of parameters, this fails due to the third party application not knowing how to parse the encoding, it tries to read the encoded values directly as far as I can tell.
I realize this is not exactly how resttemplate is designed to work, but everywhere else in our code uses restTemplate and I don't want to bring in a new service simply for a basic proxy.
Is there any way to make resttemplate allow the brackets through without trying to do substitution on them?
You can use escape URL codes for special characters in the URL. e.g. If your URL is http://domainURL/{url-part}/rest-of-the-url then you could refer to it as http://domainURL/%7Burl-part%7D/rest-of-the-url.
Below is the code snippet for the reference:
LoginDetails loginDetails = restTemplate.getForObject(restServiceURL +
"%7Btest-paranthesis%7D/" + userUUID, LoginDetails.class);
For the above code the URL is http://localhost:8087/userLogin{test-paranthesis}/842063819010

How to access and parse XML file using Java and JavaScript

New to the development scene, please ignore my ignorance if I happen to not make any sense......
I'm trying to access a xml file located in my EJB directory which has to stay there, I need to parse it into a javascript accessible object preferably JSON, to dynamically manipulate it using Javascript / Angular....
using JBOSS, and the file's location is something like
/FOO-ejb/src/main/resources/Config.xml, obviously not accessible through the web since it does not reside under a webserver root directory,
Java is the back-end and I can't seem to find any other ways to access this file to serve it to the front-end,
I'm heading towards the direction of using a service within the EJB to access the file, parse it, then use a REST service to serve the object to the front-end....or write a JSP to read in the file, parse it etc....
are there any other better solutions for this?
Thank you everyone for your time!
I think what you want to do is not achievable since it would mean you'd use Javascript to access the file system which is not possible though HTML5 offers some File API that could work but not to access any file in the file system.
So I'd say that the direction you're heading is the most appropriate and maybe easier because even if you find a way to do it in JavaScript it would be a browser-dependant or some weird workaround that could be broken in future browser's version.
I used Apache Abdera in a Servlet in the past to parse an XML RSS feed and convert it to JSON. Abdera is good at that and worked perfect for me. After getting the JSON object I just had to send it to the response and on the client side I used an AJAX call to the servlet to get the JSON object.
The code was something like this:
try {
PrintWriter result = response.getWriter();
// Creates Abdera object and client to process the request.
Abdera abderaObj = new Abdera();
AbderaClient client = new AbderaClient(abderaObj);
AbderaClient.registerTrustManager(); // For SSL connections.
// Sent the HTTP request of the ATOM Feed through AbderaClient.
ClientResponse resp = client.get( "http://url/to/your/feed" );
// if the response was OK...
if (resp.getType() == ResponseType.SUCCESS) {
// We get the document as a Feed
Document<Feed> doc = resp.getDocument();
// Creates a JSON writer to convert the ATOM Feed
Writer json = abderaObj.getWriterFactory().getWriter("json");
// Converts the (XML) ATOM Feed into JSON object
doc.writeTo(json, result);
}
} catch (Exception ex) {
ex.printStackTrace(System.out);
}

Categories

Resources