Quantcast
Channel: Baeldung
Viewing all 3450 articles
Browse latest View live

Java Scanner

$
0
0

1. Overview

In this tutorial, we’ll illustrate how to use the Java Scanner to read input and find and skip patterns with different delimiters.

2. Scan a File

First – let’s see how to read a file using Scanner. In the following example – we read a file contains “Hello world” into tokens using Scanner:

@Test
public void whenReadFileWithScanner_thenCorrect() throws IOException{
    Scanner scanner = new Scanner(new File("test.txt"));

    assertTrue(scanner.hasNext());
    assertEquals("Hello", scanner.next());
    assertEquals("world", scanner.next());

    scanner.close();
}

Note: The Scanner method next() returns the next String token.

3. Convert InputStream to String

Next – let’s see how to convert an InputStream into a String using Scanner:

@Test
public void whenConvertInputStreamToString_thenConverted()  throws IOException {
    String expectedValue = "Hello world";
    FileInputStream inputStream = new FileInputStream("test.txt");
    Scanner scanner = new Scanner(inputStream);
    scanner.useDelimiter("\\A");

    String result = scanner.next();
    assertEquals(expectedValue, result);

    scanner.close();
}

Note: In the previous example we tricked the Scanner to tokenize the entire stream from the beginning to the next regex “\A” (which matches the beginning of input).

4. Scanner vs. BufferedReader

Now – let’s discuss the difference between Scanner and BufferedReader – we generally use:

  • BufferedReader when we want to read the input into lines
  • Scanner to read the input into tokens

In the following example – we’re reading a file into lines using BufferedReader:

@Test
public void whenReadUsingBufferedReader_thenCorrect()  throws IOException {
    String firstLine = "Hello world";
    String secondLine = "Hi, John";
    BufferedReader reader = new BufferedReader(new FileReader("test.txt"));

    String result = reader.readLine();
    assertEquals(firstLine, result);

    result = reader.readLine();
    assertEquals(secondLine, result);

    reader.close();
}

Now, let’s use Scanner to read the same file into tokens:

@Test
public void whenReadUsingScanner_thenCorrect() throws IOException {
    String firstLine = "Hello world";
    FileInputStream inputStream = new FileInputStream("test.txt");
    Scanner scanner = new Scanner(inputStream);

    String result = scanner.nextLine();
    assertEquals(firstLine, result);

    scanner.useDelimiter(", ");
    assertEquals("Hi", scanner.next());
    assertEquals("John", scanner.next());

    scanner.close();
}

Note: We can also use the Scanner nextLine() API to read the entire line.

5. Scan Input from Console

Next – let’s see how to read input from Console using Scanner:

@Test
public void whenReadingInputFromConsole_thenCorrect() {
    String input = "Hello";
    InputStream stdin = System.in;
    System.setIn(new ByteArrayInputStream(input.getBytes()));

    Scanner scanner = new Scanner(System.in);

    String result = scanner.next();
    assertEquals(input, result);

    System.setIn(stdin);
    scanner.close();
}

Note that we used System.setIn(…) to simulate some input coming from the Console.

6. Validate Input

Now – let’s see how to validate input using a Scanner. In the following example – we use the Scanner method hasNextInt() to check if the input is an integer value:

@Test
public void whenValidateInputUsingScanner_thenValidated() throws IOException {
    String input = "2000";
    InputStream stdin = System.in;
    System.setIn(new ByteArrayInputStream(input.getBytes()));

    Scanner scanner = new Scanner(System.in);

    boolean isIntInput = scanner.hasNextInt();
    assertTrue(isIntInput);

    System.setIn(stdin);
    scanner.close();
}

7. Scan a String

Next – let’s see how to scan a String using Scanner:

@Test
public void whenScanString_thenCorrect() throws IOException {
    String input = "Hello 1 F 3.5";
    Scanner scanner = new Scanner(input);

    assertEquals("Hello", scanner.next());
    assertEquals(1, scanner.nextInt());
    assertEquals(15, scanner.nextInt(16));
    assertEquals(3.5, scanner.nextDouble(), 0.00000001);

    scanner.close();
}

Note: The method nextInt(16) reads the next token as a hexadecimal integer value.

8. Find Pattern

Now – let’s see how to find a Pattern using Scanner.

In the following example – we use findInLine() to search for a token that matches the given Pattern in the entire input:

@Test
public void whenFindPatternUsingScanner_thenFound() throws IOException {
    String expectedValue = "world";
    FileInputStream inputStream = new FileInputStream("test.txt");
    Scanner scanner = new Scanner(inputStream);

    String result = scanner.findInLine("wo..d");
    assertEquals(expectedValue, result);

    scanner.close();
}

We can also search for a Pattern in specific domain using findWithinHorizon() as in the following example:

@Test
public void whenFindPatternInHorizon_thenFound() throws IOException {
    String expectedValue = "world";
    FileInputStream inputStream = new FileInputStream("test.txt");
    Scanner scanner = new Scanner(inputStream);

    String result = scanner.findWithinHorizon("wo..d", 5);
    assertNull(result);

    result = scanner.findWithinHorizon("wo..d", 100);
    assertEquals(expectedValue, result);

    scanner.close();
}

Note that the search horizon is simply the number of characters within which the search is performed.

9. Skip Pattern

Next – let’s see how to skip a Pattern in Scanner. We can skip tokens that match a specific pattern while reading the input using Scanner.

In the following example – we skip “Hello” token using the Scanner method skip():

@Test
public void whenSkipPatternUsingScanner_thenSkipped() throws IOException {
    FileInputStream inputStream = new FileInputStream("test.txt");
    Scanner scanner = new Scanner(inputStream);

    scanner.skip(".e.lo");

    assertEquals("world", scanner.next());

    scanner.close();
}

10. Change Scanner Delimiter

Finally – let’s see how to change the Scanner delimiter. In the following example – we change the default Scanner delimiter to “o“:

@Test
public void whenChangeScannerDelimiter_thenChanged() throws IOException {
    String expectedValue = "Hello world";
    String[] splited = expectedValue.split("o");

    FileInputStream inputStream = new FileInputStream("test.txt");
    Scanner scanner = new Scanner(inputStream);
    scanner.useDelimiter("o");

    assertEquals(splited[0], scanner.next());
    assertEquals(splited[1], scanner.next());
    assertEquals(splited[2], scanner.next());

    scanner.close();
}

We can also use multiple delimiters. In the following example – we use both comma “,” and dash”-” as delimiters to scan a file contains “John,Adam-Tom“:

@Test
public void whenReadWithScannerTwoDelimiters_thenCorrect() 
  throws IOException {
    Scanner scanner = new Scanner(new File("test.txt"));
    scanner.useDelimiter(",|-");

    assertEquals("John", scanner.next());
    assertEquals("Adam", scanner.next());
    assertEquals("Tom", scanner.next());

    scanner.close();
}

Note: The default Scanner delimiter is whitespace.

11. Conclusion

In this tutorial we went over multiple real world example of using the Java Scanner.

We learned how to read input from file, Console or String using Scanner; we also learned how to find and skip a pattern using Scanner – as well as how to change the Scanner delimiter.

The implementation of these examples can be found in the github project – this is an Eclipse based project, so it should be easy to import and run as it is.

Java 8 is out and about now - to keep track of everything, I will keep updating the Gran Kahuna of Java 8 Resources.

I usually post about Java stuff on Google+ - you should follow me there:


Guava CharMatcher

$
0
0

In this quick tutorial we’ll explore the CharMatcher utility class in Guava.

1. Remove Special Characters from a String

Let’s start by removing all special characters from a String.

In the following example, we remove all characters that aren’t digit or letter using retainFrom():

@Test
public void whenRemoveSpecialCharacters_thenRemoved(){
    String input = "H*el.lo,}12";
    CharMatcher matcher = CharMatcher.JAVA_LETTER_OR_DIGIT;
    String result = matcher.retainFrom(input);

    assertEquals("Hello12", result);
}

2. Remove non ASCII characters from String

We can also use CharMatcher to remove non ASCII characters from a String as in the following example:

@Test
public void whenRemoveNonASCIIChars_thenRemoved() {
    String input = "あhello₤";

    String result = CharMatcher.ASCII.retainFrom(input);
    assertEquals("hello", result);

    result = CharMatcher.inRange('0', 'z').retainFrom(input);
    assertEquals("hello", result);
}

3. Validate String

Next – let’s see how to validate a String using CharMatcher.

We can use matchesAllOf() to check if all characters match a condition. And we can make use of matchesNoneOf() to check if a condition doesn’t apply on any of the String characters.

In the following example, we check if our String is lowercase, contains at least one ‘e‘ character and doesn’t contain any digits:

@Test
public void whenValidateString_thenValid(){
    String input = "hello";

    boolean result = CharMatcher.JAVA_LOWER_CASE.matchesAllOf(input);
    assertTrue(result);

    result = CharMatcher.is('e').matchesAnyOf(input);
    assertTrue(result);

    result = CharMatcher.JAVA_DIGIT.matchesNoneOf(input);
    assertTrue(result);
}

4. Trim String

Now – let’s see how trim a String using CharMatcher.

In the following example, we use trimLeading(), trimTrailing and trimFrom() to trim our String:

@Test
public void whenTrimString_thenTrimmed() {
    String input = "---hello,,,";

    String result = CharMatcher.is('-').trimLeadingFrom(input);
    assertEquals("hello,,,", result);

    result = CharMatcher.is(',').trimTrailingFrom(input);
    assertEquals("---hello", result);

    result = CharMatcher.anyOf("-,").trimFrom(input);
    assertEquals("hello", result);
}

5. Collapse a String

Next – let’s see how to collapse a String using CharMatcher.

In the following example, we use collapseFrom() to replace consecutive spaces with ‘-‘:

@Test
public void whenCollapseFromString_thenCollapsed() {
    String input = "       hel    lo      ";

    String result = CharMatcher.is(' ').collapseFrom(input, '-');
    assertEquals("-hel-lo-", result);

    result = CharMatcher.is(' ').trimAndCollapseFrom(input, '-');
    assertEquals("hel-lo", result);
}

6. Replace from String

We can use CharMatcher to replace specific characters from a String as in the following example:

@Test
public void whenReplaceFromString_thenReplaced() {
    String input = "apple-banana.";

    String result = CharMatcher.anyOf("-.").replaceFrom(input, '!');
    assertEquals("apple!banana!", result);

    result = CharMatcher.is('-').replaceFrom(input, " and ");
    assertEquals("apple and banana.", result);
}

7. Count Character Occurrences

Finally – let’s see how to count the occurrences of characters using CharMatcher.

In the following example, we count the commas and characters between ‘a‘:’h‘:

@Test
public void whenCountCharInString_thenCorrect() {
    String input = "a, c, z, 1, 2";

    int result = CharMatcher.is(',').countIn(input);
    assertEquals(4, result);

    result = CharMatcher.inRange('a', 'h').countIn(input);
    assertEquals(2, result);
}

8. Conclusion

In this article we illustrated some of the more useful APIs and real-world usage examples of using Guava for Strings.

Java – Directory Size

$
0
0

1. Overview

In this tutorial – we’ll learn how to get size of a folder in Java – using Java 6, 7 and the new Java 8 as well Guava and Apache Common IO.

Finally – we will also get a human readable representation of the directory size.

2. With Java

Let’s start with a simple example of calculating the size of a folder – using the sum of its contents:

private long getFolderSize(File folder) {
    long length = 0;
    File[] files = folder.listFiles();

    int count = files.length;

    for (int i = 0; i < count; i++) {
        if (files[i].isFile()) {
            length += files[i].length();
        }
        else {
            length += getFolderSize(files[i]);
        }
    }
    return length;
}

We can test our method getFolderSize() as in the following example:

@Test
public void whenGetFolderSizeRecursive_thenCorrect() {
    long expectedSize = 12607;

    File folder = new File("src/test/resources");
    long size = getFolderSize(folder);

    assertEquals(expectedSize, size);
}

Note: listFiles() is used to list the contents of the given folder.

3. With Java 7

Next – let’s see how to use Java 7 to get the folder size. In the following example – we use Files.walkFileTree() to traverse all files in the folder to sum their sizes:

@Test
public void whenGetFolderSizeUsingJava7_thenCorrect() throws IOException {
    long expectedSize = 12607;

    AtomicLong size = new AtomicLong(0);
    Path folder = Paths.get("src/test/resources");

    Files.walkFileTree(folder, new SimpleFileVisitor<Path>() {
        @Override
        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) 
          throws IOException {
            size.addAndGet(attrs.size());
            return FileVisitResult.CONTINUE;
        }
    });

    assertEquals(expectedSize, size.longValue());
}

Note how we’re leveraging the filesystem tree traversal capabilities here and making use of the visitor pattern to help us visit and calculate the sizes of each file and subfolder.

4. With Java 8

Now – let’s see how to get the folder size using Java 8, stream operations and lambdas. In the following example – we use Files.walk() to traverse all files in the folder to sum their size:

