Tuesday, September 4, 2018

3 ways to convert String to byte array in Java - Example

I am going to discuss one of the common tasks for programmers, converting a String to a byte array. You need to do that for multiple reasons e.g. for saving content to a file, sending over a network or maybe some other reason. Suppose you have a String "abcd" and you want to convert it into a byte array, how will you do that in a Java program? Remember, String is made of the char array, so it involves character to byte conversion, which is subject to character encoding intricacies. Thankfully, Java provides a convenient getBytes() method to convert String to byte array in Java, but unfortunately, many developers don't use it correctly. Almost 70% of the code I have reviewed uses getBytes() without character encoding, leaving it on the chance that platform's default character encoding will be same as of the source String.

Oracle Java String, Oracle Java Tutorial and Material, Java Certification

The right way to use getBytes() should always be with explicit character encoding, as shown in this article. Java even comes with some standard set of character encoding which is supported out-of-box by StandardCharset class, we will review them as well.

It's also a good practice is to use the pre-defined contestants for specifying character encoding in your code instead of using a free text or String to avoid typos and other silly mistakes.

String to byte array using getBytes()


This is the most common way to convert a String into a byte array, it works most of the time but it's error-prone and can produce an erroneous result if platform's character encoding doesn't match with expected encoding.

Here is an example of converting String to byte[] in Java :

// converts String to bytes using platform's default character encoding,
// in Eclipse it's Cp1252
// in Linux it could be something else
byte[] ascii = "abcdefgh".getBytes();

System.out.println("platform's default character encoding : "
                     + System.getProperty("file.encoding"));
System.out.println("length of byte array in default encoding : "
                     + ascii.length);
System.out.println("contents of byte array in default encoding: "
                     + Arrays.toString(ascii));

Output :
platform's default character encoding : Cp1252
length of byte array in default encoding : 8
contents of byte array in default encoding: [97, 98, 99, 100,
                                               101, 102, 103, 104]

Remark :

1) Platform's default encoding is used for converting a character to bytes if you don't specify any character encoding.

2) You can see platform's default character encoding by using System.getProperty("file.encoding");, this return the default character encoding of the machine your JVM is running.

3) Beware, your code may work in one environment e.g. QA but not work in production because of different default character encoding. That's why you should not rely on default character encoding.

4) length of byte array may not be same as the length of String, it depends upon character encoding. Some character encoding is multi-byte but usually, take 1 byte to encode ASCII characters.

String to byte array using getBytes("encoding)


Here is another way to convert a String to a byte array but this time by specifying the proper encoding to leave any guess or platform default aside.

// convert String to bytes of specified character encoding but
// also throw checked UnsupportedEncodingException, which pollutes the code
try {
byte[] utf16 = "abcdefgh".getBytes("UTF-16");
System.out.println("length of byte array in UTF-16 charater encoding : "
 + utf16.length);
System.out.println("contents of byte array in UTF-16 encoding: "
 + Arrays.toString(utf16));

} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}

Output :
length of byte array in UTF-16 charater encoding : 18
contents of byte array in UTF-16 encoding: [-2, -1, 0, 97,
0, 98, 0, 99, 0, 100, 0, 101, 0, 102, 0, 103, 0, 104]

Remark :

1) It's better than the previous approach but throws a checked exception java.io.UnsupportedEncodingException, if character encoding String has a typo or specifies and character encoding not supported by Java.

2) The returned byte array is on specified character encoding

3) You can see that length of the byte array is not same as a number of characters in String as was the case in the previous example because UTF-16 encoding takes at-least 2 bytes to encode a character.

String to byte array using getBytes(Charset)

This is third but probably the best way to convert to String to byte[] in Java. In this example, I have used java.nio.StandardCharsets to specify character encoding. This class contains some of the widely used character encoding constants e.g. UTF-8, UTF-16 etc.

A good thing about this approach is that it doesn't throw checked java.io.UnsupportedEncodingException, but unfortunately this class is only available from JDK 7 onward so it might not be an option for several Java application running on Java 6 and lower version.

// return bytes in UTF-8 character encoding
// pros - no need to handle UnsupportedEncodingException
// pros - bytes in specified encoding scheme
byte[] utf8 = "abcdefgh".getBytes(StandardCharsets.UTF_8);
System.out.println("length of byte array in UTF-8 : " + utf8.length);
System.out.println("contents of byte array in UTF-8: " + Arrays.toString(utf8));

Output:

length of byte array in UTF-8 : 8
contents of byte array in UTF-8: [97, 98, 99, 100, 101, 102, 103, 104]

Remarks :

1) This is the best way to convert String to a byte array in Java.

