2015-03-29
2015-03-12
HTML Barcode Scanner
Have you ever tried to type in a long number on your cell phone or simply enter the number of your membership card into a web application?
This might be a time consuming and error prone task which can be avoided by using barcodes.
This is nothing new. Many solutions exist for reading barcodes with a regular camera, like zxing, but they require a native platform such as Android or iOS.
Building your own application in two different platforms its not the easiest thing to do because it requires a lot of effort to develop and maintain in parallel. Of course there are cross platform mobile SDKs that give you the flexibility - and some of them are quite exciting like Phonegap/Cordova.
The problem is that you will need to learn and invest on a new API which might lead to unfortunate results.
If let's say you have build and invest a lot of know-how and source code in a technology that will not evolve, then your company will be exposed to a big risk.
If we had to gather up all the requirements needed in order to build an application that uses the device camera to scan barcodes, we would probably come up with the following aspects:
- It must be able to use the mobile's/tablet's camera to scan barcodes quickly enough.
- It must be developed in one platform (at least the 95% of it) in order to avoid duplicate work and maintenance.
- It must be developed with a widely approved technology that minimizes the possibility to be discontinued or having everlasting bugs.
After thoroughly examining the related technologies and the requirements that I had, I concluded on 2 different solutions and each of them had it's own strengths and weaknesses.
Solution A. Pure HTML5.
This is a very promising solution since it is all implemented in HTML. The HTML5 specification gives to the developer a very powerful toolset that can even gain access to the device camera. Hopefully there are people that have took advantage of it and have already implemented a javascript library that actually does the work.The best implementation I have come across so far is made by Christoph Oberhofer and it is named quaggaJS. The specific library although it feels a bit immature works quite impressive on specific devices and browsers. Those that are interested may have a look on http://serratus.github.io/quaggaJS/ which is the original web site. You can also read a nice article in Mozilla about it here
https://hacks.mozilla.org/2014/12/quaggajs-building-a-barcode-scanner-for-the-web/ .
After testing it for a while on android I realized that it still has some issues important enough to be a barrier for production environment.
Some of them are:
- It fails to use camera's autofocus on some browsers. On Android I managed to make it work in Firefox but I had no luck with chrome.
- It's a bit slow on scan. The main requirement of the project is to make it easier to scan than typing. If it takes more time to scan the people will prefer to type.
Solution B. HTML & Native app hybrid.
This solution is a bit hard to grasp the first time you hear about but it makes sense after a while. The basic idea is to write the whole application business logic in pure HTML and leave only the scanning part for the native app. Then in order to activate the scan ability of you phone you can click a link of a URL. The specific url is hooked by a native android/ios application where it's only scope is to scan and return the value to the caller.If you don't know how to open a native app from browser in android you can read here whereas those that want to do in ios should read here.
The tricky part here is returning the scanned value back to browser since there is an obvious isolation between them. Unfortunately the cookies cannot help you since the native application's cookies cannot be accessed by the caller browser. So what is left?
The solution that I though was to have browser open the app and at the same time passing a unique token code. Then, after the native app scans the barcode it will make an http post to a web service passing as parameter the token and the value scanned. After that, the mobile app will close automatically and return focus to the caller browser. At the same time the browser should poll the same web service and actual ask it if there is available any value with the specific token.
Here is a diagram describing the process flow.
With this technique, when the value arrives from the mobile app to the web service, the web application will learn about it and display on GUI.
You might think that this is too complicated but we have actually managed to implement a full operational proof of concept with a colleague of mine in a few hours.
Here is a commercial app that more or less does the same.
2015-03-10
Enable CORS v2 Spring Boot
Using REST web services directly from a web page using javascript/jquery/angularjs is one of the hot issues these days. My guess is that many people (like me) have bugged a bit, trying to find out how to make it work using Spring Boot Rest Web Services.
The obstacle that stands between you and the solution has a name and this is CORS.
On my previous post here, I have some short explanation of what it is and how to overcome it in Java EE environment.
On Spring Boot we will need to do almost the same thing except from the fact that instead of changing a web.xml, we will add a configuration class that does more or less the same thing.
How to start then? First follow this guide in order to create a REST web service with CORS enabled. Yeah that's right. Spring.io will give you a great step by step guide how to do it. The problem is though that if it happens to also want to have some basic security there, then the CORS will break again. So, after completing the previous guide open you pom.xml and add the following dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
This will add some basic http authentication with a user named "user" and a random password that will be created each time you start your app (something like: Using default security password: 8f608422-3faf-4f94-b60a-67ebd966af10).
Now, the trick is to add the following class:
This will do 2 things.
1) Add a user admin will password 1111 on group USER.
2) Enable OPTIONS request to be called without basic http authentication.
That's it. you are done!
1) Add a user admin will password 1111 on group USER.
2) Enable OPTIONS request to be called without basic http authentication.
That's it. you are done!
2015-03-08
Enable CORS on JavaEE Web Application
Let's say that you have created a REST API in your Java EE WEB Application and you want to use it in HTML pages through AngularJS, jQuery or even plain JS. If you were newb (like I was), you would expect that this is going to work out of the box (as is) since your API has already been used in many cross platform clients without any problem.
Unfortunately though, for Murphy's sake, this is not the case. Due to Same-origin policy http requests that are made in browsers must be done with a very specific way in order to work when the caller (web site) is on different domain than the web service (REST API).
In order to make it work, the caller must perform CORS HTTP request to the WEB service and the web service subsequently must be modified in order to support CORS requests.
When I first came across to that problem I thought that this would be a-half-an-hour-problem but it wasn't. I had to spend a full day on this (thankfully on weekend) until the problem was completely "solved and working" on every modern browser.
For your web services, to support CORS requests you must deal with 2 problems.
1) CORS HEADERS
The first problem is about adding some additional HTTP headers (CORS) in your HTTP responses. This is relatively easy to find since googling about CORS almost everyone will tell about this. The new CORS headers will "tell" the caller if you support CORS requests and some other things like from which origin or which headers you accept as valid.For example the header with value "Access-Control-Allow-Origin" expects the valid caller domain names. If the caller site is on domain mydomain.com, then the value of that header should be "http://mydomain.com". Alternatively in order to indicate that callers from any domain can access your resource you may just use the value "*".
If your application requires authentication (which was my case), the header "Access-Control-Allow-Headers" should also include the value "Authorization".
2) Preflighted requests
The second one is about Preflighted requests. This was very tricky and hard to find since I only saw that happen on Firefox and Chrome - which in my opinion are the most important browsers out there. These two browsers first send an HTTP request by the OPTIONS method to the resource on the other domain, in order to determine whether the actual request is safe to send. Cross-site requests are preflighted like this since they may have implications to user data. In particular, a request is preflighted if:- It uses methods other than GET, HEAD or POST. Also, if POST is used to send request data with a Content-Type other than application/x-www-form-urlencoded, multipart/form-data, or text/plain, e.g. if the POST request sends an XML payload to the server using application/xml or text/xml, then the request is preflighted.
- It sets custom headers in the request.
SOLUTION
In order to overcome both of the problems you must change your web.xml file and also create a custom class that implements javax.servlet.Filter interface.This is what I had to do in order to overcome Problem 1:
As you can see I created a Filter Class that accepts from web.xml one parameter which is the permitted origin and I used * as a value. The specific filter will intercept all of your application responses and add the custom CORS headers.
To overcome Problem 2 you will also need to modify your web.xml and in your security-constraint tag under web-resource-collection add all the HTTP method except OPTIONS. This will remove your current security from OPTIONS requests and actually make preflight requests feasible.
Here is a sample of what I did in our API:
As you can seeI have exluded OPTIONS request from authentication filter. If you don't do that your requests will always get a 401 error although the security on client is set correctly.
Here is the JavaScript code that I used to call one om Web services:
2015-03-01
Openshift! Create free account and deploy your Java app in less than 5 minutes
On a previous blog entry here, I analyzed the steps to create a basic Java RESTful app in less than 5 minutes. Most probably after creating a RESTful app you will need to put it on cloud in order to be accessible for clients to use. In case that your app is not going to have too much load it is ok to use one of the free PaaS services that exists out there.
There are quite a few of them helping developers to bootstrap their projects.
Openshift (https://www.openshift.com/), Google Cloud Platform (https://cloud.google.com/appengine/docs) and Cloud Foundry are some of them.
The scope of this tutorial is to analyze the steps creating account and deploy your Java project in Openshift.
To begin with it, you should navigate to https://www.openshift.com/ and click on Signup for free. After filling in your info you will receive an email to validate your mail account. Click on the link to validate login to Openshift.
The first thing it will ask you to do is to add an application and this is done in 3 steps.
Step1. Choose a type of application.
Select Do it Yourself.
Step2. Configure the application.
On field "Public URL" you will need to provide the application name and a domain name. The app name and the domain name will be on the final URL of your app so if you give"myapp" as app name and "mydomain" as domain name then you app's url will be http://myapp-mydomain.rhcloud.com/ .
On field "Source Code" you should provide your Github's URL of your project see here for more info. Hit create application.
Step3. Next Steps.
Click on "Continue to the application overview page."
Now that your application is created you will need to create an RSA key to connect with SSH. Click on settings and add your RSA key. If you don't have any you can read this guide that will help you create one.
Next, click on Applications and select your app. Click on "Want to log in to your application?".
This will expand some text that have a code to connect with SHH. Copy the code and use it to connect (in case that you have Windows you can use putty).
Assuming that you have managed so far to login you should run the following command to navigate to you data folder:
cd $OPENSHIFT_DATA_DIR
Then run the following command:
echo -e "<settings>\n <localRepository>$OPENSHIFT_DATA_DIR</localRepository>\n</settings>\n" > settings.xml
This commands will setup maven local repository on a folder that is actually writable.
Then run the following to change folder to your repository:
cd $OPENSHIFT_REPO_DIR
and to build your project:
mvn install -s $OPENSHIFT_DATA_DIR/settings.xml
Finally you run the following to actually run the project:
java -jar target/*.jar --server.port=${OPENSHIFT_DIY_PORT} --server.address=${OPENSHIFT_DIY_IP}
That's it you are done. You can now navigate to http://myapp-mydomain.rhcloud.com/ and see the results.
Subscribe to:
Comments (Atom)
Popular Posts
-
Lately I wanted to use the java jira client (jira-rest-java-client-core) to create custom reports for my w...
-
Let's say that you have created a REST API in your Java EE WEB Application and you want to use it in HTML pages through AngularJS,...
-
More than a decade after its introduction, REST has become one of the most important technologies for Web applications. Its...
-
Many people coming from Java ecosystem to Node.js (like I did) are facing problems to adjust with the new platform philosophy since th...
-
PKIX path building failed: SunCertPathBuilderException: unable to find valid certification path to requested target....
-
It's been almost two months since I wrote anything in here and before moving forward in topics I will try to add something more w...
-
Here is a very nice tutorial in spring.io explaining how to create Hypermedia REST Web Services (HATEOAS) in Java. For those ...
-
On a previous blog entry here , I analyzed the steps to create a basic Java RESTful app in less than 5 minutes. Most probably after ...
-
The Watch Service was introduced in Java 7 as a “thread-safe” service responsible for watching objects for changes. The most popular us...
-
How many times have you need to import raw data in your database? In the company that I work ( Cloudbiz ), this used to be ...