@Test
public void whenGetFolderSizeUsingJava8_thenCorrect() throws IOException {
    long expectedSize = 12607;

    Path folder = Paths.get("src/test/resources");
    long size = Files.walk(folder)
                     .filter(p -> p.toFile().isFile())
                     .mapToLong(p -> p.toFile().length())
                     .sum();

    assertEquals(expectedSize, size);
}

Note: mapToLong() is used to generate a LongStream by applying the length function in each element – after which we can sum and get a final result.

5. With Apache Commons IO

Next – lets see how to get the folder size using Apache Commons IO. In the following example – we simply use FileUtils.sizeOfDirectory() to get the folder size:

@Test
public void whenGetFolderSizeUsingApacheCommonsIO_thenCorrect() {
    long expectedSize = 12607;

    File folder = new File("src/test/resources");
    long size = FileUtils.sizeOfDirectory(folder);

    assertEquals(expectedSize, size);
}

Note that this to the point utility method implements a simple Java 6 solution under the hood.

Also note that the library also provides a FileUtils.sizeOfDirectoryAsBigInteger() method that deals with security restricted directories better.

6. With Guava

Now – let’s see how to calculate the size of a folder using Guava. In the following example – we use Files.fileTreeTraverser() to traverse all files in the folder to sum their size:

@Test
public void whenGetFolderSizeUsingGuava_thenCorrect() {
    long expectedSize = 12607;

    File folder = new File("src/test/resources");

    Iterable<File> files = Files.fileTreeTraverser()
                                .breadthFirstTraversal(folder);
    long size = StreamSupport.stream(files.spliterator(), false)
                             .filter(f -> f.isFile())
                             .mapToLong(File::length).sum();

    assertEquals(expectedSize, size);
}

7. Human Readable Size

Finally – let’s see how to get a more user readable representation of the folder size – not just a size in bytes:

@Test
public void whenGetReadableSize_thenCorrect() {
    File folder = new File("src/test/resources");
    long size = getFolderSize(folder);

    String[] units = new String[] { "B", "KB", "MB", "GB", "TB" };
    int unitIndex = (int) (Math.log10(size) / 3);
    double unitValue = 1 << (unitIndex * 10);

    String readableSize = new DecimalFormat("#,##0.#")
                                .format(size / unitValue) + " " 
                                + units[unitIndex];
    assertEquals("12.3 KB", readableSize);
}

Note: We used DecimalFormat(“#,##0,#”) to round the result into one decimal place.

8. Notes

Here is some notes about folder size calculation:

  • Both Files.walk() and Files.walkFileTree() will throw a SecurityException if the security manager denies access to the starting file.
  • Infinite loop may occur if the folder contains symbolic links.

9. Conclusion

In this quick tutorial we illustrated examples of using different Java versions, Apache Commons IO and Guava to calculate the size of a directory in the file system.

The implementation of these examples can be found in the github project – this is an Eclipse based project, so it should be easy to import and run as it is.

Java 8 is out and about now - to keep track of everything, I will keep updating the Gran Kahuna of Java 8 Resources.

I usually post about Java stuff on Google+ - you should follow me there:

Baeldung Weekly Review 46

$
0
0

At the very beginning of 2014 I decided to start to track my reading habits and share the best stuff here, on Baeldung.

Curating my reading has made it more purposeful and diverse – and I’m hopefully providing value to you as well by allowing the best content of the week to raise to the top.

Here we go…

1. Java and Spring

>> Oracle announces more new Java 9 features!

New Java 9 features were announced this week. We knew modularity was the main focus, but we didn’t know logging is getting a facelift and the GC options a bit of a cleanup.

>> A beginner’s guide to Java time zone handling

The basics of dealing with time in Java – good stuff.

>> Interrupting Executor Tasks

I like this blog – it’s almost always something I find bookmarking after I read it. This one is about the details of how to handle canceling ongoing work happening inside a thread.

I have only vague recollections of doing this a few years back – and unfortunately I didn’t take notes. Turns out I can just refer back to this piece.

>> ExecutorService – 10 tips and tricks

Practical suggestions to follow when working with thread pools. Even one hidden behind the Springs @Async abstraction will benefit from a lot of these points. All in all, if you’re using them, go read this one – you’ll save yourself some time.

>> Devoxx 2014 – Whiteboard votes

Interesting snapshot of the Java ecosystem by voters from Devoxx 2014. Worth a quick read.

Of course new Spring recordings from SpringOne came out this week:

2. Technical and Musings

>> Continuous Delivery 101: Automated Deployments

Continuous Deployment is the way to go – I don’t think anyone would argue with that. Getting there though is a different story – this piece is a quick and to the point maturity model for CD – a very useful thing to keep in your back pocket when you’re setting up Jenkins for your next project.

>> Testing Strategies in a Microservice Architecture

This presentation-style deck is a very good place to start understanding microservices.

2014 has definitely been a year of growth and adoption for this architectural style, but – based on the number of failure stories that come out recently – it shouldn’t be treated as a default go-to.

Regardless, this deck is a balanced and well put together resource.

>> CAP Should Be CLAP

Very good read on why latency should be part of our discussion about CAP and our reasoning about availability. Definitely worth a read.

>> Annihilating Complexity

The fact that some people naturally add complexity to any scenario and some remove it is one of those things that – once you grok – you start seeing everywhere. And there’s worse things to be seeing everywhere – like the number 11 (I knew a guy).

To cut a long story short – like all models, this one is a bit of a simplification, but a very useful one. Useful in the fact that it gives you a good frame to look at your own solutions to a given problem analytically and improve.

>> How do I still write code as a Tech Lead?

Useful tactics on being an effective Tech lead. And effective means not putting distance between yourself and the code – if you stop coding, then you stop being a good lead.

3. Comics

You though I’m running out of good XKCD? Think again:

>> CD Tray Fight

>> The Difference

>> Connoisseur

4. Pick of the Week

I recently introduced the “Pick of the Week” section here in my “Weekly Review”. If you’re already on my email list – you got the pick already – hope you enjoyed it.

If not – you can share the review and unlock it right here:

I usually post about Dev stuff on Google+ - you can follow me there:

Baeldung Weekly Review 47

$
0
0

At the very beginning of 2014 I decided to start to track my reading habits and share the best stuff here, on Baeldung.

Curating my reading has made it more purposeful and diverse – and I’m hopefully providing value to you as well by allowing the best content of the week to raise to the top.

Here we go…

1. Java and Spring

>> Tuning Java Servers

In depth article on how to first understand and then improve the performance of a production Java server. Good stuff.

>> Making Elasticsearch Groovy-er

Elasticsearch now has a Groovy client – looking good.

>> Unit Testing exercise with FizzBuzz and Mockito

Who knew FizzBuzz can be even more useful – I’ve primarily been using it during interviewing. Very cool to see some mocking demonstrated with it as well.

>> Spring Boot 1.2.0.RC2 Available Now

Spring Boot is moving forward at a very fast pace, with second RC and better support for Java EE.

I’ve been using Boot in my own projects, both client work and personal and it is indeed a very helpful piece of kit.

>> Externalizing session state for a Spring-boot application using spring-session

A solid piece on externalizing all session state to Redis with the help of the new Spring-Session project. Helps a lot when you’re running a cluster.

A few other webinar recordings and releases to play with:

My Weekly Review on Baeldung

2. Technical and Musings

>> People Deserve The “What”

Great advice on how to delegate to knowledge workers so that you have good results long term. Or – if you are being delegated to – a frame you can use to letter understand your own situation and – if needed – change it.

Especially in the beginning, it’s a good idea to optimize for learning and growth.

>> Because Reading is Fundamental

Very interesting read how to encourage useful behavior in communities by displaying useful metrics next to each user, instead of metrics that won’t lead to good results.

>> Making Side Projects With New Technologies

If you’re reading my weekly reviews, then you’re probably at least somewhat passionate about your work – otherwise you wouldn’t be here. Now – consuming is well and good, but creating something new – that’s where the real learning happens.

This is a good and quick read going over why a side project is a good idea and how it will definitely benefit you in the long run.

>> Designing APIs for Machines

Building an API for other developers to consume is not an easy task. Every design decision needs to be carefully considered, especially once the API is in use by others.

Now – building an API that’s going to be consumed not by developers, but by other connected devices – in huge numbers no less – is a different kind of hard. Insightful read about what that looks like.

3. Comics

Let’s end the week with some XKCD:

>> Fiction Rule of Thumb

>> Escalators

>> Resonance

4. Pick of the Week

I recently introduced the “Pick of the Week” section here in my “Weekly Review”. If you’re already on my email list – you got the pick already – hope you enjoyed it.

If not – you can share the review and unlock it right here:

I usually post about Dev stuff on Google+ - you can follow me there:

Best Java Blogs

$
0
0

I usually post about Java stuff on Google+ - you should follow me there:

 

Overview and Criteria

There are several “Top Java Blogs” pages out there – but also a lot of noise. Some of these blogs are abandoned with the last postin 2008, some have simply switched focused from Java to something else. Others are gone altogether.

This page is meant to a up to date – end of 2014 – view of the Java ecosystem.

In order for a blog/site to be listed, here’s the simple criteria:

  • At least 10 relevant (Java) articles in the last 6 months
  • More text than Ads on the page
  • Alexa Rank < 10.000.000
  • Actually useful (in my view)

Top Java Websites (8 sites)

>> Javaworld

>> Java Code Geeks

>> InfoQ | Java

>> Javalobby

>> The Server Side

>> Jaxenter | Java

>> The Spring Blog

>> DeveloperWorks: Java technology

 

Top Java Developers Blogs (24 blogs)

>> Mkyong

>> Vogella | Java

>> Java Specialists Newsletter

>> Raible Designs | Java

>> Javarevisited

>> Java Papers | Java

>> Stephen Colebourne’s blog

>> ProgramCreek

>> Bozho’s tech blog

>> Baeldung // my site

>> Plumbr Blog

>> Takipi Blog | Java

>> jOOQ Blog | Java

>> Petri Kainulainen

>> NoBlogDefFound

>> Inspired by Actual Events

>> Vlad Mihalcea’s Blog

>> A Java geek

>> Jenkov Tutorials

>> Java Deep

>> Antonio’s Blog | A blog mainly about Java

>> Adam Bien’s Weblog

 >> Vanilla #Java

 >> Java2S | Java

If you want to suggest a site/blog – feel free to add it in the comments.

I usually post about Java stuff on Google+ - you should follow me there:

 

 

Best Spring Blogs

$
0
0

I usually post about Spring stuff on Google+ - you can follow me there:

Overview and Criteria

This page is meant to a up to date – end of 2014 – view of the Spring ecosystem.

In order for a blog/site to be listed, here’s the simple criteria:

  • At least 5 relevant (Java/Spring) articles in the last 6 months
  • More text than Ads on the page
  • Alexa Rank < 10.000.000
  • Actually useful (in my view)

Top Spring Developers Blogs and Sites

>> The Spring Blog

>> Codeleak

>> Petri Kainulainen | Spring

>> Captain Debug’s Blog

>> A Java Geek | Spring

>> All and Sundry | Spring

>> geekAbyte | Spring

>> Josh Long

>> Baeldung | Spring // my site

I usually post about Spring stuff on Google+ - you can follow me there:

 

HttpAsyncClient Tutorial

$
0
0

I usually post about Dev stuff on Google+ - you can follow me there:

1. Overview

In this tutorial we’ll illustrate the most common use cases of the Apache HttpAsyncClient – from basic usage, to how to set up a proxy, how to use SSL certificate and finally – how to authenticate with the async client.

2. Simple Example

First – let’s see how to use HttpAsyncClient in a simple example – send a GET request:

@Test
public void whenUseHttpAsyncClient_thenCorrect() throws Exception {
    CloseableHttpAsyncClient client = HttpAsyncClients.createDefault();
    client.start();
    HttpGet request = new HttpGet("http://www.google.com");
    
    Future<HttpResponse> future = client.execute(request, null);
    HttpResponse response = future.get();
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
    client.close();
}

Note how we need to start the async client before using it; without that, we would get the following exception:

java.lang.IllegalStateException: Request cannot be executed; I/O reactor status: INACTIVE
    at o.a.h.u.Asserts.check(Asserts.java:46)
    at o.a.h.i.n.c.CloseableHttpAsyncClientBase.
      ensureRunning(CloseableHttpAsyncClientBase.java:90)

3. Multi-Threading with HttpAsyncClient

Now – let’s see how to use HttpAsyncClient to execute multiple requests simultaneously.

In the following example – we send three GET requests to three different host using HttpAsyncClient and PoolingNHttpClientConnectionManager:

@Test
public void whenUseMultipleHttpAsyncClient_thenCorrect() throws Exception {
    ConnectingIOReactor ioReactor = new DefaultConnectingIOReactor();
    PoolingNHttpClientConnectionManager cm = 
      new PoolingNHttpClientConnectionManager(ioReactor);
    CloseableHttpAsyncClient client = 
      HttpAsyncClients.custom().setConnectionManager(cm).build();
    client.start();
    
    String[] toGet = { 
        "http://www.google.com/", 
        "http://www.apache.org/", 
        "http://www.bing.com/" 
    };

    GetThread[] threads = new GetThread[toGet.length];
    for (int i = 0; i < threads.length; i++) {
        HttpGet request = new HttpGet(toGet[i]);
        threads[i] = new GetThread(client, request);
    }

    for (GetThread thread : threads) {
        thread.start();
    }
    for (GetThread thread : threads) {
        thread.join();
    }
}

Here is our GetThread implementation to handle the response:

static class GetThread extends Thread {
    private CloseableHttpAsyncClient client;
    private HttpContext context;
    private HttpGet request;

    public GetThread(CloseableHttpAsyncClient client,HttpGet req){
        this.client = client;
        context = HttpClientContext.create();
        this.request = req;
    }

    @Override
    public void run() {
        try {
            Future<HttpResponse> future = client.execute(request, context, null);
            HttpResponse response = future.get();
            assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
        } catch (Exception ex) {
            System.out.println(ex.getLocalizedMessage());
        }
    }
}

4. Proxy with HttpAsyncClient

Next – let’s see how to set up and use a proxy with the HttpAsyncClient.

In the following example – we send a HTTP GET request over proxy:

@Test
public void whenUseProxyWithHttpClient_thenCorrect() throws Exception {
    CloseableHttpAsyncClient client = HttpAsyncClients.createDefault();
    client.start();
    
    HttpHost proxy = new HttpHost("74.50.126.248", 3127);
    RequestConfig config = RequestConfig.custom().setProxy(proxy).build();
    HttpGet request = new HttpGet("https://issues.apache.org/");
    request.setConfig(config);
    
    Future<HttpResponse> future = client.execute(request, null);
    HttpResponse response = future.get();
    
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
    client.close();
}

5. SSL Certificate with HttpAsyncClient

Now – let’s see how to use a SSL Certificate with HttpAsyncClient.

In the following example – we configure HttpAsyncClient to accept all certificates:

@Test
public void whenUseSSLWithHttpAsyncClient_thenCorrect() throws Exception {
    TrustStrategy acceptingTrustStrategy = new TrustStrategy() {
        public boolean isTrusted(X509Certificate[] certificate,  String authType) {
            return true;
        }
    };
    SSLContext sslContext = SSLContexts.custom()
      .loadTrustMaterial(null, acceptingTrustStrategy).build();

    CloseableHttpAsyncClient client = HttpAsyncClients.custom()
      .setSSLHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)
      .setSSLContext(sslContext).build();
    client.start();
    
    HttpGet request = new HttpGet("https://mms.nw.ru/");
    Future<HttpResponse> future = client.execute(request, null);
    HttpResponse response = future.get();
    
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
    client.close();
}