2) This doesn't throw java.io.UnsupportedEncodingException exception, which means no boilerplate code for handling this checked exception.

3) Though, you must keep in in mind that StandarhardCasets class is only available from Java 7 onward.

That's all about how to convert a String to byte array in Java. Remember the size of byte array can be more than the length of String because it's not necessary that one byte is used to encode one character, it all depends on character encoding. For example, UTF-8 is a multi-byte character encoding scheme and uses between 1 to 4 bytes per character. In general, characters of the old ASCII range takes 1 bytes but characters from the old ISO-8859 range beyond ASCII takes 2 bytes.

Monday, April 30, 2018

JavaFX WebView Overview

In this blog, we will be looking at how JavaFX can render webpages and the component responsible for it – which is known as WebView

JavaFX is a:

◈ Software platform for creating and delivering desktop applications, as well as rich internet applications (RIAs) that can run across a wide variety of devices.

◈ Set of graphics and media packages that enables developers to design, create, test, debug, and deploy rich client applications that operate consistently across diverse platforms.


JavaFX Key Features:


Oracle JavaFX, Oracle Java Tutorial and Material, Oracle Java Guides, Oracle Java Learning, Oracle Java Certification

WebView: A web component that uses WebKit HTML technology to make it possible to embed web pages within a JavaFX application. JavaScript running in WebView can call Java APIs, and Java APIs can call JavaScript running in WebView. Support for additional HTML5 features, including Web Sockets, Web Workers, and Web Fonts, and printing capabilities have been added in JavaFX.

JavaFX WebView:

  • JavaFX WebView is a mini browser (also called as an embedded browser) that provides a web viewer and full browsing functionality through its API  in JavaFX applications.
  • This browser is based on WebKit, that is a open source web browser engine that supports HTML5, JavaScript, CSS, DOM rendering and SVG graphics.
  • The WebView class is an extension of the Node class.
  • The embedded browser inherits all fields and methods from the Node class, and therefore, it has all its features.
  • It encapsulates a WebEngine object, incorporates HTML content into an application's scene, and provides properties and methods to apply effects and transformations.
  • The getEngine() method called on a WebView object returns a Web Engine associated with it.
  • The classes that constitute the embedded browser reside in the javafx.scene.web package.
  • WebView  enables developers to implement the following features in their Java applications:
    • Render HTML content from local or remote URLs
    • Support history and provide Back and Forward navigation
    • Reload the content
    • Apply effects to the web component
    • Edit the HTML content
    • Execute JavaScript commands
    • Perform upcalls from JavaScript to JavaFX
    • Handle events
  • WebView component supports the following HTML5 features apart from supporting CSS3 and ecmascript6 (ES6):
    • DOM3
    • Canvas
    • Media Playback
    • Form controls (except for <input type="color"> )
    • Editable content
    • History maintenance
    • Support for the <meter>, <progress>, <details> and <summary> tags
    • SVG
    • Web Sockets
    • Web Workers
    • Support for domain names written in national languages
Below diagram depicts architecture of embedded browser and its relation to other JavaFX classes:

Oracle JavaFX, Oracle Java Tutorial and Material, Oracle Java Guides, Oracle Java Learning, Oracle Java Certification

Web Engine:


1. is a non-visual object capable of managing one Web page at a time

2. Provides basic web page functionality through its API.

3. It supports user interaction such as navigating links and submitting HTML forms, although it does not interact with users directly.

4. It loads Web pages, creates their document models, applies styles as necessary, and runs JavaScript on pages.

5. It provides access  to the document model of the current page, and enables two-way communication between a Java application and JavaScript code of the page.

6. It wraps a WebPage object, which provides interaction with the native Webkit core.

Relationship between WebView and WebEngine classes:

Oracle JavaFX, Oracle Java Tutorial and Material, Oracle Java Guides, Oracle Java Learning, Oracle Java Certification

Code Snippet for Loading content in JavaFX WebView:


1. Create WebView, WebEngine objects and load via Remote URL.:


Oracle JavaFX, Oracle Java Tutorial and Material, Oracle Java Guides, Oracle Java Learning, Oracle Java Certification

2. Load Static HTML Content:


Oracle JavaFX, Oracle Java Tutorial and Material, Oracle Java Guides, Oracle Java Learning, Oracle Java Certification

3. Loading HTML content from local file:


Oracle JavaFX, Oracle Java Tutorial and Material, Oracle Java Guides, Oracle Java Learning, Oracle Java Certification

4. To track Load Progress with the help of LoadWorker:


◈ Loading always happens on a background thread. Methods that initiate loading return immediately after scheduling a background job.