6. Cookies with HttpAsyncClient

Next – let’s see how to use cookies with HttpAsyncClient.

In the following example – we set a cookie value before sending the request:

@Test
public void whenUseCookiesWithHttpAsyncClient_thenCorrect() throws Exception {
    BasicCookieStore cookieStore = new BasicCookieStore();
    BasicClientCookie cookie = new BasicClientCookie("JSESSIONID", "1234");
    cookie.setDomain(".github.com");
    cookie.setPath("/");
    cookieStore.addCookie(cookie);
    
    CloseableHttpAsyncClient client = HttpAsyncClients.custom().build();
    client.start();
    
    HttpGet request = new HttpGet("http://www.github.com");
    HttpContext localContext = new BasicHttpContext();
    localContext.setAttribute(HttpClientContext.COOKIE_STORE, cookieStore);
    Future<HttpResponse> future = client.execute(request, localContext, null);
    HttpResponse response = future.get();
    
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
    client.close();
}

7. Authentication with HttpAsyncClient

Next – let’s see how to use authentication with HttpAsyncClient.

In the following example – we use the CredentialsProvider to access a host through basic authentication:

@Test
public void whenUseAuthenticationWithHttpAsyncClient_thenCorrect() throws Exception {
    CredentialsProvider provider = new BasicCredentialsProvider();
    UsernamePasswordCredentials creds = new UsernamePasswordCredentials("user", "pass");
    provider.setCredentials(AuthScope.ANY, creds);
    
    CloseableHttpAsyncClient client = 
      HttpAsyncClients.custom().setDefaultCredentialsProvider(provider).build();
    client.start();
    
    HttpGet request = new HttpGet("http://localhost:8080");
    Future<HttpResponse> future = client.execute(request, null);
    HttpResponse response = future.get();
    
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
    client.close();
}

8. Conclusion

In this article, we illustrated the various use cases of the asynchronous Apache Http client.

The implementation of all these examples and code snippets can be found in my github project – this is an Eclipse based project, so it should be easy to import and run as it is.

I usually post about Dev stuff on Google+ - you can follow me there:


Registration – Activate a New Account by Email

$
0
0

I usually post about Spring stuff on Google+ - you can follow me there:

1. Overview

This article continues our ongoing Registration with Spring Security series with one of the missing pieces of the registration process – verifying the users email to confirm their account.

The registration confirmation mechanism forces the user to respond to a “Confirm Registration” email sent after successful registration to verify his email address and activate their account. The user does this by clicking a unique activation link sent to them over email.

Following this logic, a newly registered user will not be able to log into the system until this process is completed.

2. A Verification Token

We will make use of a simple verification token as the key artifact through which a user is verified.

2.1. The VerificationToken Entity

The VerificationToken entity must meet the following criteria:

  1. It must link back to the User (via a unidirectional relation)
  2. It will be created right after registration
  3. It will expire within 24 hours following its creation
  4. Has a unique, randomly generated value

Requirements 2 and 3 are part of the registration logic. The other two are implemented in a simple VerificationToken entity like the one in Example 2.1.:

Example 2.1.

@Entity
public class VerificationToken {
    private static final int EXPIRATION = 60 * 24;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    
    private String token;
  
    @OneToOne(targetEntity = User.class, fetch = FetchType.EAGER)
    @JoinColumn(nullable = false, name = "user_id")
    private User user;
    
    private Date expiryDate;

    public VerificationToken() {
        super();
    }
    public VerificationToken(String token, User user) {
        super();
        this.token = token;
        this.user = user;
        this.expiryDate = calculateExpiryDate(EXPIRATION);
        this.verified = false;
    }
    
    private Date calculateExpiryDate(int expiryTimeInMinutes) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Timestamp(cal.getTime().getTime()));
        cal.add(Calendar.MINUTE, expiryTimeInMinutes);
        return new Date(cal.getTime().getTime());
    }
    
    // standard getters and setters
}

Note the nullable = false on the User to ensure data integrity and consistency in the VerificationToken<->User association.

2.2. Add the enabled field to User

Initially, when the User is registered, this enabled field will be set to false. During the account verification process – if successful – it will become true.

Lets start by adding the field to our User entity:

public class User {
    ...
    @Column(name = "enabled")
    private boolean enabled;
    
    public User() {
        super();
        this.enabled=false;
    }
    ...
}

Note how we also set the default value of this field to false.

3. During Account Registration

Lets add two additional pieces of business logic to the user registration use case:

  1. Generate the VerificationToken for the User and persist it
  2. Send out the email message for account confirmation – which includes a confirmation link with the VerificationToken’s value

3.1. Using a Spring Event to Create the Token and Send the Verification Email

These two additional pieces of logic should not be performed by the controller directly because they are “collateral” back-end tasks.

The controller will publish a Spring ApplicationEvent to trigger the execution of these tasks. This is as simple as injecting the ApplicationEventPublisher  and then using it to publish the registration completion.

Example 3.1. shows this simple logic:

Example 3.1.

@Autowired
ApplicationEventPublisher eventPublisher

@RequestMapping(value = "/user/registration", method = RequestMethod.POST)
public ModelAndView registerUserAccount(@ModelAttribute("user") @Valid UserDto accountDto, 
      BindingResult result, WebRequest request, Errors errors) {
    if (result.hasErrors()) {
        return new ModelAndView("registration", "user", accountDto);
    }
    
    User registered = registered = createUserAccount(accountDto);
    if (registered == null) {
        result.rejectValue("email", "message.regError");
    }
    try {
        String appUrl = request.getContextPath();
        eventPublisher.publishEvent(new OnRegistrationCompleteEvent
          (registered, request.getLocale(), appUrl));
    } catch (Exception me) {
        return new ModelAndView("emailError", "user", accountDto);
    }
    return new ModelAndView("successRegister", "user", accountDto);
}

One additional thing to notice is the try catch block surrounding the publishing of the event. This piece of code will display an error page whenever there is an exception in the logic executed after the publishing of the event, which in this case is the sending of the email.

3.2. The Event and The Listener

Let’s now see the actual implementation of this new OnRegistrationCompleteEvent that our controller is sending out, as well as the listener that is going to handle it:

Example 3.2.1. – The OnRegistrationCompleteEvent

public class OnRegistrationCompleteEvent extends ApplicationEvent {
    private final String appUrl;
    private final Locale locale;
    private final User user;

    public OnRegistrationCompleteEvent(User user, Locale locale, String appUrl) {
        super(user);
        
        this.user = user;
        this.locale = locale;
        this.appUrl = appUrl;
    }
    
    // standard getters and setters
}

Example 3.2.2. - The RegistrationListener Handles the OnRegistrationCompleteEvent

@Component
public class RegistrationListener implements ApplicationListener<OnRegistrationCompleteEvent> {
    @Autowired
    private IUserService service;
    @Autowired
    private MessageSource messages;
    @Autowired
    private JavaMailSender mailSender;

    @Override
    public void onApplicationEvent(OnRegistrationCompleteEvent event) {
        this.confirmRegistration(event);
    }

    private void confirmRegistration(OnRegistrationCompleteEvent event) {
        User user = event.getUser();
        String token = UUID.randomUUID().toString();
        service.createVerificationToken(user, token);
        
        String recipientAddress = user.getEmail();
        String subject = "Registration Confirmation";
        String confirmationUrl = event.getAppUrl() + "/regitrationConfirm.html?token=" + token;
        String message = messages.getMessage("message.regSucc", null, event.getLocale());
        SimpleMailMessage email = new SimpleMailMessage();
        email.setTo(recipientAddress);
        email.setSubject(subject);
        email.setText(message + " \r\n" + "http://localhost:8080" + confirmationUrl);
        mailSender.send(email);
    }
}

Here, the confirmRegistration method will receive the OnRegistrationCompleteEvent, extract all the necessary User information from it, create the verification token, persist it, and then send it as a parameter in the “Confirm Registration” link.

As was mentioned above, any javax.mail.AuthenticationFailedException thrown by JavaMailSender will be handled by the controller.

3.3. Processing the Verification Token Parameter

When the user receives the “Confirm Registration” link they should click on it.

Once they do – the controller will extract the value of the token parameter in the resulting GET request and will use it to enable the User.

Lets see this process in Example 3.3.1.:

Example 3.3.1. – RegistrationController Processing the Registration Confirmation

@Autowired
private IUserService service;

@RequestMapping(value = "/regitrationConfirm", method = RequestMethod.GET)
public String confirmRegistration
      (WebRequest request, Model model, @RequestParam("token") String token) {
    Locale locale = request.getLocale();
    
    VerificationToken verificationToken = service.getVerificationToken(token);
    if (verificationToken == null) {
        String message = messages.getMessage("auth.message.invalidToken", null, locale);
        model.addAttribute("message", message);
        return "redirect:/badUser.html?lang=" + locale.getLanguage();
    }
    
    User user = verificationToken.getUser();
    Calendar cal = Calendar.getInstance();
    if ((verificationToken.getExpiryDate().getTime() - cal.getTime().getTime()) <= 0) {
        model.addAttribute("message", messages.getMessage("auth.message.expired", null, locale));
        return "redirect:/badUser.html?lang=" + locale.getLanguage();
    } 
    
    user.setEnabled(true); 
    service.saveRegisteredUser(user); 
    return "redirect:/login.html?lang=" + request.getLocale().getLanguage(); 
}

The user will be redirected to an error page with the corresponding message if:

  1. The VerificationToken does not exist, for some reason or
  2. The VerificationToken has expired

See Example 3.3.2. to see the error page.

Example 3.3.2. – The badUser.html

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags"%>
<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<fmt:setBundle basename="messages" />
<%@ page session="true"%>
<html>
<head>
    <link href="<c:url value="/resources/bootstrap.css" />" rel="stylesheet">
    <title>Expired</title>
</head>
<body>
    <h1>${message}</h1>
    <br>
    <a href="<c:url value="/user/registration" />">
        <spring:message code="label.form.loginSignUp"></spring:message>
    </a>
</body>
</html>

If no errors are found, the user is enabled.