◈ To track progress and/or cancel a job, we can use the Worker instance available from the getLoadWorker() method.

◈ The following example changes the stage title when loading completes successfully:

Oracle JavaFX, Oracle Java Tutorial and Material, Oracle Java Guides, Oracle Java Learning, Oracle Java Certification

5. Access to Document Model


◈ The WebEngine objects create and manage a Document Object Model (DOM) for their Web pages. The model can be accessed and modified using Java DOM Core classes.

◈ The getDocument() method provides access to the root of the model. Additionally DOM Event specification is supported to define event handlers in Java code.

◈ The following example attaches a Java event listener to an element of a Web page. Clicking on the element causes the application to exit:

Oracle JavaFX, Oracle Java Tutorial and Material, Oracle Java Guides, Oracle Java Learning, Oracle Java Certification

6. Calling Javascript from JavaFX:


◈ After WebView loads a website, it is possible to execute arbitrary JavaScript code in the context of the current page using the executeScript(java.lang.String) method.

Oracle JavaFX, Oracle Java Tutorial and Material, Oracle Java Guides, Oracle Java Learning, Oracle Java Certification

7. Mapping JavaScript values to Java objects:


◈ JavaScript values are represented using the obvious Java classes: null becomes Java null; a boolean becomes a java.lang.Boolean; and a string becomes a java.lang.String.

◈ If the result is a JavaScript object, it is wrapped as an instance of the JSObject class.

◈ The JSObject class is a proxy that provides access to methods and properties of its underlying JavaScript object.

◈ The most commonly used JSObject methods are getMember (to read a named property), setMember (to set or define a property), and call (to call a function-valued property).

◈ A DOM Node is mapped to an object that both extends JSObject and implements the appropriate DOM interfaces. To get a JSObject object for a Node just do a cast:

JSObject jdoc = (JSObject) webEngine.getDocument();

8. Mapping Java objects to JavaScript values:


◈ The arguments of the JSObject methods setMember and call pass Java objects to the JavaScript environment.

◈ This is roughly the inverse of the JavaScript-to-Java mapping described above: Java String, Number, or Boolean objects are converted to the obvious JavaScript values.

◈ A JSObject object is converted to the original wrapped JavaScript object. Otherwise a JavaRuntimeObject is created.

◈ This is a JavaScript object that acts as a proxy for the Java object, in that accessing properties of the JavaRuntimeObject causes the Java field or method with the same name to be accessed.

Sunday, December 31, 2017

How to Convert a Map to a List in Java Example

Map and List are two common data structures available in Java and in this article we will see how can we convert Map values or Map keys into List in Java. The primary difference between Map (HashMap, ConcurrentHashMap or TreeMap) and List is that Map holds two objects key and value while List just holds one object which itself is a value. Key in hashmap is just an addon to find values, so you can just pick the values from Map and create a List out of it. The map in Java allows duplicate value which is fine with List which also allows duplicates but Map doesn't allow duplicate key.

Friday, July 21, 2017

How to convert String or char to ASCII values in Java

You can convert a character e.g. 'A' to its corresponding ASCII value 65 by just storing it into a numeric data type e.g. byte, int or long as shown below :

int asciiOfA = (int) 'A';

Oracle Java Tutorial and Material, Oracle Java Certification, Oracle Java Learning

Here casting is not necessary, simply assigning a character to integer is enough to store ASCII value of character into an int variable, but casting improves readability. Since ASCII is 7-bit character encoding, you don't even need an integer variable to store ASCII values, byte data type in Java, which is 8 bits wide is enough to store ASCII value of any character.  So you can also do like this :

byte asciiOfB = 'B'; // assign 66 to variable

Since String is nothing but a character array in Java, you can also use this technique to convert a String into ASCII values, as shown below :

StringBuilder sb = new StringBuilder();
char[] letters = str.toCharArray();

for (char ch : letters) {
    sb.append((byte) ch);
}

System.out.println(sb.toString()); // print 749711897

You can also directly convert String to byte array, where bytes will hold ASCII value of  characters as shown below :

byte[] ascii = "Java".getBytes(StandardCharsets.US_ASCII);
String asciiString = Arrays.toString(ascii);
System.out.println(asciiString); // print [74, 97, 118, 97]

You can pass character encoding as "US-ASCII" also, as we have done in our Java example, but using StandardCharsets.US_ASCII is safer because there is no chance of any spelling mistake causing UnsupportedEncodingException.

Java Program to convert String and char to ASCII


Here is our Java program, which combines all the ways we have seen to convert String and character to their respective ASCII values. You can also use the same technique to convert String to other encoding formats e.g. ISO-8859-X (1-7) , UTF-8 , UTF-16BE , UTF-16LE. These are some of the popular encoding formats internally supported by Java.