There are two opportunities for improvement in handling the VerificationToken checking and expiration scenarios:

  1. We can use a Cron Job to check for token expiration in the background
  2. We can give the user the opportunity to get a new token once it has expired

We’ll deffer the generation of a new token for a future article and assume that the user does indeed successfully verify their token here.

4. Adding Account Activation Checking to the Login Process

We need to add the code that will check if the user is enabled:

Lets see this in Example 4.1. which shows the loadUserByUsername method of MyUserDetailsService.

Example 4.1.

@Autowired
UserRepository userRepository;

public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
    boolean enabled = true;
    boolean accountNonExpired = true;
    boolean credentialsNonExpired = true;
    boolean accountNonLocked = true;
    try {
        User user = userRepository.findByEmail(email);
        if (user == null) {
            return new org.springframework.security.core.userdetails.User
              (" ", " ", enabled, true, true, true, getAuthorities(new Integer(1)));
        }
        return new org.springframework.security.core.userdetails.User(
          user.getEmail(), 
          user.getPassword().toLowerCase(), 
          user.isEnabled(), 
          accountNonExpired, 
          credentialsNonExpired, 
          accountNonLocked, 
          getAuthorities(user.getRole().getRole()));
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

As we can see, now MyUserDetailsService not uses the enabled flag of the user – and so it will only allow enabled user to authenticate. .

Now, we need to modify our login.html page to show the exception messages coming from MyUserDetailsService. The error checking code we added to login.html is shown in Example 4.2.:

Example 4.2. – Adding Account Activation Error Checking to login.html

<c:if test="${param.error != null}">
    <c:choose>
        <c:when test="${SPRING_SECURITY_LAST_EXCEPTION.message == 'User is disabled'}">
            <div class="alert alert-error">
                <spring:message code="auth.message.disabled"></spring:message>
            </div>
        </c:when>
        <c:when test="${SPRING_SECURITY_LAST_EXCEPTION.message == 'User account has expired'}">
            <div class="alert alert-error">
                <spring:message code="auth.message.expired"></spring:message>
            </div>
        </c:when>
        <c:otherwise>
            <div class="alert alert-error">
	      <spring:message code="message.badCredentials"></spring:message>
           </div>
        </c:otherwise>
    </c:choose>
</c:if>

5. Adapting the Persistence Layer

Let’s now provide the actual implementation of some of these operations involving the verification token as well as the users.

We’ll cover:

  1. A new VerificationTokenRepository
  2. New methods in the IUserInterface and its implementation for new CRUD operations needed

Examples 5.1 – 5.3. show the new interfaces and implementation:

Example 5.1. – The VerificationTokenRepository

public interface VerificationTokenRepository extends JpaRepository<VerificationToken, Long> {

    VerificationToken findByToken(String token);

    VerificationToken findByUser(User user);
}

Example 5.2. – The IUserService Interface

public interface IUserService {
    
    User registerNewUserAccount(UserDto accountDto) throws EmailExistsException;

    User getUser(String verificationToken);

    void saveRegisteredUser(User user);

    void createVerificationToken(User user, String token);

    VerificationToken getVerificationToken(String VerificationToken);
}

Example 5.3. The UserService

@Service
@Transactional
public class UserService implements IUserService {
    @Autowired
    private UserRepository repository;

    @Autowired
    private VerificationTokenRepository tokenRepository;

    @Override
    public User registerNewUserAccount(UserDto accountDto) throws EmailExistsException {
        if (emailExist(accountDto.getEmail())) {
            throw new EmailExistsException
              ("There is an account with that email adress: " + accountDto.getEmail());
        }
        User user = new User();
        user.setFirstName(accountDto.getFirstName());
        user.setLastName(accountDto.getLastName());
        user.setPassword(accountDto.getPassword());
        user.setEmail(accountDto.getEmail());
        user.setRole(new Role(Integer.valueOf(1), user));
        return repository.save(user);
    }

    private boolean emailExist(String email) {
        User user = repository.findByEmail(email);
        if (user != null) {
            return true;
        }
        return false;
    }
    
    @Override
    public User getUser(String verificationToken) {
        User user = tokenRepository.findByToken(verificationToken).getUser();
        return user;
    }
    
    @Override
    public VerificationToken getVerificationToken(String VerificationToken) {
        return tokenRepository.findByToken(VerificationToken);
    }
    
    @Override
    public void saveRegisteredUser(User user) {
        repository.save(user);
    }
    
    @Override
    public void createVerificationToken(User user, String token) {
        VerificationToken myToken = new VerificationToken(token, user);
        tokenRepository.save(myToken);
    }
}

6. Conclusion

In this article, we’ve expanded the registration process to include an email based account activation procedure. The account activation logic requires sending a verification token to the user via email, so that they can send it back to the controller to verify their identity.

The implementation of this Spring Security REST Tutorial can be found in the github project – this is an Eclipse based project, so it should be easy to import and run as it is.

I usually post about Spring stuff on Google+ - you can follow me there:

 

Baeldung Weekly Review 48

$
0
0

I usually post about Dev stuff on Google+ - you can follow me there:

At the very beginning of 2014 I decided to start to track my reading habits and share the best stuff here, on Baeldung.

Curating my reading has made it more purposeful and diverse – and I’m hopefully providing value to you as well by allowing the best content of the week to raise to the top.

Here we go…

1. Java and Spring

>> Java Doesn’t Suck – You’re Just Using it Wrong

Let’s put our best foot forward and start this weeks review with a must read. If you’re reading my reviews, you’re likely doing some work in Java – in which case, this piece will be highly useful.

Some of these points are obvious but I need to give a bit more through to the ones that aren’t.

>> New Java Version – it’s not JDK 1.9

I never thought I’d see the day, but it looks like it actually may be happening – Java’s going for semantic versioning. No more elvish 1.7.0_65-b20 (7u65) – but simple 7.6.15.

And since we’re on JDK related news, the main JDK 9 page was just updated with a few interesting tidbits. A few more JEPs as well as a proposal to drop the JSON API!

>> 15 Tools Java Developers Should Use After a Major Release

Whenever I come across a system running in production without monitoring or a good logging solution – and it happens more often than you’d imagine – I tend to fall back to a few of the solutions in this article.

ELK is my go to for logging, as for monitoring, I usually set up collectd + Graphite. It’s not pretty but it gets the job done. And of course Pingdom, or something like it – is a must.

>> A Simple Use-case Comparison of JVM Libraries for MongoDB

If you’re doing Mongo work on the JVM, go ahead and read this one – it’s useful and doesn’t waste your time.

I always find these high level comparisons useful – they give you the much needed context of someone who took the time to try out all of the options for themselves.

>> The Fatal Flaw of Finalizers and Phantoms

An in-depth read on why not to use finalizers in Java.

>> Latest Jackson integration improvements in Spring

I’m very excited about the new Jackson goodness in the very latest Spring releases – it looks like it’s going to allow a lot more flexibility in terms of output.

>> First Milestone of Spring Data Release Train Fowler Available

Spring Data needs no introduction – here’s what’s going to be available in the next release. Or – if you’re not going with it in production, what might already be available by using this Milestone. I’m going to try the new Elasticsearch release shortly.

>> Spring Tool Suite and Groovy/Grails Tool Suite 3.6.3 released

Step right up. Upgrade your IDE.

>> Avoid unwanted component scanning of Spring Configuration

If you have the problem of duplicate beans in your Spring context, you might not even be aware of it. Here’s a simple solution for the Spring Security configuration.

>> Spring request-level memoization

A cool technique to leverage caching as cross-cutting concern of your system and get repeatable reads at the request level with Spring.

>> Spring RestTemplate with a linked resource

Making the RestTemplate HAL aware – very cool indeed.

And finally, the webinar recordings that I have on my TODO list for this weekend:

2. Technical and Musings

>> The Dominant Leader Fallacy

Leadership is a matter of trust — not dominance.” The last sentence sums up this piece quite well – mosey over and give it a read if you resonate with that.

>> TDDaiymi vs. Naked Primitives

TDD-ing your way to good design is a learned skill that takes years of practice. I’m certainly not “there” yet, nor do I think there is a “There” really.

That being said – these Katas/Activities are a very useful kick in the read end. And the only way to start – unless your uber-disciplined – is doing them in a group setting, such as a code retreat – where you have no other choice.

>> Getting Started with Machine Learning

A conversational intro to machine learning, along with an actual example of how to build yourself a classifier (and why).

>> What is the Web?

You’ve been doing development on the web in some shape of form for years now, as have I. Is it still worth reading this article?

Yes it is!

>> Static Typing Is Not for Type Checking

A nuanced view on some of the advantages of statically-typed language. An interesting read.

>> Git 2.2.0 is out!

Nice overview of what’s new and useful in the 2.2 release of Git.

3. Comics

XKCD is my go to. Dilbert is a close second:

>> Anonymous Survey

>> Lie by omission?

>> A nun, a CEO and a Scientist a in a burning building

4. Pick of the Week

I recently introduced the “Pick of the Week” section here in my “Weekly Review”. If you’re already on my email list – you got the pick already – hope you enjoyed it.

If not – you can share the review and unlock it right here:

I usually post about Dev stuff on Google+ - you can follow me there:

@Async in Spring

$
0
0

1. Overview

In this article we’ll explore the asynchronous execution support in Spring – and the @Async annotation.

Simply put – annotating a method of a bean with @Async will make it execute in a separate thread i.e. the caller will not wait for the completion of the called method.

2. Enable Async Support

Let’s start by enabling asynchronous processing with Java configuration – by simply adding the @EnableAsync to a configuration class:

@Configuration
@EnableAsync
public class SpringAsyncConfig { ... }

The enable annotation is enough, but as you’d expect, there are also a few simple options for configuration as well:

  • annotation – by default, @EnableAsync detects Spring’s @Async annotation and the EJB 3.1 javax.ejb.Asynchronous; this option can be used to detect other, user defined annotation types as well
  • mode – indicates the type of advice that should be used – JDK proxy-based or AspectJ weaving
  • proxyTargetClass - indicates the type of proxy that should be used – CGLIB or JDK; this attribute has effect only if the mode is set to AdviceMode.PROXY
  • order – sets the order in which AsyncAnnotationBeanPostProcessor should be applied; by default it runs last, just so that it can take into account all existing proxies

Asynchronous processing can also be enabled using XML configuration – by using the task namespace:

<task:executor id="myexecutor" pool-size="5"  />
<task:annotation-driven executor="myexecutor"/>

3. The @Async Annotation

First – let’s go over the rules – @Async has two limitations:

  • it must be applied to public methods only
  • self invocation – calling the async method from within the same class – won’t work

The reasons are simple – the method needs to be public so that it can be proxied. And self-invocation doesn’t work because it bypasses the proxy and calls the underlying method directly.

3.1. Methods with void Return Type

Following is the simple way to configure a method with void return type to run asynchronously:

@Async
public void asyncMethodWithVoidReturnType() {
    System.out.println("Execute method asynchronously. " 
      + Thread.currentThread().getName());
}

3.2. Methods With Return Type

@Async can also be applied to a method with return type – by wrapping the actual return in a Future:

@Async
public Future<String> asyncMethodWithReturnType() {
    System.out.println("Execute method asynchronously - " 
      + Thread.currentThread().getName());
    try {
        Thread.sleep(5000);
        return new AsyncResult<String>("hello world !!!!");
    } catch (InterruptedException e) {
        //
    }

    return null;
}

Spring also provides a AsyncResult class which implements Future. This can be used to track the result of asynchronous method execution.

Now, let’s invoke the above method and retrieve the result of the asynchronous process using the Future object.

public void testAsyncAnnotationForMethodsWithReturnType()
	throws InterruptedException, ExecutionException {
    System.out.println("Invoking an asynchronous method. " 
      + Thread.currentThread().getName());
    Future<String> future = asyncAnnotationExample.asyncMethodWithReturnType();

    while (true) {
        if (future.isDone()) {
            System.out.println("Result from asynchronous process - " + future.get());
            break;
        }
        System.out.println("Continue doing something else. ");
        Thread.sleep(1000);
    }
}

4. The Executor

By default Spring uses a SimpleAsyncTaskExecutor to actually run these methods asynchronously. The defaults can be overridden at two levels – at the application level or at the individual method level.

4.1. Override the Executor at the Method Level

The required executor needs to be declared in a configuration class:

@Configuration
@EnableAsync
public class SpringAsyncConfig {
    
    @Bean(name = "threadPoolTaskExecutor")
    public Executor threadPoolTaskExecutor() {
        return new ThreadPoolTaskExecutor();
    }
}

Then the executor name should be provided as an attribute in @Async:

@Async("threadPoolTaskExecutor")
public void asyncMethodWithConfiguredExecutor() {
    System.out.println("Execute method with configured executor - "
      + Thread.currentThread().getName());
}

4.2. Override the Executor at the Application Level

The configuration class should implement the AsyncConfigurer interface – which will mean that it has the implement the getAsyncExecutor() method. It’s here that we will return the executor for the entire application – this now becomes the default executor to run methods annotated with @Async:

@Configuration
@EnableAsync
public class SpringAsyncConfig implements AsyncConfigurer {
    
    @Override
    public Executor getAsyncExecutor() {
        return new ThreadPoolTaskExecutor();
    }
    
}

5. Exception Handling

When a method return type is a Future, exception handling is easy – Future.get() method will throw the exception.

But, if the return type is void, exceptions will not be propagated to the calling thread. Hence we need to add extra configurations to handle exceptions.

We’ll create a custom async exception handler by implementing AsyncUncaughtExceptionHandler interface. The handleUncaughtException() method is invoked when there are any uncaught asynchronous exceptions:

public class CustomAsyncExceptionHandler  implements AsyncUncaughtExceptionHandler {

    @Override
    public void handleUncaughtException(Throwable throwable, Method method, Object... obj) {
        System.out.println("Exception message - " + throwable.getMessage());
        System.out.println("Method name - " + method.getName());
        for (Object param : obj) {
            System.out.println("Parameter value - " + param);
        }
    }
    
}

In the previous section we looked at the AsyncConfigurer interface implemented by the configuration class. As part of that, we also need to override the getAsyncUncaughtExceptionHandler() method to return our custom asynchronous exception handler:

@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
    return new CustomAsyncExceptionHandler();
}

7. Conclusion

In this tutorial we looked at running asynchronous code with Spring. We started with the very basic configuration and annotation to make it work but also looked at more advanced configs such as providing our own executor, or exception handling strategies.

Baeldung Weekly Review 49

$
0
0

I usually post about Dev stuff on Google+ - you can follow me there:

At the very beginning of 2014 I decided to track my reading habits and share the best stuff here, on Baeldung.

Here we go…

1. Spring

Let’s star the review with some exciting news – lots of Spring releases this week:

And of course, a few more recordings from SpringOne – most about Spring XD:

>> Spring Data JPA Tutorial: Getting the Required Dependencies

A very helpful and to the point post on putting together the right Maven dependencies to use Spring Data JPA.

>> Creating a REST API with Spring Boot and MongoDB

And a solid intro to build a REST API with Boot and MongoDB.

>> Boot your own infrastructure – Extending Spring Boot in five steps

A detailed, infrastructure level article on building your own Spring Boot Starter, if you can’t find an existing one that already covers your needs. And who knows – perhaps it will someday became official.

>> Avoid conditional logic in @Configuration

When @Profile was introduced in Spring, it had quite an effect on the way we could control our configuration. We could do things with profiles that simply weren’t possible before, at least not cleanly – which is ultimately what you’re looking for in a good abstraction.

Spring 4.0 improved on @Profile by introducing @Conditional - a next level of abstraction annotation that basically allow you to control your configuration based on any number of conditions, not just profiles.

This piece goes into some detail on how to use these conditional annotations that Spring Boot makes available.

2. Java

>> What might a Beans v2.0 spec contain?

A cool though experiment on what would make sense in a new Java Beans 2.0 spec. But more than just that – an actual, early implementation you can check out (and contribute to).

>> On heap vs off heap memory usage

Off heap memory for the JVM is one of those things you read about but may never actually use. Even so, this is a piece I enjoyed reading.

>> Don’t be “Clever”: The Double Curly Braces Anti Pattern

An oldie but a goodie – the double curly braces instantiation. Yeah – not a good idea.

>> The downside of version-less optimistic locking

An article on version-less optimistic locking – a cool Hibernate feature I didn’t know about.

>> Replacing Throwing Exceptions with Notification in Validations

A must read on handling validation properly and how to refactor your way to a better notification based solution.

>> Elasticsearch tips: inserting vs. updating your index

I’ve been using a lot of Elasticsearch lately and this was helpful.

3. Technical and Musings

>> Chris Richardson Discusses CQRS and Event Sourcing via Docker

A very articulate and engaging 15 minute interview with Chris Richardson on CQRS architecture.

If you’re building micro-services (or thinking about it) – CQRS and Event Sourcing are a solid way to go.

>> Flexibility vs Simplicity? Why Not Both?

Pragmatic piece on being critical and reevaluating your beliefs, even (or especially) the industry accepted ones you previously took for granted. A better way may be available if you just look at the problem differently.

4. Comics

All in with Dilbert this week:

>> Hunt Down and Kill Our Data

>> Made Up Numbers

>> Reinstall your OS

5. Pick of the Week

I recently introduced the “Pick of the Week” section here in my “Weekly Review”. If you’re already on my email list – you got the pick already – hope you enjoyed it.

If not – you can share the review and unlock it right here:

I usually post about Dev stuff on Google+ - you can follow me there:

Jackson JSON Views

$
0
0

I usually post about Jackson and JSON stuff on Google+ - you can follow me there:

1. Overview

In this tutorial, we’ll go over how to use Jackson JSON Views to serialize/deserialize objects, customize the views and finally – how to start integrating with Spring.

2. Serialize using JSON Views

First – let’s go through a simple example – serialize an object with @JsonView.

Here is our view:

public class Views {
    public static class Public {
    }
}

And the “User” entity:

public class User {
    public int id;

    @JsonView(Views.Public.class)
    public String name;
}

Now let’s serialize a “User” instance using our view:

@Test
public void whenUseJsonViewToSerialize_thenCorrect() 
  throws JsonProcessingException {
    User user = new User(1, "John");

    ObjectMapper mapper = new ObjectMapper();
    mapper.disable(MapperFeature.DEFAULT_VIEW_INCLUSION);

    String result = mapper.writerWithView(Views.Public.class)
                          .writeValueAsString(user);

    assertThat(result, containsString("John"));
    assertThat(result, not(containsString("1")));
}

Note how, because we’re serializing with a specific view active, we’re seeing only the right fields being serialized.

It’s also important to understand, that – by default – all properties not explicitly marked as being part of a view, are serialized. We are disabling that behavior with the handy DEFAULT_VIEW_INCLUSION feature.

3. Use Multiple JSON Views

Next – let’s see how to use multiple JSON Views – each has different fields as in the following example:

Here we have to views where Internal extends Public, with the internal view extending the public one:

public class Views {
    public static class Public {
    }

    public static class Internal extends Public {
    }
}

And here is our entity “Item” where only the fields id and name are included in the Public view:

public class Item {
    @JsonView(Views.Public.class)
    public int id;

    @JsonView(Views.Public.class)
    public String itemName;

    @JsonView(Views.Internal.class)
    public String ownerName;
}

If we use the Public view to serialize – only id and name will be serialized to JSON:

@Test
public void whenUsePublicView_thenOnlyPublicSerialized() 
  throws JsonProcessingException {
    Item item = new Item(2, "book", "John");

    ObjectMapper mapper = new ObjectMapper();
    String result = mapper.writerWithView(Views.Public.class)
                          .writeValueAsString(item);

    assertThat(result, containsString("book"));
    assertThat(result, containsString("2"));

    assertThat(result, not(containsString("John")));
}

But if we use the Internal view to perform the serialization, all fields will be part of the JSON output:

@Test
public void whenUseInternalView_thenAllSerialized() 
  throws JsonProcessingException {
    Item item = new Item(2, "book", "John");

    ObjectMapper mapper = new ObjectMapper();
    String result = mapper.writerWithView(Views.Internal.class)
                          .writeValueAsString(item);

    assertThat(result, containsString("book"));
    assertThat(result, containsString("2"));

    assertThat(result, containsString("John"));
}

4. Deserialize using JSON Views

Now – let’s see how to use JSON Views to deserialize objects – specifically, a User instance:

@Test
public void whenUseJsonViewToDeserialize_thenCorrect() 
  throws IOException {
    String json = "{\"id\":1,\"name\":\"John\"}";

    ObjectMapper mapper = new ObjectMapper();
    User user = mapper.readerWithView(Views.Public.class)
                      .withType(User.class)
                      .readValue(json);

    assertEquals(1, user.getId());
    assertEquals("John", user.getName());
}

Note how we’re using the readerWithView() API to create an ObjectReader using the given view.

5. Customize JSON Views

Next – let’s see how to customize JSON Views. In the next example – we want to make the Username” UpperCase in the serialization result.

We will use BeanPropertyWriter and BeanSerializerModifier to customize our JSON view. First – here is the BeanPropertyWriter UpperCasingWriter to transform the User name to upper case:

public class UpperCasingWriter extends BeanPropertyWriter {
    BeanPropertyWriter _writer;

    public UpperCasingWriter(BeanPropertyWriter w) {
        super(w);
        _writer = w;
    }

    @Override
    public void serializeAsField(Object bean, JsonGenerator gen, 
      SerializerProvider prov) throws Exception {
        String value = ((User) bean).name;
        value = (value == null) ? "" : value.toUpperCase();
        gen.writeStringField("name", value);
    }
}

And here is the BeanSerializerModifier to set the User name BeanPropertyWriter with our custom UpperCasingWriter:

public class MyBeanSerializerModifier extends BeanSerializerModifier{

    @Override
    public List<BeanPropertyWriter> changeProperties(
      SerializationConfig config, BeanDescription beanDesc, 
      List<BeanPropertyWriter> beanProperties) {
        for (int i = 0; i < beanProperties.size(); i++) {
            BeanPropertyWriter writer = beanProperties.get(i);
            if (writer.getName() == "name") {
                beanProperties.set(i, new UpperCasingWriter(writer));
            }
        }
        return beanProperties;
    }
}

Now – let’s serialize a User instance using the modified Serializer:

@Test
public void whenUseCustomJsonViewToSerialize_thenCorrect() 
  throws JsonProcessingException {
    User user = new User(1, "John");
    SerializerFactory serializerFactory = BeanSerializerFactory.instance
      .withSerializerModifier(new MyBeanSerializerModifier());

    ObjectMapper mapper = new ObjectMapper();
    mapper.setSerializerFactory(serializerFactory);

    String result = mapper.writerWithView(Views.Public.class)
                          .writeValueAsString(user);

    assertThat(result, containsString("JOHN"));
    assertThat(result, containsString("1"));
}

6. Using JSON Views with Spring

Finally – let’s take a quick look at using JSON views with the Spring Framework. We can leverage the @JsonView annotation to customize our JSON response at the API level.

In the following example – we used the Public view to respond:

@JsonView(Views.Public.class)
@RequestMapping("/items/{id}")
public Item getItemPublic(@PathVariable int id) {
    return ItemManager.getById(id);
}

The response is:

{"id":2,"itemName":"book"}

And when we used the Internal view as follows:

@JsonView(Views.Internal.class)
@RequestMapping("/items/internal/{id}")
public Item getItemInternal(@PathVariable int id) {
    return ItemManager.getById(id);
}

That was the response:

{"id":2,"itemName":"book","ownerName":"John"}

If you want to dive deeper into using the views with Spring 4.1, you should check out the Jackson improvements in Spring 4.1.

7. Conclusion

In this quick tutorial, we had a look at the Jackson JSON views and the @JsonView annotation. We learned how to use JSON Views to have fine-grained control over our serialize/deserialize process – using a single or multiple views.

I usually post about Jackson and JSON stuff on Google+ - you can follow me there:

 

Baeldung Weekly Review 50

$
0
0

I usually post about Dev stuff on Google+ - you can follow me there:

At the very beginning of 2014 I decided to track my reading habits and share the best stuff here, on Baeldung.

Here we go…

1. Java and Spring

>> Project Jigsaw: Modular run-time images

Here’s what’s happening with modularization in JDK 9, straight from the horse’s mouth. Some breaking changes to move the platform forward.

>> EAGER fetching is a code smell

Using LAZY fetching and a per query fetching strategy are two useful constraints to work within when using Hibernate.

>> Java 8 Streams and JPA

Very cool usage of Java 8 streams with the older JPA API.

>> Really Too Bad that Java 8 Doesn’t Have Iterable.stream()

Balancing design decisions, especially when growing a language as widely used as Java, is nuanced and difficult. That being said – I would really want to be able to do iterable.stream() :)

>> Spring MVC 4 Quickstart Maven Archetype Improved

Very nice improvements to the Spring MVC 4 Maven Archetype.

While I stayed away from using Maven Archetypes and prefer to set things up myself, I do see the value of a shortcut like this to speed up your initial project setup.

Let’s see what are the weeks Spring releases:

And of course some recordings for the weekend:

2. Technical and Musings

>> APIs should not be copyrightable

This lays out the thinking behind NOT making APIs copyrightable and protected. It’s an important piece of reading for the 5 minutes it takes – go ahead and read it.

>> In Devs We Trust

The ideological underpinnings of Agile are quite different then what the industry matured into. It’s no surprise though, but it is important to understand the difference is and why an “Agile Certification” is silly.

>> Hacking is Important

The ethos of “hacking” as the force not to move forward but leap forward.

>> Why big companies slow down, and what to do about it

A long piece on the growth lifecyle of a software company, and a very interesting read.

>> In Favour of Self-Signed Certificates