Here is ASCII table for your quick reference :

Oracle Java Tutorial and Material, Oracle Java Certification, Oracle Java Learning

import java.text.ParseException;
import java.util.Arrays;

/**
 * How to convert a String to ASCII bytes in Java
 * 
 * @author WINDOWS 8
 */

public class StringToASCII {

    public static void main(String args[]) throws ParseException {
        
        // converting character to ASCII value in Java
        char A = 'A';
        int ascii = A;
        System.out.println("ASCII value of 'A' is  : " + ascii);
        
        // you can explicitly cast also
        char a = 'a';
        int value = (int) a;
        System.out.println("ASCII value of 'a' is  : " + value);
        
        
        
        
        // converting String to ASCII value in Java
        try {
            String text = "ABCDEFGHIJKLMNOP";

            // translating text String to 7 bit ASCII encoding
            byte[] bytes = text.getBytes("US-ASCII");
            
            System.out.println("ASCII value of " + text + " is following");
            System.out.println(Arrays.toString(bytes));
            
        } catch (java.io.UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

}

Output
ASCII value of 'A' is  : 65
ASCII value of 'a' is  : 97
ASCII value of ABCDEFGHIJKLMNOP is following
[65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80]

That's all guys, now you know how to convert a Java char or String to their ASCII values. Remember, when you store  a char data type into numeric types e.g. byte, short, int or long, their ASCII values are stored. It's also efficient to use byte data type to store ASCII values because it's a 7-bit character encoding and byte is enough to store ASCII.

Friday, May 26, 2017

Different Types of JDBC Drivers in Java

There are mainly 4 types of JDBC drivers in Java, those are referred as type 1 to type 4 jdbc drivers. I agree its easy to remember them by type rather than with there actual name, Which I have yet to get in memory except plain old JDBC-ODBC bridge driver. By the way here are there full names :

Oracle JDBC, Oracle Java Tutorial and Material, Oracle Java Guides

Type 1 JDBC Driver is called JDBC-ODBC Bridge driver (bridge driver)
Type 2 JDBC Driver is referred as Native-API/partly Java driver (native driver)
Type 3 JDBC Driver is called AllJava/Net-protocol driver (middleware driver)
Type 4 JDBC Driver is called All Java/Native-protocol driver (Pure java driver)

1. JDBC ODBC Bridge Driver or Type 1 JDBC driver

In case of JDBC ODBC bridge driver all JDBC calls doesn't directly goes to database instead they go via ODBC driver. JDBC-ODBC driver translates JDBC calls into ODBC callas and send them to ODBC driver for passing to database. Since type 1 driver act as bridge between JDBC and ODBC and that's why its called JDBC-ODBC bridge driver. This driver is not fast and good for production use mainly because of several layer of translation on back and fourth database traffic but it has  advantage in terms of of availability and can be your last choice.

2. Native-API/partly Java driver or Type 2 JDBC driver


This is also called type 2 driver and its slightly better than type 1 JDBC driver. type 2 JDBC driver convert JDBC calls into database calls by using native API provided by database. This driver is database specific so once you switch from one database to another you need to change type 2 JDBC driver. performance is better than JDBC-ODBC bridge driver since communication layer is reduced. type 2 JDBC driver requires database native library to be available on client but it poses several version and compatibility issue. This was liked by Database vendors though because they can reuse there existing native libraries.

3. All Java/Net-protocol driver or Type 3 JDBC driver


both type 1 and type 2 JDBC drivers were not written in Java so there was need for pure Java JDBC driver to resolve portability issue. type 3 JDBC driver comes with pure java implementation (that's why All Java word ) but it uses 3 tier architecture where you have a Java client and Java Server which talk with Net protocol and Server speaking to database. type 3 JDBC driver never get popular among database vendors as it was costly for them to rewrite there existing native database library which was mainly on C and C++.

4. All Java/Native-protocol driver or Type 4 JDBC driver


type 4 JDBC driver is most popular among all four types of JDBC driver. it has not only implemented in Java but also incorporates all database call in single driver. It was pretty easy to use and deploy as well just include driver's jar in classpath and you are ready. It also removes 3 tier architecture of type 3 JDBC driver which makes it faster than type 3.  Major development happens on type 4 JDBC driver when database upgrade themselves, though some of them still upgrade native database library or type 2 driver.

That's all on quick overview of different types of JDBC drivers in Java. JDBC drivers has evolved from JDBC ODBC bridge driver to type 4 JDBC driver, which is clean and portable. There has been some buzz around JDBC driver 5 on Java community which may include some advanced functionality.