Interesting thinking around the edges of security and HTTPS certificates for all.

>> The Cycles of TDD

What it means to do TDD at the nano level and up.

>> Programmer Knowledge

The half-life of programmer knowledge is why it’s never a good idea to stop learning.

3. Comics

All in with Dilbert this week:

>> Code Mocking

>> Blah Blah Cloud

>> Vortex of Failure

4. Pick of the Week

I recently introduced the “Pick of the Week” section here in my “Weekly Review”. If you’re already on my email list – you got the pick already – hope you enjoyed it.

If not – you can share the review and unlock it right here:

I usually post about Dev stuff on Google+ - you can follow me there:

Transactions with Spring 4 and JPA

$
0
0

I usually post about Persistence on Google+ - you can follow me there:

 

1. Overview

This tutorial will discuss the right way to configure Spring Transactions, how to use the @Transactional annotation and common pitfalls.

For a more in depth discussion on the core persistence configuration, check out the Spring with JPA tutorial.

There are two distinct ways to configure Transactions – annotations and AOP – each with their own advantages – we’re going to discuss the more common annotation config here.

2. Configure Transactions without XML

Spring 3.1 introduces the @EnableTransactionManagement annotation to be used in on @Configuration classes and enable transactional support:

@Configuration
@EnableTransactionManagement
public class PersistenceJPAConfig{

   @Bean
   public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(){
      ...
   }

   @Bean
   public PlatformTransactionManager transactionManager(){
      JpaTransactionManager transactionManager = new JpaTransactionManager();
      transactionManager.setEntityManagerFactory(
       entityManagerFactoryBean().getObject() );
      return transactionManager;
   }
}

3. Configure Transactions with XML

Before 3.1 or if Java is not an option, here is the XML configuration, using annotation-driven and the namespace support:

<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
   <property name="entityManagerFactory" ref="myEmf" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />

4. The @Transactional Annotation

With transactions configured, a bean can now be annotated with @Transactional either at the class or method level:

@Service
@Transactional
public class FooService {
    ...
}

The annotation supports further configuration as well:

  • the Propagation Type of the transaction
  • the Isolation Level of the transaction
  • a Timeout for the operation wrapped by the transaction
  • a readOnly flag – a hint for the persistence provider that the transaction should be read only
  • the Rollback rules for the transaction

Note that – by default, rollback happens for runtime, unchecked exceptions only. Checked exception do not trigger a rollback of the transaction; the behavior can of course be configured with the rollbackFor and noRollbackFor annotation parameters.

5. Potential Pitfalls

5.1. Transactions and Proxies

At a high level, Spring creates proxies for all the classes annotated with @Transactional – either on the class or on any of the methods. The proxy allows the framework to inject transactional logic before and after the method being invoked – mainly for starting and committing the transaction.

What is important to keep in mind is that, if the transactional bean is implementing an interface, by default the proxy will be a Java Dynamic Proxy. This means that only external method calls that come in through the proxy will be intercepted – any self-invocation calls will not start any transaction – even if the method is annotated with @Transactional.

Another caveat of using proxies is that only public methods should be annotated with @Transactional – methods of any other visibilities will simply ignore the annotation silently as these are not proxied.

This article discusses further proxying pitfals in great detail here.

5.2. Changing the Isolation level

One of the major pitfalls when configuring Spring to work with JPA is that changing the isolation of the transaction semantics will not work – JPA does not support custom isolation levels. This is a limitation of JPA, not Spring; nevertheless changing the @Transactional isolation property will result in:

org.springframework.transaction.InvalidIsolationLevelException: Standard JPA does not support custom isolation levels – use a special JpaDialect for your JPA implementation

5.3. Read Only Transactions

The readOnly flag usually generates confusion, especially when working with JPA; from the javadoc:

This just serves as a hint for the actual transaction subsystem; it will not necessarily cause failure of write access attempts. A transaction manager which cannot interpret the read-only hint will not throw an exception when asked for a read-only transaction.

The fact is that it cannot be guaranteed that an insert or update will not occur when the readOnly flag is set – its behavior is vendor dependent whereas JPA is vendor agnostic.

It is also important to understand that the readOnly flag is only relevant inside a transaction; if an operation occurs outside of a transactional context, the flag is simply ignored. A simple example of that would calling a method annotated with:

@Transactional( propagation = Propagation.SUPPORTS,readOnly = true )

from a non-transactional context – a transaction will not be created and the readOnly flag will be ignored.

5.4. Transaction Logging

Transactional related issues can also be better understood by fine-tuning logging in the transactional packages; the relevant package in Spring is “org.springframework.transaction”, which should be configured with a logging level of TRACE.

6. Conclusion

We covered the basic configuration of transactional semantics using both java and XML, how to use @Transactional and best practices of a Transactional Strategy. The Spring support for transactional testing as well as some common JPA pitfalls were also discussed.

The implementation of this Spring Transaction Tutorial can be downloaded as a working sample project.

This is an Eclipse based project, so it should be easy to import and run as it is.

I usually post about Persistence on Google+ - you can follow me there:


Jackson Exceptions – Problems and Solutions

$
0
0

I usually post about Jackson and JSON stuff on Google+ - you can follow me there:

1. Overview

In this tutorial, we’ll go over the most common Jackson Exceptions – the JsonMappingException and UnrecognizedPropertyException.

Finally – we’ll briefly discuss Jackson no such method errors.

2. JsonMappingException: Can not construct instance of

2.1. The Problem

First – let’s take a look at JsonMappingException: Can not construct instance of.

This exception is thrown if Jackson can’t create instance of the class – this happens if the class is abstract or it is just an interface.

In the following example – we try to deserialize an instance from class Zoo which has a property animal with abstract type Animal:

public class Zoo {
    public Animal animal;
    
    public Zoo() { }
}

abstract class Animal {
    public String name;
    
    public Animal() { }
}

class Cat extends Animal {
    public int lives;
    
    public Cat() { }
}

When we try to deserialize a JSON String to Zoo instance it throws the “JsonMappingException: Can not construct instance of” as in the following example:

@Test(expected = JsonMappingException.class)
public void givenAbstractClass_whenDeserializing_thenException() 
  throws IOException {
    String json = "{\"animal\":{\"name\":\"lacy\"}}";
    ObjectMapper mapper = new ObjectMapper();

    mapper.reader().withType(Zoo.class).readValue(json);
}

The full exception is:

com.fasterxml.jackson.databind.JsonMappingException: 
Can not construct instance of org.baeldung.jackson.exception.Animal,
 problem: abstract types either need to be mapped to concrete types, have custom deserializer, 
or be instantiated with additional type information
 at 
[Source: {"animal":{"name":"lacy"}}; line: 1, column: 2] 
(through reference chain: org.baeldung.jackson.exception.Zoo["animal"])
	at c.f.j.d.JsonMappingException.from(JsonMappingException.java:148)

2.2. The Solution

We can solve the problem with a simple annotation – @JsonDeserialize on the abstract class:

@JsonDeserialize(as = Cat.class)
abstract class Animal {...}

3. JsonMappingException: No suitable constructor

3.1. The Problem

Now – let’s look at the common JsonMappingException: No suitable constructor found for type.

This exception is thrown if Jackson can’t access the constructor.

In the following example – class User doesn’t have a default constructor:

public class User {
    public int id;
    public String name;

    public User(int id, String name) {
        this.id = id;
        this.name = name;
    }
}

When we try to deserialize a JSON String to User an Exception “JsonMappingException: No suitable constructor found” is thrown – as in the following example:

@Test(expected = JsonMappingException.class)
public void givenNoDefaultConstructor_whenDeserializing_thenException() 
  throws IOException {
    String json = "{\"id\":1,\"name\":\"John\"}";
    ObjectMapper mapper = new ObjectMapper();

    mapper.reader().withType(User.class).readValue(json);
}

The full exception is:

com.fasterxml.jackson.databind.JsonMappingException: 
No suitable constructor found for type 
[simple type, class org.baeldung.jackson.exception.User]:
 can not instantiate from JSON object (need to add/enable type information?)
 at [Source: {"id":1,"name":"John"}; line: 1, column: 2]
        at c.f.j.d.JsonMappingException.from(JsonMappingException.java:148)

3.2. The Solution

To solve this problem – just add a default constructor as in the following example:

public class User {
    public int id;
    public String name;

    public User() {
        super();
    }

    public User(int id, String name) {
        this.id = id;
        this.name = name;
    }
}

Now when we deserialize – the process will work just fine:

@Test
public void givenDefaultConstructor_whenDeserializing_thenCorrect() 
  throws IOException {
    String json = "{\"id\":1,\"name\":\"John\"}";
    ObjectMapper mapper = new ObjectMapper();

    User user = mapper.reader().withType(User.class).readValue(json);
    assertEquals("John", user.name);
}

4. JsonMappingException: Root name does not match expected

4.1. The Problem

Next – let’s take a look at JsonMappingException: Root name does not match expected.

This exception is thrown if the JSON doesn’t match exactly what Jackson is looking for; for example, the main JSON could be wrapped as in the following example:

@Test(expected = JsonMappingException.class)
public void givenWrappedJsonString_whenDeserializing_thenException()
  throws IOException {
    String json = "{\"user\":{\"id\":1,\"name\":\"John\"}}";

    ObjectMapper mapper = new ObjectMapper();
    mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);

    mapper.reader().withType(User.class).readValue(json);
}

The full exception is:

com.fasterxml.jackson.databind.JsonMappingException:
Root name 'user' does not match expected ('User') for type
 [simple type, class org.baeldung.jackson.dtos.User]
 at [Source: {"user":{"id":1,"name":"John"}}; line: 1, column: 2]
	at c.f.j.d.JsonMappingException.from(JsonMappingException.java:148)

4.2. The Solution

We can solve this problem using the annotation @JsonRootName – as in the following example:

@JsonRootName(value = "user")
public class UserWithRoot {
    public int id;
    public String name;
}

When we try to deserialize the wrapped JSON – it works correctly:

@Test
public void givenWrappedJsonStringAndConfigureClass_whenDeserializing_thenCorrect() 
  throws IOException {
    String json = "{\"user\":{\"id\":1,\"name\":\"John\"}}";

    ObjectMapper mapper = new ObjectMapper();
    mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);

    UserWithRoot user = mapper.reader()
                              .withType(UserWithRoot.class)
                              .readValue(json);
    assertEquals("John", user.name);
}

5. JsonMappingException: No serializer found for class

5.1. The Problem

Now – let’s take a look at JsonMappingException: No serializer found for class.

This exception is thrown if you try to serialize an instance while its properties and their getters are private.

In the following example – we try to serialize a “UserWithPrivateFields“:

public class UserWithPrivateFields {
    int id;
    String name;
}

When we try to serialize an instance of “UserWithPrivateFields” – an Exception “JsonMappingException: No serializer found for class” is thrown as in the following example:

@Test(expected = JsonMappingException.class)
public void givenClassWithPrivateFields_whenSerializing_thenException() 
  throws IOException {
    UserWithPrivateFields user = new UserWithPrivateFields(1, "John");

    ObjectMapper mapper = new ObjectMapper();
    mapper.writer().writeValueAsString(user);
}

The full exception is:

com.fasterxml.jackson.databind.JsonMappingException: 
No serializer found for class org.baeldung.jackson.exception.UserWithPrivateFields
 and no properties discovered to create BeanSerializer 
(to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) )
	at c.f.j.d.ser.impl.UnknownSerializer.failForEmpty(UnknownSerializer.java:59)

5.2. The Solution

We can solve this problem by configuring the ObjectMapper visibility – as in the following example:

@Test
public void givenClassWithPrivateFields_whenConfigureSerializing_thenCorrect() 
  throws IOException {
    UserWithPrivateFields user = new UserWithPrivateFields(1, "John");

    ObjectMapper mapper = new ObjectMapper();
    mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);

    String result = mapper.writer().writeValueAsString(user);
    assertThat(result, containsString("John"));
}

Or using the annotation @JsonAutoDetect – as in the following example:

@JsonAutoDetect(fieldVisibility = Visibility.ANY)
public class UserWithPrivateFields { ... }

Of course, if we do have the option to modify the source of the class, we can also add in getters for Jackson to use.

6. JsonMappingException: Can not deserialize instance of

6.1. The Problem

Next – let’s take a look at JsonMappingException: Can not deserialize instance of.

This exception is thrown if the wrong type is used while deserializing.

In the following example – we are trying to deserialize a List of User:

@Test(expected = JsonMappingException.class)
public void givenJsonOfArray_whenDeserializing_thenException() 
  throws JsonProcessingException, IOException {
    String json = 
    "[{\"id\":1,\"name\":\"John\"},{\"id\":2,\"name\":\"Adam\"}]";
    ObjectMapper mapper = new ObjectMapper();
    mapper.reader().withType(User.class).readValue(json);
}

The full exception is:

com.fasterxml.jackson.databind.JsonMappingException:
Can not deserialize instance of org.baeldung.jackson.dtos.User out of START_ARRAY token
 at [Source: [{"id":1,"name":"John"},{"id":2,"name":"Adam"}]; line: 1, column: 1]
	at c.f.j.d.JsonMappingException.from(JsonMappingException.java:148)

6.2. The Solution

We can solve this problem by changing the type from User to List<User> – as in the following example:

@Test
public void givenJsonOfArray_whenDeserializing_thenCorrect() 
  throws JsonProcessingException, IOException {
    String json = 
    "[{\"id\":1,\"name\":\"John\"},{\"id\":2,\"name\":\"Adam\"}]";
   
    ObjectMapper mapper = new ObjectMapper();
    List<User> users = 
      mapper.reader()
            .withType(new TypeReference<List<User>>() {})
            .readValue(json);

    assertEquals(2, users.size());
}

7. UnrecognizedPropertyException

7.1. The Problem

Now – let’s see the UnrecognizedPropertyException.

This exception is thrown if there is an unknown property in the JSON String while deserializing.

In the following example – we try to deserialize a JSON String with extra property “checked“:

@Test(expected = UnrecognizedPropertyException.class)
public void givenJsonStringWithExtra_whenDeserializing_thenException() 
  throws IOException {
    String json = "{\"id\":1,\"name\":\"John\", \"checked\":true}";

    ObjectMapper mapper = new ObjectMapper();
    mapper.reader().withType(User.class).readValue(json);
}

The full exception is:

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:
Unrecognized field "checked" (class org.baeldung.jackson.dtos.User),
 not marked as ignorable (2 known properties: "id", "name"])
 at [Source: {"id":1,"name":"John", "checked":true}; line: 1, column: 38]
 (through reference chain: org.baeldung.jackson.dtos.User["checked"])
	at c.f.j.d.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:51)

7.2. The Solution

We can solve this problem by configuring the ObjectMapper – as in the following example:

@Test
public void givenJsonStringWithExtra_whenConfigureDeserializing_thenCorrect() 
  throws IOException {
    String json = "{\"id\":1,\"name\":\"John\", \"checked\":true}";

    ObjectMapper mapper = new ObjectMapper();
    mapper.disable
      (DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

    User user = mapper.reader().withType(User.class).readValue(json);
    assertEquals("John", user.name);
}

Or we can use the annotation @JsonIgnoreProperties:

@JsonIgnoreProperties(ignoreUnknown = true)
public class User {...}

8. JsonParseException: Unexpected character (”’ (code 39))

8.1. The Problem

Next – let’s discuss JsonParseException: Unexpected character (”’ (code 39)).

This exception is thrown if the JSON String to be deserialized contains single quotes instead of double quotes.

In the following example – we try to deserialize a JSON String containing single quotes:

@Test(expected = JsonParseException.class)
public void givenStringWithSingleQuotes_whenDeserializing_thenException() 
  throws JsonProcessingException, IOException {
    String json = "{'id':1,'name':'John'}";
    ObjectMapper mapper = new ObjectMapper();

    mapper.reader().withType(User.class).readValue(json);
}

The full exception is:

com.fasterxml.jackson.core.JsonParseException:
Unexpected character (''' (code 39)): was expecting double-quote to start field name
 at [Source: {'id':1,'name':'John'}; line: 1, column: 3]
	at c.f.j.core.JsonParser._constructError(JsonParser.java:1419)

8.2. The Solution

We can solve this by configuring the ObjectMapper to allow single quotes:

@Test
public void givenStringWithSingleQuotes_whenConfigureDeserializing_thenCorrect() 
  throws JsonProcessingException, IOException {
    String json = "{'id':1,'name':'John'}";

    JsonFactory factory = new JsonFactory();
    factory.enable(JsonParser.Feature.ALLOW_SINGLE_QUOTES);
    ObjectMapper mapper = new ObjectMapper(factory);

    User user = mapper.reader().withType(User.class)
                               .readValue(json);
    assertEquals("John", user.name);
}

9. Jackson NoSuchMethodError

Finally – let’s quickly discuss the Jackson “No such method” errors.

When java.lang.NoSuchMethodError Exception is thrown, it is usually because you have multiple (and incompatible) versions of Jackson jars on your classpath.

The full exception is:

java.lang.NoSuchMethodError:
com.fasterxml.jackson.core.JsonParser.getValueAsString()Ljava/lang/String;
 at c.f.j.d.deser.std.StringDeserializer.deserialize(StringDeserializer.java:24)

10. Conclusion

In this article, we did a deep dive in the most common Jackson problems – exceptions and errors, looking at the potential causes and at the solutions for each one.

The implementation of all these examples and code snippets can be found in my github project – this is an Eclipse based project, so it should be easy to import and run as it is.

I usually post about Jackson and JSON stuff on Google+ - you can follow me there:

 

Top 10 Articles on Baeldung from 2014

$
0
0

Here are the most read articles on the site written in 2014 (as well as the number of visits):

1#: Http Message Converters with the Spring Framework ~40K

2#: HttpClient Basic Authentication ~24K

3#Jackson – Custom Deserializer ~18K

4#Jackson – Custom Serializer ~16K

5#: HttpClient – Set Custom Header ~9K

6#Java InputStream to String ~9K

7#Hibernate Pagination ~7K

8#Multipart Upload with HttpClient 4 ~7K

9#: HttpClient Connection Management ~6K

10#: The Registration Process With Spring Security ~5K

Make sure you didn’t miss any.

Baeldung Weekly Review 51

$
0
0

I usually post about Dev stuff on Google+ - you can follow me there:

At the very beginning of 2014 I decided to track my reading habits and share the best stuff here, on Baeldung.

2014 has been quite the year, covering each week with a review. I’ve been doing a lot more reading to make sure I cover and curate stuff that has value and is actually interesting.

Let me know in the comments if you’re finding my reviews interesting and useful.

Here we go…

1. Java and Spring

>> Java Past, Present, and Future

The Java ecosystem is like Sweden? A bit confused by that statement? Yeah – you need to listen to Brian Goetz talk about how the Java language, platform and ecosystem is moving forward.

And if there’s someone that can intelligently speak on the subject, it’s Brian Goetz.

If you’re a Java developer – and I assume you are – understanding how the platform is evolving is, while not immediately practical, nevertheless very important.

>> A beginner’s guide to transaction isolation levels in enterprise Java

A well researched and practical guide to transaction isolation levels – something that should be well understood by each and every java developer out there. It’s a good read even if you have a solid grasp on the topic.

>> How to encapsulate Spring bean

Making your beans package private is a very good practice that will allow the system to remain lighter and be understood quickly. It’s a good idea to do this by default and only allow a bean to “escape” its package if it absolutely needs to.

And some very useful webinar recordings:

>> Looking into the Java 9 Money and Currency API (JSR 354)

An good intro to what is definitely an interesting JSR – the Money and Currency API, with lots of code level examples diving into the reference implementation.

>> Rapid prototyping with Spring Boot and AngularJS

An intro to the Spring Boot/AngularJS stack.

>> Apache Maven Version 3.2.5 Released

Bug fixes in Maven are always welcome. Here’s a end of the year release bumping up the version to 3.2.5.

2. Technical and Musings

>> New and Interesting on ThoughtWorks Radar Jan 2015

The ThoughtWorks Radar is always a good source of insight and high level overview of the technical landscape. And while most of what it covers doesn’t directly apply to your work, what does apply is advice worth listening to (check out what they’re saying about microservices).

>> Be the We

Didn’t know what to expect when I started reading this weirdly named piece. Simply put it’s solid advice for having the right kind of mindset when walking into a new gig.

3. Comics

And some Dilbert to get you through the holidays:

>> All I heard was “Give Up”

>> It was my ethical duty to do nothing…

>> The “Goat Head” issue

4. Pick of the Week

Earlier this year I introduced the “Pick of the Week” section here in my “Weekly Review”. If you’re already on my email list – you got the pick already – hope you enjoyed it.

If not – you can share the review and unlock it right here:

This is the last review of 2014 – a bit shorter than usual as I imagine people are spending their holidays doing other things than writing.

And as I mentioned – let me know in the comments if these curated reviews have been useful to you.

I usually post about Dev stuff on Google+ - you can follow me there:

Posting with HttpClient

$
0
0

1. Overview

In this tutorial – we’ll POST with the HttpClient 4 - using first authorization, then the fluent HttpClient API. Finally – we will discuss how to upload File using HttpClient.

2. Basic POST

First – let’s go over a simple example and send a POST request using HttpClient.

In the following example – we will do a POST with two parameters – “username” and “password“:

@Test
public void whenPostRequestUsingHttpClient_thenCorrect() 
  throws ClientProtocolException, IOException {
    CloseableHttpClient client = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost("http://www.example.com");

    List<NameValuePair> params = new ArrayList<NameValuePair>();
    params.add(new BasicNameValuePair("username", "John"));
    params.add(new BasicNameValuePair("password", "pass"));
    httpPost.setEntity(new UrlEncodedFormEntity(params));

    CloseableHttpResponse response = client.execute(httpPost);
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
    client.close();
}

Note how we used a List of NameValuePair to include parameters in the POST request.

3. POST with Authorization

Next – let’s see how to do a POST with Authentication credentials using the HttpClient.

In the following example – we send a post request to a URL secured with Basic Authentication:

@Test
public void whenPostRequestWithAuthorizationUsingHttpClient_thenCorrect()
  throws ClientProtocolException, IOException, AuthenticationException {
    CloseableHttpClient client = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost("http://www.example.com");

    httpPost.setEntity(new StringEntity("test post"));
    UsernamePasswordCredentials creds = 
      new UsernamePasswordCredentials("John", "pass");
    httpPost.addHeader(new BasicScheme().authenticate(creds, httpPost, null));

    CloseableHttpResponse response = client.execute(httpPost);
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
    client.close();
}

4. POST with JSON

Now – let’s see how to send POST request with a JSON body using the HttpClient.

In the following example – we’re sending some person information (id, name) as JSON:

@Test
public void whenPostJsonUsingHttpClient_thenCorrect() 
  throws ClientProtocolException, IOException {
    CloseableHttpClient client = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost("http://www.example.com");

    String json = "{\"id\":1,\"name\":\"John\"}";
    StringEntity entity = new StringEntity(json);
    httpPost.setEntity(entity);
    httpPost.setHeader("Accept", "application/json");
    httpPost.setHeader("Content-type", "application/json");

    CloseableHttpResponse response = client.execute(httpPost);
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
    client.close();
}

Note how we’re using the StringEntity to set the body of the request.

We are also setting the ContentType header to application/json to give the server the necessary information about the representation of the content we’re sending.

5. POST with the HttpClient Fluent API

Next – let’s POST with the HttpClient Fluent API; we’re going to send a request with two parameters “username” and “password“:

@Test
public void whenPostFormUsingHttpClientFluentAPI_thenCorrect() 
  throws ClientProtocolException, IOException {
    HttpResponse response = 
      Request.Post("http://www.example.com").bodyForm(
        Form.form().add("username", "John").add("password", "pass").build())
        .execute().returnResponse();

    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
}

6. POST Multipart Request

Now – let’s POST a Multipart Request – in the following example, we’ll post a File, username and password using MultipartEntityBuilder:

@Test
public void whenSendMultipartRequestUsingHttpClient_thenCorrect() 
  throws ClientProtocolException, IOException {
    CloseableHttpClient client = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost("http://www.example.com");

    MultipartEntityBuilder builder = MultipartEntityBuilder.create();
    builder.addTextBody("username", "John");
    builder.addTextBody("password", "pass");
    builder.addBinaryBody("file", new File("test.txt"),
      ContentType.APPLICATION_OCTET_STREAM, "file.ext");

    HttpEntity multipart = builder.build();
    httpPost.setEntity(multipart);

    CloseableHttpResponse response = client.execute(httpPost);
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
    client.close();
}

7. Upload a File using HttpClient

Next – let’s see how to upload a File using the HttpClient – we’ll upload the “test.txt” file using MultipartEntityBuilder:

@Test
public void whenUploadFileUsingHttpClient_thenCorrect() 
  throws ClientProtocolException, IOException {
    CloseableHttpClient client = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost("http://www.example.com");

    MultipartEntityBuilder builder = MultipartEntityBuilder.create();
    builder.addBinaryBody("file", new File("test.txt"),
      ContentType.APPLICATION_OCTET_STREAM, "file.ext");
    HttpEntity multipart = builder.build();

    httpPost.setEntity(multipart);

    CloseableHttpResponse response = client.execute(httpPost);
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
    client.close();
}

8. Get File Upload Progress

Finally – let’s see how to get the progress of File upload using HttpClient. In the following example – we will extend HttpEntityWrapper to gain visibility into the upload process:

First – here’s the upload method:

@Test
public void whenGetUploadFileProgressUsingHttpClient_thenCorrect()
  throws ClientProtocolException, IOException {
    CloseableHttpClient client = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost("http://www.example.com");

    MultipartEntityBuilder builder = MultipartEntityBuilder.create();
    builder.addBinaryBody("file", new File("test.txt"), 
      ContentType.APPLICATION_OCTET_STREAM, "file.ext");
    HttpEntity multipart = builder.build();

    ProgressEntityWrapper.ProgressListener pListener = 
     new ProgressEntityWrapper.ProgressListener() {
        @Override
        public void progress(float percentage) {
            assertFalse(Float.compare(percentage, 100) > 0);
        }
    };

    httpPost.setEntity(new ProgressEntityWrapper(multipart, pListener));

    CloseableHttpResponse response = client.execute(httpPost);
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
    client.close();
}

And here is the interface ProgressListener that enables us to observe the upload progress:

public static interface ProgressListener {
    void progress(float percentage);
}

And here our extended version of HttpEntityWrapper ProgressEntityWrapper“:

public class ProgressEntityWrapper extends HttpEntityWrapper {
    private ProgressListener listener;

    public ProgressEntityWrapper(HttpEntity entity, 
      ProgressListener listener) {
        super(entity);
        this.listener = listener;
    }

    @Override
    public void writeTo(OutputStream outstream) throws IOException {
        super.writeTo(new CountingOutputStream(outstream, 
          listener, getContentLength()));
    }
}

And the extended version of FilterOutputStreamCountingOutputStream“:

public static class CountingOutputStream extends FilterOutputStream {
    private ProgressListener listener;
    private long transferred;
    private long totalBytes;

    public CountingOutputStream(
      OutputStream out, ProgressListener listener, long totalBytes) {
        super(out);
        this.listener = listener;
        transferred = 0;
        this.totalBytes = totalBytes;
    }

    @Override
    public void write(byte[] b, int off, int len) throws IOException {
        out.write(b, off, len);
        transferred += len;
        listener.progress(getCurrentProgress());
    }

    @Override
    public void write(int b) throws IOException {
        out.write(b);
        transferred++;
        listener.progress(getCurrentProgress());
    }

    private float getCurrentProgress() {
        return ((float) transferred / totalBytes) * 100;
    }
}

Note that:

  • When extending FilterOutputStream to “CountingOutputStream” – we are overriding the write() method to count the written (transferred) bytes
  • When extending HttpEntityWrapper to “ProgressEntityWrapper” – we are overriding the writeTo() method to use ourCountingOutputStream

9. Conclusion

In this tutorial we illustrated the most common ways to send POST HTTP Requests with the Apache HttpClient 4.

We learned how to send post request with Authorization, how to post using HttpClient fluent API and how to upload a file and track its progress.

Jackson Date

$
0
0

I usually post about Jackson and JSON stuff on Google+ - you can follow me there:

1. Overview

In this tutorial, we’ll serialize dates with Jackson. We’ll start by serializing a simple java.util.Date, then Joda-Time as well as the Java 8 DateTime.

2. Serialize Date with Jackson

First – let’s see how to serialize a simple java.util.Date with Jackson.

In the following example – we will serialize an instance of “Event” which has a Date field “eventDate“:

@Test
public void whenSerializingDateWithJackson_thenSerializedToTimestamp()
  throws JsonProcessingException, ParseException {
    SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy hh:mm");
    df.setTimeZone(TimeZone.getTimeZone("UTC"));

    Date date = df.parse("01-01-1970 01:00");
    Event event = new Event("party", date);

    ObjectMapper mapper = new ObjectMapper();
    mapper.writeValueAsString(event);
}

What’s important here is that Jackson will serialize the Date to a timestamp format by default (number of milliseconds since January 1st, 1970, UTC).

The actual output of the “event” serialization is:

{
   "name":"party",
   "eventDate":3600000
}

3. Serialize Date to ISO-8601

Clearly serializing to this terse timestamp format is not optimal. Let’s now serialize the Date to the ISO-8601 format.

If we disable the use of timestamps, ISO-8601 will be automatically used instead as in the following example:

@Test
public void whenSerializingDateToISO8601_thenSerializedToText()
  throws JsonProcessingException, ParseException {
    SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy hh:mm");
    df.setTimeZone(TimeZone.getTimeZone("UTC"));

    String toParse = "01-01-1970 02:30";
    Date date = df.parse(toParse);
    Event event = new Event("party", date);

    ObjectMapper mapper = new ObjectMapper();
    mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);

    String result = mapper.writeValueAsString(event);
    assertThat(result, containsString("1970-01-01T02:30:00.000+0000"));
}

Note how the representation of the date is now much more readable – though maybe not as clean as it could be.

4. Configure ObjectMapper DateFormat

The previous solutions still lack the full flexibility of choosing the exact format to represent the java.util.Date instances.

Let’s now take a look at a configuration that will allow us to set our own formats for representing dates:

@Test
public void whenSettingObjectMapperDateFormat_thenCorrect()
  throws JsonProcessingException, ParseException {
    SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy hh:mm");

    String toParse = "20-12-2014 02:30";
    Date date = df.parse(toParse);
    Event event = new Event("party", date);

    ObjectMapper mapper = new ObjectMapper();
    mapper.setDateFormat(df);

    String result = mapper.writeValueAsString(event);
    assertThat(result, containsString(toParse));
}

Note that, even though we’re now more flexible in terms of the date format – we’re still using a global configuration at the level of the entire ObjectMapper.

5. Use @JsonFormat to format Date

Next, let’s take a look at the @JsonFormat annotation to control the date format on individual classes instead of globally, for the entire application:

public class Event {
    public String name;

    @JsonFormat
      (shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy hh:mm:ss")
    public Date eventDate;
}

Now – let’s test it:

@Test
public void whenUsingJsonFormatAnnotationToFormatDate_thenCorrect()
  throws JsonProcessingException, ParseException {
    SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
    df.setTimeZone(TimeZone.getTimeZone("UTC"));

    String toParse = "20-12-2014 02:30:00";
    Date date = df.parse(toParse);
    Event event = new Event("party", date);

    ObjectMapper mapper = new ObjectMapper();
    String result = mapper.writeValueAsString(event);
    assertThat(result, containsString(toParse));
}

6. Custom Date Serializer

Next – to get full control over the output, we’ll leverage a custom serializer for Dates:

public class CustomDateSerializer extends JsonSerializer<Date> {
    private static SimpleDateFormat formatter = 
      new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");

    @Override
    public void serialize (Date value, JsonGenerator gen, SerializerProvider arg2)
      throws IOException, JsonProcessingException {
        gen.writeString(formatter.format(value));
    }
}

Next – let’s use it as the serializer of our “eventDate” field:

public class Event {
    public String name;

    @JsonSerialize(using = CustomDateSerializer.class)
    public Date eventDate;
}

Finally – let’s test it:

@Test
public void whenUsingCustomDateSerializer_thenCorrect()
  throws JsonProcessingException, ParseException {
    SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");

    String toParse = "20-12-2014 02:30:00";
    Date date = df.parse(toParse);
    Event event = new Event("party", date);

    ObjectMapper mapper = new ObjectMapper();
    String result = mapper.writeValueAsString(event);
    assertThat(result, containsString(toParse));
}

7. Serialize Joda-Time with Jackson

Dates aren’t always an instance of java.util.Date; actually – they’re more and more represented by some other class – and a common one is of course the DateTime implementation from the Joda-Time library.

Let’s see how we can serialize DateTime with Jackson.

We’ll make use of the jackson-datatype-joda module for out of the box Joda-Time support:

<dependency>
  <groupId>com.fasterxml.jackson.datatype</groupId>
  <artifactId>jackson-datatype-joda</artifactId>
  <version>2.4.0</version>
</dependency>

And now we can simply register the JodaModule and be done:

@Test
public void whenSerializingJodaTime_thenCorrect() 
  throws JsonProcessingException {
    DateTime date = new DateTime(2014, 12, 20, 2, 30, 
      DateTimeZone.forID("Europe/London"));

    ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(new JodaModule());
    mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);

    String result = mapper.writeValueAsString(date);
    assertThat(result, containsString("2014-12-20T02:30:00.000Z"));
}

8. Serialize Joda DateTime with Custom Serializer

If we don’t want the extra Joda-Time Jackson dependency – we can also make use of a custom serializer (similar to the earlier examples) to get DateTime instances serialized cleanly:

public class CustomDateTimeSerializer extends JsonSerializer<DateTime> {

    private static DateTimeFormatter formatter = 
      DateTimeFormat.forPattern("yyyy-MM-dd HH:mm");

    @Override
    public void serialize
      (DateTime value, JsonGenerator gen, SerializerProvider arg2)
      throws IOException, JsonProcessingException {
        gen.writeString(formatter.print(value));
    }
}

Next – let’s use it as our property “eventDate” serializer:

public class Event {
    public String name;

    @JsonSerialize(using = CustomDateTimeSerializer.class)
    public DateTime eventDate;
}

Finally – let’s put everything together and test it:

@Test
public void whenSerializingJodaTimeWithJackson_thenCorrect() 
  throws JsonProcessingException {
    DateTime date = new DateTime(2014, 12, 20, 2, 30);
    Event event = new Event("party", date);

    ObjectMapper mapper = new ObjectMapper();
    String result = mapper.writeValueAsString(event);
    assertThat(result, containsString("2014-12-20 02:30"));
}

9. Serialize Java 8 Date with Jackson

Next – let’s see how to serialize Java 8 DateTime - in this example, LocalDateTime – using Jackson. We can make use of the jackson-datatype-jsr310 module:

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>2.4.0</version>
</dependency>

Now, all we need to do is register the JSR310Module and Jackson will take care of the rest:

@Test
public void whenSerializingJava8Date_thenCorrect()
  throws JsonProcessingException {
    LocalDateTime date = LocalDateTime.of(2014, 12, 20, 2, 30);

    ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(new JSR310Module());
    mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);

    String result = mapper.writeValueAsString(date);
    assertThat(result, containsString("2014-12-20T02:30"));
}

10. Serialize Java 8 Date with Jackson

If you don’t want the extra dependency, you can always use a custom serializer to write out the Java 8 DateTime to JSON:

public class CustomLocalDateTimeSerializer 
  extends JsonSerializer<LocalDateTime> {

    private static DateTimeFormatter formatter = 
      DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");

    @Override
    public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider arg2)
      throws IOException, JsonProcessingException {
        gen.writeString(formatter.format(value));
    }
}

Next – let’s use the serializer for our “eventDate” field:

public class Event {
    public String name;

    @JsonSerialize(using = CustomLocalDateTimeSerializer.class)
    public LocalDateTime eventDate;
}

Now – let’s test it:

@Test
public void whenSerializingJava8DateWithCustomSerializer_thenCorrect()
  throws JsonProcessingException {
    LocalDateTime date = LocalDateTime.of(2014, 12, 20, 2, 30);
    Event event = new Event("party", date);

    ObjectMapper mapper = new ObjectMapper();
    String result = mapper.writeValueAsString(event);
    assertThat(result, containsString("2014-12-20 02:30"));
}

11. Deserialize Date

Next – let’s see how to deserialize a Date with Jackson. In the following example – we deserialize an “Event” instance containing a date:

@Test
public void whenDeserializingDateWithJackson_thenCorrect()
  throws JsonProcessingException, IOException {
    String json = "{\"name\":\"party\",\"eventDate\":\"20-12-2014 02:30:00\"}";

    SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
    ObjectMapper mapper = new ObjectMapper();
    mapper.setDateFormat(df);

    Event event = mapper.reader(Event.class).readValue(json);
    assertEquals("20-12-2014 02:30:00", df.format(event.eventDate));
}

12. Custom Date deserializer

Let’s also see how to use a custom Date deserializer; we’ll write a custom deserializer for the property “eventDate“:

public class CustomDateDeserializer extends JsonDeserializer<Date> {

    private static SimpleDateFormat formatter = 
      new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");

    @Override
    public Date deserialize(JsonParser jsonparser, DeserializationContext context)
      throws IOException, JsonProcessingException {
        String date = jsonparser.getText();
        try {
            return formatter.parse(date);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }
}

Next – let’s use it as the “eventDate” deserializer:

public class Event {
    public String name;

    @JsonDeserialize(using = CustomDateDeserializer.class)
    public Date eventDate;
}

And finally – let’s test it:

@Test
public void whenDeserializingDateUsingCustomDeserializer_thenCorrect()
  throws JsonProcessingException, IOException {
    String json = "{\"name\":\"party\",\"eventDate\":\"20-12-2014 02:30:00\"}";

    SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
    ObjectMapper mapper = new ObjectMapper();

    Event event = mapper.reader(Event.class).readValue(json);
    assertEquals("20-12-2014 02:30:00", df.format(event.eventDate));
}

13. Conclusion

In this extensive Date article we looked at most relevant ways Jackson can help marshalling and unmarshall a date to JSON using a sensible format we have control over.

I usually post about Jackson and JSON stuff on Google+ - you can follow me there:

 

Viewing all 3450 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>