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

Conferences in May

$
0
0

After reading the enthusiastic Join me at GeeCON article I was inspired to do a quick writeup about the conferences that are coming up in the month of May.

I’m super excited about May; first off, there’s GeeCON, starting on the 11th and wrapping up on the 13th and then SpringIO in Barcelona, on the 19 and the 20th.

Both of these are fantastic events with a lot of cool talks. But, beyond the talks, it’s the hallway track that I’m psyched about even more. Reading about “the community” in general simply doesn’t compare to being in a room with so many passionate developers.

So, if you’re planning to attend – and I definitely recommend you do – grab me and say hi.

 

Now, here are the talks I’m most excited about – first, from GeeCON:

– Cloud Native Java

– MDD: Metrics Driven Development

– Microservices. Stairway to heaven or highway to hell?

– Microservices tracing with Spring Cloud and Zipkin

– Beyond lambdas – the aftermath

– PrivateEye

– Creating Jenkins pipelines with groovy-based DSL

– Take me on a journey – the next step in automated testing practices

– Building multiplayer game using Reactive Streams

– How to Think, in RxJava, Before Reacting

– Twelve BDD Antipatterns – stories from the trenches about how NOT to do BDD

– Every millisecond counts

– Better living through pull requests

 

And from SpringIO:

– From Spring Framework 4.3 to 5.0

– Designing Applications: The Reactive Way

– 10 ways to get super-productive with Spring Boot

– JUnit 5 – Shaping the Future of Testing on the JVM

– Understanding Microservice Performance

– Testing Spring Boot Applications

– What’s new in Spring Data?

– From Imperative To Reactive

– Test-driven documentation with Spring REST Docs

– Extending Spring Data

– Securing RESTful services with Spring HATEOAS and HDIV

 

A lot of cool stuff that’s going to have an impact over the work I’m going to be doing in 2016.

And of course I’m excited about my own presentations, so definitely join me for that as well.

Yeah, May is going to be fun.


Mockito’s Mock Methods

$
0
0

I just released the Starter Class of "Learn Spring Security":

>> CHECK OUT THE COURSE

1. Overview

This tutorial illustrates various uses of the standard static mock methods of the Mockito API.

As with other articles focused on the Mockito framework (like Mockito Verify or Mockito When/Then), the MyList class shown below will be used as the collaborator to be mocked in test cases:

public class MyList extends AbstractList<String> {
    @Override
    public String get(int index) {
        return null;
    }

    @Override
    public int size() {
        return 1;
    }
}

2. Simple Mocking

The simplest overloaded variant of the mock method is the one with a single parameter for the class to be mocked:

public static <T> T mock(Class<T> classToMock)

We will use this method to mock a class and set an expectation:

MyList listMock = mock(MyList.class);
when(listMock.add(anyString())).thenReturn(false);

Then execute a method on the mock:

boolean added = listMock.add(randomAlphabetic(6));

The following code confirms that the add method has been invoked on the mock, and that the invocation returns a value which matches the expectation we set before:

verify(listMock).add(anyString());
assertThat(added, is(false));

3. Mocking with Mock’s Name

In this section, we will cover another variant of the mock method which is provided with an argument specifying the name of the mock:

public static <T> T mock(Class<T> classToMock, String name)

Generally speaking, the name of a mock has nothing to do with working code, but may be helpful when it comes to debugging, where the mock’s name is used to track down verification errors.

To make sure that the provided name of a mock is included in the message of an exception thrown from an unsuccessful verification, we will rely on a JUnit implementation of the TestRule interface, called ExpectedException, and include it in a test class:

@Rule
public ExpectedException thrown = ExpectedException.none();

This rule will be used to handle exceptions thrown from test methods.

In the following code, we create a mock for the MyList class and name it myMock:

MyList listMock = mock(MyList.class, "myMock");

Afterwards, set an expectation on a method of the mock and execute it:

when(listMock.add(anyString())).thenReturn(false);
listMock.add(randomAlphabetic(6));

We will create an intentionally failed verification that should throw an exception with the message containing information about the mock. In order to do it, expectations on the exception need to be set first:

thrown.expect(TooLittleActualInvocations.class);
thrown.expectMessage(containsString("myMock.add"));

The following verification should fail and throw an exception matching what were expected:

verify(listMock, times(2)).add(anyString());

Here is the thrown exception’s message:

org.mockito.exceptions.verification.TooLittleActualInvocations:
myMock.add(<any>);
Wanted 2 times:
at com.baeldung.mockito.MockitoMockTest
  .whenUsingMockWithName_thenCorrect(MockitoMockTest.java:...)
but was 1 time:
at com.baeldung.mockito.MockitoMockTest
  .whenUsingMockWithName_thenCorrect(MockitoMockTest.java:...)

As we can see, the mock’s name has been included in the exception message, which will be useful to find the failure point in case of an unsuccessful verification.

4. Mocking with Answer

Here, we will demonstrate the use of a mock variant in which the strategy for the mock’s answers to interaction is configured at creation time. This mock method’s signature in the Mockito documentation looks like the following:

public static <T> T mock(Class<T> classToMock, Answer defaultAnswer)

Let’s start with the definition of an implementation of the Answer interface:

class CustomAnswer implements Answer<Boolean> {
    @Override
    public Boolean answer(InvocationOnMock invocation) throws Throwable {
        return false;
    }
}

The CustomAnswer class above is used for the generation of a mock:

MyList listMock = mock(MyList.class, new CustomAnswer());

If we do not set an expectation on a method, the default answer, which was configured by the CustomAnswer type, will come into play. In order to prove it, we will skip over the expectation setting step and jump to the method execution:

boolean added = listMock.add(randomAlphabetic(6));

The following verification and assertion confirm that the mock method with an Answer argument has worked as expected:

verify(listMock).add(anyString());
assertThat(added, is(false));

5. Mocking with MockSettings

The final mock method that is covered within this article is the variant with a parameter of the MockSettings type. This overloaded method is use to provide a non-standard mock.

There are several custom settings that are supported by methods of the MockSettings interface, such as registering a listener for method invocations on the current mock with invocationListeners, configuring serialization with serializable, specifying the instance to spy on with spiedInstance, configuring Mockito to attempt to use a constructor when instantiating a mock with useConstructor, and some others.

For the convenience, we will reuse the CustomAnswer class introduced in the previous section to create a MockSettings implementation that defines a default answer.

A MockSettings object is instantiated by a factory method as follows:

MockSettings customSettings = withSettings().defaultAnswer(new CustomAnswer());

That setting object will be used in the creation of a new mock:

MyList listMock = mock(MyList.class, customSettings);

Similar to the preceding section, we will invoke the add method of a MyList instance and verify that a mock method with a MockSettings argument works as it is meant to by using the following code snippet:

boolean added = listMock.add(randomAlphabetic(6));
verify(listMock).add(anyString());
assertThat(added, is(false));

6. Conclusion

This tutorial has covered the mock method of Mockito in detail. The implementation of these examples and code snippets can be found in a GitHub project.

Get the early-bird price (20% Off) of my upcoming "Learn Spring Security" Course:

>> CHECK OUT THE COURSE

Java Web Weekly, Issue 123

$
0
0

I just released the Starter Class of "Learn Spring Security":

>> CHECK OUT THE COURSE

At the very beginning of last year, I decided to track my reading habits and share the best stuff here, on Baeldung. Haven’t missed a review since.

Here we go…

1. Spring and Java

>> FizzBuzz Kata With Java Streams [securesoftwaredev.com]

“Practicing means slowing down” – very nicely put.

This is a step by step Kata of a well known problem, using some Java 8 goodness.

>> The best way of logging JDBC statements [vladmihalcea.com]

Some cool techniques to set up logging in a Hibernate system or right around the data source.

This one falls in the category – “didn’t know you could do that”.

>> What’s new in Spring Data Hopper? [spring.io]

Some really cool stuff in this latest Spring Data release.

I’m especially interested in the Querydsl stuff – looks like I have something to play with this weekend.

Projections also look like they’re going to really come in handy in some scenarios.

>> Using Java Generics to express variance of Collections and Functions [advancedweb.hu]

Playing with generics is always fun, especially when you sprinkle some Java 8 syntax on top.

>> Laziness at extreme: developing JAX-RS services with Spring Boot [aredko.com]

A quick and fun way of using Boot outside the core Spring ecosystem.

Also worth reading:

Webinars and presentations:

Time to upgrade:

2. Technical

>> The Benefits of Hypermedia APIs [olivergierke.de]

If you’ve been following Baeldung for any amount of time, you know Hypermedia APIs are one of my favorite topics. So I was excited to see this writeup pop up in my RSS feed.

Yeah – go read this one.

>> Locating Common Micro Service Performance Anti-Patterns [infoq.com]

A solid overview of the common things that can go wrong in a microservice architecture.

Some of these aren’t microservice specific, but the ones that are definitely paint a clear picture of the extra complexity in this kind of system.

>> Microservices are about applying a group of Best Practices [vanillajava.blogspot.com]

Moving an existing codebase to a microservice architecture is no small feat. And that’s not even taking into account the non-technical challenges.

We definitely need more nuanced strategies based on actual production experience with microservices to help drive these architectural decisions.

Also worth reading:

3. Musings

>> Hiring is Broken… And It Isn’t Worth Fixing [daedtech.com]

An insightful read on how the hiring process isn’t looking at the right things.

It’s also long enough to fit three cool cartoons 🙂

The interesting thing is that I’ve read about at least two companies trying to take on the challenge just this week – both with non-traditional, depth vs width approaches. So maybe there’s hope.

>> Breach concealment is not a security strategy [troyhunt.com]

If you find security news and musings about the right way to handle a data breach interesting – then this is certainly worth reading.

>> Email: how to be polite and efficient [lemire.me]

The more email I get, the more I think that writing good email is a black art. This quick writeup has some useful rules to live by when writing that email.

>> Applied Consultant Taxonomy to Prevent Confusion [daedtech.com]

More nuanced and practical examples of how scoping and defining different roles is important, and “consultant” really isn’t enough.

Also worth reading:

4. Comics

And my favorite Dilberts of the week:

>> I’ll sweet your dumb tweets off to the side [dilbert.com]

>> Buy our monthly subscription or I’ll send your browser history to your contacts [dilbert.com]

>> Should have kept that thought bottled up [dilbert.com]

5. Pick of the Week

>> Hacking is Important [medium.com]

Get the early-bird price (20% Off) of my upcoming "Learn Spring Security" Course:

>> CHECK OUT THE COURSE

Spring HTTP/HTTPS Channel Security

$
0
0

I just released the Starter Class of "Learn Spring Security":

>> CHECK OUT THE COURSE

1. Overview

This tutorial shows how to use HTTPS to protect your application’s login page using Spring’s Channel Security feature.

Using HTTPS for authentication is crucial to protect the integrity of sensitive data when in transport.

The article builds on top of the Spring Security Login tutorial by adding an additional layer of security. We highlight the steps needed to secure the authentication data by serving the login page through the encoded HTTPS channel.

2. Initial Setup Without Channel Security

Let’s start out with the security configuration explained in the aforementioned article.

The web-app allows users to access:

  1. /anonymous.html without authentication,
  2. /login.html, and
  3. other pages (/homepage.html) after a successful login.

The access is controlled by the following configuration:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests() 
      .antMatchers("/anonymous*")
      .anonymous();

    http.authorizeRequests()
      .antMatchers("/login*")
      .permitAll();

    http.authorizeRequests()
      .anyRequest()
      .authenticated();

Or via XML:

<http use-expressions="true">
    <intercept-url pattern="/anonymous*" access="isAnonymous()"/>
    <intercept-url pattern="/login*" access="permitAll"/>
    <intercept-url pattern="/**" access="isAuthenticated()"/>
</http>

At this point, the login page is available at:

http://localhost:8080/spring-security-login/login.html

Users are able to authenticate themselves through HTTP, however this is insecure as passwords will be sent in plain text.

3. HTTPS Server Configuration

To only deliver the login page over HTTPS your web-server must be able to serve HTTPS pages. This requires that SSL/TLS support is enabled.

Note that you can either use a valid certificate or, for testing purposes, you can generate your own.

Let’s say we’re using Tomcat and rolling our own certificate. We’ll first need to create a keystore with a self-signed certificate.

Generating the keystore can be done issuing the following command in the terminal:

keytool -genkey -alias tomcat -keyalg RSA -storepass changeit -keypass changeit -dname 'CN=tomcat'

This will create a private a key and a self-signed certificate in the default keystore for your user profile, in your home folder.

The next step is to edit conf/server.xml to make it look like this:

<Connector port="8080" protocol="HTTP/1.1"
   connectionTimeout="20000"
   redirectPort="8443" />

<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
   maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
   clientAuth="false" sslProtocol="TLS"
   keystoreFile="${user.home}/.keystore" keystorePass="changeit" />

The second SSL/TLS <Connector> tag is usually commented out in the config file so uncommenting and adding keystore information is all that is needed. Further information is available in Tomcat’s related documentation.

With the HTTPS configuration in place, the login page can now be served under the following URL as well:

https://localhost:8443/spring-security-login/login.html

Web-servers other than Tomcat would require different but likely similar configuration.

4. Configuring Channel Security

At this point, we are able to serve the login page both under HTTP and HTTPS. This section explains how to mandate the usage of HTTPS.

To require HTTPS for the login page modify your security configuration by adding the following:

http.requiresChannel()
  .antMatchers("/login*").requiresSecure();

Or add the requires-channel=”https” attribute to your XML config:

<intercept-url pattern="/login*" access="permitAll" requires-channel="https"/>

After this point users could login only via HTTPS. All relative links e.g. a forward to /homepage.html will inherit the protocol of the original request and will be served under HTTPS.

When mixing HTTP and HTTPS request inside a single web app, there are additional aspects to be aware of and that require further configuration.

5. Mixing HTTP and HTTPS

From the security perspective, serving all requests under HTTPS is considered a best practice.

When using HTTPS exclusively is not an option, we can configure Spring to use HTTP by appending the following to the config:

http.requiresChannel()
  .anyRequest().requiresInsecure();

Or add requires-channel=”http” attributes to the XML:

<intercept‐url pattern="/**" access="isAuthenticated()" requires‐channel="http"/>

This instructs Spring to use HTTP for all requests that are not explicitely configured to use HTTPS, but at the same time it breaks the original login mechanism. The following sections explain the underlying cause.

5.1. A Custom Login Processing URL over HTTPS

The security configuration in the original security tutorial contains the following:

<form-login login-processing-url="/perform_login"/>

Without forcing /perform_login to use HTTPS a redirect would happen to the HTTP variant of it, losing the login information sent with the original request.

To overcome this we need to configure Spring to use HTTPS for the processing URL:

http.requiresChannel()
  .antMatchers("/login*", "/perform_login");

Notice the extra argument /perform_login passed to the antMatchers method.

The equivalent in the XML configuration requires adding a new <intercept-url> element to the config:

<intercept-url pattern="/perform_login" requires-channel="https"/>

If your own application is using the default login-processing-url (which is /login) you don’t need to configure this explicitly as the /login* pattern already covers that.

With the configuration in place, users are able to login, but are not able access authenticated pages e.g. /homepage.html under the HTTP protocol, because of Spring’s session fixation protection feature.

5.2. Disabling session-fixation-protection

Session fixation is a problem which can’t be avoided when switching between HTTP and HTTPS.

By default Spring creates a new session-id after a successful login. When a user loads the HTTPS login page the user’s session-id cookie will be marked as secure. After logging in, the context will switch to HTTP and the cookie will be lost as HTTP is insecure.

To avoid this setting session-fixation-protection to none is required.

http.sessionManagement()
  .sessionFixation()
  .none();

Or via XML:

<session-management session-fixation-protection="none"/>

Disabling session fixation protection might have security implications, therefore you need to weigh the pros and cons if you’re concerned about session fixation based attacks.

6. Test

After applying all these configuration changes accessing /anonymous.html without logging in (using either http:// or https://) will forward you to the page through HTTP.

Opening other pages directly like /homepage.html should get you forwarded to the login page via HTTPS and after login you will be forwarded back to /homepage.html using HTTP.

7. Conclusion

In this tutorial we’ve taken a look on how to configure a Spring web-application which communicates through HTTP except for the login mechanism. However new modern web-applications should almost always use HTTPS exclusively as their communication protocol. Lowering security levels or turning off security features (like session-fixation-protection) is never a good idea.

This tutorial and the one it is based on shares the same codebase which is available at GitHub. The channel security configuration can be enabled by listing https as an active Spring profile.

Get the early-bird price (20% Off) of my upcoming "Learn Spring Security" Course:

>> CHECK OUT THE COURSE

Java Web Weekly, Issue 124

$
0
0

I just released the Starter Class of "Learn Spring Security":

>> CHECK OUT THE COURSE

At the very beginning of last year, I decided to track my reading habits and share the best stuff here, on Baeldung. Haven’t missed a review since.

Here we go…

1. Spring and Java

>> JUnit 5 – Conditions [codefx.org]

Conditions and better control over the execution of tests are solid steps forward in the JUnit ecosystem – can’t wait to get my hands on the new syntax.

>> Reducing boilerplate code with Project Lombok [codecentric.de]

A quick intro to the foundations of Lombock to get rid of some of the more verbose parts of Java.

>> java.util.Optional – Short Tutorial By Example [javaspecialists.eu]

We’ve seen many introductions to Optional since it came out. I’ve covered some in these weekly reviews over that time. This one is as good as any and it has a solid video as well – so if you’re not yet using Optional well, have a look.

>> The Top 100 Java Libraries in 2016 – After Analyzing 47,251 Dependencies [takipi.com]

A very cool breakdown and high level view of what’s going with the libraries in the Java ecosystem.

Also worth reading:

Webinars and presentations:

Time to upgrade:

2. Technical

>> 5 Ways to NOT F**K Up Your Microservices in Production [takipi.com]

More practical and realistic writeups about working in a microservice architecture are getting published than before.

This one is simple and to the point, but it does a good job illustrating a clear fact – microservices do come with a real cost and extra complexity.

Also worth reading:

3. Musings

>> A Manager’s Guide to Legacy Code [daedtech.com]

Working with legacy code is a necessary evil – and this writeup tries to frame what that works entails for the developer tasked to do it.

>> Github and Code Review: A Quiet Revolution [daedtech.com]

Sometimes it’s important to take a step back and have a look at broad strokes of the industry. Especially if you’re heads down in that industry and most of these new workflows are second nature to you.

That’s the direction of this writeup – a step back and a look at what’s been happening.

>> The New 10-Year Vesting Schedule [zachholman.com]

Some realities that are well worth understanding before taking a job at a startup.

Also worth reading:

4. Comics

And my favorite Dilberts of the week:

>> I feel good about next year [dilbert.com]

>> All I could get is fake buy-in [dilbert.com]

>> This stain is fudge [dilbert.com]

5. Pick of the Week

Some fun with giraffes:

>> 5 mètres 80 (video) [vimeo.com]

Get the early-bird price (20% Off) of my upcoming "Learn Spring Security" Course:

>> CHECK OUT THE COURSE

Intro to WebSockets with Spring

$
0
0

I just released the Starter Class of "Learn Spring Security":

>> CHECK OUT THE COURSE

1. Overview

In this article we will create a simple web application that implements messaging using the new WebSocket capabilities introduced with Spring Framework 4.0.

WebSockets are a bi-directional, full-duplex, persistent connection between a web browser and a server. Once a WebSocket connection is established the connection stays open until the client or server decides to close this connection.

A typical use case could be when an app involves multiple users communicating with each other, like in a chat. We will build a simple chat client in our example.

2. Maven Dependencies

Since this is a Maven-based project, we first add the required dependencies to the pom.xml:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-websocket</artifactId>
    <version>4.2.4.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-messaging</artifactId>
    <version>4.2.4.RELEASE</version>
</dependency>

In addition, as we’ll use JSON to build the body of our messages, we need to add the Jackson dependencies. This allow Spring to convert our Java object to / from JSON:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.7.3</version>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId> 
    <version>2.7.3</version>
</dependency>

If you want to get the newest version of the libraries above, look for them on Maven Central.

3. Enable WebSocket in Spring

The first thing to do is to enable the WebSocket capabilities. To do this we need to add a configuration to our application and annotate this class with @EnableWebSocketMessageBroker. As its name suggests, it enables WebSocket message handling, backed by a message broker:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic");
        config.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
         registry.addEndpoint("/chat").withSockJS();
    }
}

Here can we see that the method configureMessageBroker is used to configure the message broker. First, we enable an in-memory message broker to carry the messages back to the client on destinations prefixed with “/topic”.

We complete our simple configuration by designating the “/app” prefix to filter destinations targeting application annotated methods (via @MessageMapping).

The registerStompEndpoints method registers the “/chat” endpoint, enabling Spring’s STOMP support.

This endpoint, when prefixed with “/app”, is the endpoint that the ChatController.send() method is mapped to handle.

It also enables the SockJS fallback options, so that alternative messaging options may be used if WebSockets are not available. This is useful since WebSocket is not supported in all browsers yet and may be precluded by restrictive network proxies. The fallbacks let the applications use a WebSocket API, but gracefully degrade to non-WebSocket alternatives when necessary at runtime.

4. Create the Message Model

Now that we’ve set up the project and configured the WebSocket capabilities, we need to create a message to send.

The endpoint will accept messages containing the sender name and a text in a STOMP message whose body is a JSON object. The message might look like this:

{
    "from": "John",
    "text": "Hello!"
}

To model the message carrying the text,  we can create a simple Java object with from and text properties:

public class Message {

    private String from;
    private String text;

    // getters and setters
}

By default, Spring will use the Jackson library to convert our model object to and from JSON.

5. Create a Message-Handling Controller

As we’ve seen, Spring’s approach to working with STOMP messaging is to associate a controller method to the configured endpoint. This is made possible through the @MessageMapping annotation.

The association between the endpoint and the controller gives us the ability to handle the message, if needed:

@MessageMapping("/chat")
@SendTo("/topic/messages")
public OutputMessage send(Message message) throws Exception {
    String time = new SimpleDateFormat("HH:mm").format(new Date());
    return new OutputMessage(message.getFrom(), message.getText(), time);
}

For the purposes of our example, we’ll create another model object named OutputMessage to represent the output message sent to the configured destination. We populate our object with the sender and the message text taken from the incoming message and enrich it with a timestamp.

After handling our message, we send it to the appropriate destination defined with the @SendTo annotation. All subscribers to the “/topic/messages” destination will receive the message.

6. Create a Browser Client

After making our configurations in the server-side, we’ll use the sockjs-client library to build a simple HTML page that interact with our messaging system.

First of all, we need to import the sockjs and stomp Javascript client libraries. Next, we can create a connect() function to open the communication with our endpoint, a sendMessage() function to send our STOMP message and a disconnect() function to close the communication:

<html>
    <head>
        <title>Chat WebSocket</title>
        <script src="./js/sockjs-0.3.4.js"></script>
        <script src="./js/stomp.js"></script>
        <script type="text/javascript">
            var stompClient = null;
            
            function setConnected(connected) {
                document.getElementById('connect').disabled = connected;
                document.getElementById('disconnect').disabled = !connected;
                document.getElementById('conversationDiv').style.visibility 
                  = connected ? 'visible' : 'hidden';
                document.getElementById('response').innerHTML = '';
            }
            
            function connect() {
                var socket = new SockJS('/spring-mvc-java/chat');
                stompClient = Stomp.over(socket);  
                stompClient.connect({}, function(frame) {
                    setConnected(true);
                    console.log('Connected: ' + frame);
                    stompClient.subscribe('/topic/messages', function(messageOutput) {
                        showMessageOutput(JSON.parse(messageOutput.body));
                    });
                });
            }
            
            function disconnect() {
                if(stompClient != null) {
                    stompClient.disconnect();
                }
                setConnected(false);
                console.log("Disconnected");
            }
            
            function sendMessage() {
                var from = document.getElementById('from').value;
                var text = document.getElementById('text').value;
                stompClient.send("/app/chat", {}, 
                  JSON.stringify({'from':from, 'text':text}));
            }
            
            function showMessageOutput(messageOutput) {
                var response = document.getElementById('response');
                var p = document.createElement('p');
                p.style.wordWrap = 'break-word';
                p.appendChild(document.createTextNode(messageOutput.from + ": " 
                  + messageOutput.text + " (" + messageOutput.time + ")"));
                response.appendChild(p);
            }
        </script>
    </head>
    <body onload="disconnect()">
        <div>
            <div>
                <input type="text" id="from" placeholder="Choose a nickname"/>
            </div>
            <br />
            <div>
                <button id="connect" onclick="connect();">Connect</button>
                <button id="disconnect" disabled="disabled" onclick="disconnect();">
                    Disconnect
                </button>
            </div>
            <br />
            <div id="conversationDiv">
                <input type="text" id="text" placeholder="Write a message..."/>
                <button id="sendMessage" onclick="sendMessage();">Send</button>
                <p id="response"></p>
            </div>
        </div>

    </body>
</html>

7. Testing the Example

To test our example, we can open a couple of browser windows and access the chat page at:

http://localhost:8080/spring-mvc-java/resources/chat.html

Once this is done, we can join the chat by entering a nickname and hitting the connect button. If we compose and send a message we can see it in all browser sessions that have joined the chat.

Take a look at the screenshot to see an example:

screenshot

8. Conclusion

In this tutorial we have explored Spring’s WebSocket support. We have seen its server side configuration and built a simple client side counterpart with the use of sockjs and stomp Javascript libraries.

The example code can be found in the GitHub project.

Get the early-bird price (20% Off) of my upcoming "Learn Spring Security" Course:

>> CHECK OUT THE COURSE

Returning Image/Media Data with Spring MVC

$
0
0

I just released the Starter Class of "Learn Spring Security":

>> CHECK OUT THE COURSE

1. Overview

In this tutorial, we’ll illustrate how to return images and other media using the Spring MVC framework.

We will discuss several approaches, starting from directly manipulating HttpServletResponse than moving to approaches that benefit from Message ConversionContent Negotiation and Spring’s Resource abstraction. We’ll take a closer look on each of them and discuss their advantages and disadvantages.

2. Using the HttpServletResponse

The most basic approach of the image download is to directly work against a response object and mimic a pure Servlet implementation, and its demonstrated using the following snippet:

@RequestMapping(value = "/image-manual-response", method = RequestMethod.GET)
public void getImageAsByteArray(HttpServletResponse response) throws IOException {
    InputStream in = servletContext.getResourceAsStream("/WEB-INF/images/image-example.jpg");
    response.setContentType(MediaType.IMAGE_JPEG_VALUE);
    IOUtils.copy(in, response.getOutputStream());
}

Issuing the following request will render the image in a browser:

http://localhost:8080/spring-mvc-xml/image-manual-response.jpg

The implementation is fairly straightforward and simple owing to IOUtils from the org.apache.commons.io package. However, the disadvantage of the approach is that its not robust against the potential changes. The mime type is hard-coded and the change of the conversion logic or externalizing the image location requires changes to the code.

The following section discusses a more flexible approach.

3. Using the HttpMessageConverter

The previous section discussed a basic approach that does not take advantage of the Message Conversion and Content Negotiation features of the Spring MVC Framework. To bootstrap these feature we need to:

  • Annotate the controller method with the @ResponseBody annotation
  • Register an appropriate message converter based on the return type of the controller method (ByteArrayHttpMessageConverter for example needed for correct conversion of bytes array to an image file)

3.1. Configuration

For showcasing the configuration of the converters, we will use the built-in ByteArrayHttpMessageConverter that converts a message whenever a method returns the byte[] type.

The ByteArrayHttpMessageConverter is registered by default, but the configuration is analogous for any other built-in or custom converter.

Applying the message converter bean requires registering an appropriate MessageConverter bean inside Spring MVC context and setting up media types that it should handle. You can define it via XML, using <mvc:message-converters> tag.

This tag should be defined inside <mvc:annotation-driven> tag, like in the following example:

<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter">
            <property name="supportedMediaTypes">
                <list>
                    <value>image/jpeg</value>
                    <value>image/png</value>
                </list>
            </property>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

Aforementioned configuration part will register ByteArrayHttpMessageConverter for image/jpeg and image/png response content types. If <mvc:message-converters> tag is not present in the mvc configuration, then the default set of converters will be registered.

Also, you can register the message converter using Java configuration:

@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    converters.add(byteArrayHttpMessageConverter());
}

@Bean
public ByteArrayHttpMessageConverter byteArrayHttpMessageConverter() {
    ByteArrayHttpMessageConverter arrayHttpMessageConverter = new ByteArrayHttpMessageConverter();
    arrayHttpMessageConverter.setSupportedMediaTypes(getSupportedMediaTypes());
    return arrayHttpMessageConverter;
}

private List<MediaType> getSupportedMediaTypes() {
    List<MediaType> list = new ArrayList<MediaType>();
    list.add(MediaType.IMAGE_JPEG);
    list.add(MediaType.IMAGE_PNG);
    list.add(MediaType.APPLICATION_OCTET_STREAM);
    return list;
}

3.2. Implementation

Now we can implement our method that will handle requests for media. As it was mentioned above, you need to mark your controller method with the @ResponseBody annotation and use byte[] as the returning type:

@RequestMapping(value = "/image-byte-array", method = RequestMethod.GET)
public @ResponseBody byte[] getImageAsByteArray() throws IOException {
    InputStream in = servletContext.getResourceAsStream("/WEB-INF/images/image-example.jpg");
    return IOUtils.toByteArray(in);
}

To test the method, issue the following request in your browser:

http://localhost:8080/spring-mvc-xml/image-byte-array.jpg

On the advantage side, the method knows nothing about the HttpServletResponse, the conversion process is highly configurable, ranging from using the available converters to specifying a custom one. The content type of the response does not have to be hard-coded rather it will be negotiated based on the request path suffix .jpg.

The disadvantage of this approach is that you need to explicitly implement the logic for retrieving image from a data source (local file, external storage, etc.) and you don’t have a control over the headers or the status code of the response.

4. Using the ResponseEntity Class

You can return an image as byte[] wrapped in the Response Entity. Spring MVC ResponseEntity enables control not only over the body of the HTTP Response but also the header and the respose status code. Following this approach, you need to define the return type of the method as ResponseEntity<byte[]> and create returning ResponseEntity object in the method body.

@RequestMapping(value = "/image-response-entity", method = RequestMethod.GET)
public ResponseEntity<byte[]> getImageAsResponseEntity() {
    HttpHeaders headers = new HttpHeaders();
    InputStream in = servletContext.getResourceAsStream("/WEB-INF/images/image-example.jpg");
    byte[] media = IOUtils.toByteArray(in);
    headers.setCacheControl(CacheControl.noCache().getHeaderValue());
    
    ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(media, headers, HttpStatus.OK);
    return responseEntity;
}

Using the ResponseEntity allows you to configure a response code for a given request.

Explicitly setting the response code is especially useful in the face of an exceptional event e.g. if the image was not found (FileNotFoundException) or is corrupted (IOException). In these cases all that is needed is setting the response code e.g. new ResponseEntity<>(null, headers, HttpStatus.NOT_FOUND), in an adequate catch block.

In addition, if you need to set some specific headers in your response, this approach is more straightforward than setting headers by means of HttpServletResponse object that is accepted by the method as a parameter. It makes the method signature clear and focused.

5. Returning Image Using the Resource Class

Finally, you can return an image in the form of the Resource object.

The Resource interface is an interface for abstracting access to low-level resources. It is introduced in Spring as more capable replacement for the standard java.net.URL class. It allows an easy access to different types of resources (local files, remote files, classpath resources) without need to write a code that explicitly retrieve them.

To use this approach the return type of the method should be set to Resource and you need to annotate the method with the @ResponseBody annotation.

5.1. Implementation

@ResponseBody
@RequestMapping(value = "/image-resource", method = RequestMethod.GET)
public Resource getImageAsResource() {
   return new ServletContextResource(servletContext, "/WEB-INF/images/image-example.jpg");
}

or, if we want more control over the response headers:

@RequestMapping(value = "/image-resource", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<Resource> getImageAsResource() {
    HttpHeaders headers = new HttpHeaders();
    Resource resource = 
      new ServletContextResource(servletContext, "/WEB-INF/images/image-example.jpg");
    return new ResponseEntity<>(resource, headers, HttpStatus.OK);
}

Using this approach, you treat images as resources that can be loaded using the ResourceLoader interface implementation. In such case, you abstract from the exact location of your image and ResourceLoader decides where from it is loaded.

It provides a common approach to control the location of images using the configuration, and eliminate the need for writting file loading code.

6. Conclusion

Among the aforementioned approaches, we started from the basic approach, than using the approach that benefits from message conversion feature of the framework. We also discussed how to get the set the response code and response headers without handing the response object directly.

Finally, we added flexibility from the image locations point of view, because where to retrieve an image from, is defined in the configuration that is easier to change on the fly.

The sample code following the tutorial is available at GitHub.

Get the early-bird price (20% Off) of my upcoming "Learn Spring Security" Course:

>> CHECK OUT THE COURSE

Spring Security – Run-As Authentication

$
0
0

I just released the Starter Class of "Learn Spring Security":

>> CHECK OUT THE COURSE

1. Overview

In this tutorial, we’ll illustrate how to use Run-As authentication in Spring Security with a simple scenario.

The very high level explanation about Run-As is as follows: a user can execute some piece of logic as another principal with different privileges.

2. The RunAsManager

The first thing we’ll need to do is set up our GlobalMethodSecurity and inject a RunAsManager.

This is responsible for providing the temporary Authentication object with extra privileges:

@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
    @Override
    protected RunAsManager runAsManager() {
        RunAsManagerImpl runAsManager = new RunAsManagerImpl();
        runAsManager.setKey("MyRunAsKey");
        return runAsManager;
    }
}

By overriding runAsManager, we’re replacing the default implementation in the base class – which simply returns a null.

Also notice the key property – the framework uses that to secure/verify temporary Authentication objects (created via this manager).

Finally – the resulting Authentication object is a RunAsUserToken.

3. Security Configuration

To authenticate our temporary Authentication object, we’ll set up a RunAsImplAuthenticationProvider:

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    ...
    auth.authenticationProvider(runAsAuthenticationProvider());
}

@Bean
public AuthenticationProvider runAsAuthenticationProvider() {
    RunAsImplAuthenticationProvider authProvider = new RunAsImplAuthenticationProvider();
    authProvider.setKey("MyRunAsKey");
    return authProvider;
}

We’re of course setting this up with the same key we used in the manager – so that the provider can check that the RunAsUserToken authentication object is created using the same key.

4. The Controller With @Secured

Now – let’s see how to use Run-As Authentication replacement:

@Controller
@RequestMapping("/runas")
class RunAsController {

    @Secured({ "ROLE_USER", "RUN_AS_REPORTER" })
    @RequestMapping
    @ResponseBody
    public String tryRunAs() {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        return "Current User Authorities inside this RunAS method only " + 
          auth.getAuthorities().toString();
    }

}

The core thing here is the new role – RUN_AS_REPORTER. This is the trigger of the Run-As functionality – as the framework deals with it differently because of the prefix.

When a request executes through this logic, we’ll have:

 

  • The current user authorities before tryRunAs() method are [ROLE_USER]
  • The current user authorities inside tryRunAs() method are [ROLE_USER, ROLE_RUN_AS_REPORTER]
  • The temporary Authentication object replaces the existing Authentication object for the duration of the tryRunAS() method invocation only

 

5. The Service

Finally, let’s implement the actual logic – a simple service layer that’s also secured:

@Service
public class RunAsService {

    @Secured({ "ROLE_RUN_AS_REPORTER" })
    public Authentication getCurrentUser() {
        Authentication authentication = 
          SecurityContextHolder.getContext().getAuthentication();
        return authentication;
    }
}

Note that:

  • To access getCurrentUser() method, we need to ROLE_RUN_AS_REPORTER
  • So we can only call getCurrentUser() method inside our tryRunAs() controller method

6. The Front-End

Next, we will use a simple front-end to test our Run-As feature:

<html>
<body>
Current user authorities: 
    <span sec:authentication="principal.authorities">user</span>
<br/>
<span id="temp"></span>
<a href="#" onclick="tryRunAs()">Generate Report As Super User</a>
             
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script type="text/javascript">
function tryRunAs(){
    $.get( "/runas" , function( data ) {
         $("#temp").html(data);
    });
}
</script>
</body>
</html>

So now, when a user triggers the “Generate Report As Super User” action – they’ll obtain the temporary ROLE_RUN_AS_REPORTER authority.

7. Conclusion

In this quick tutorial, we explored a simple example using the Spring Security Run-As authentication replacement feature.

This tutorial is based on the codebase available on GitHub.

Get the early-bird price (20% Off) of my upcoming "Learn Spring Security" Course:

>> CHECK OUT THE COURSE


Java Web Weekly, Issue 125

$
0
0

I just released the Starter Class of "Learn Spring Security":

>> CHECK OUT THE COURSE

A bit of a quicker one this week, as I’m writing it in between Spring IO sessions.

Here we go…

1. Spring and Java

>> Thymeleaf 3 – Get Started Quickly with Thymeleaf 3 and Spring MVC [codeleak.pl]

A quick and to the point intro to using Thymeleaf with Spring, hopefully getting the industry one step closer to never touching a JSP file ever again.

>> How to Split JUnit Tests in a Continuous Integration Environment [semaphoreci.com]

A solid, thorough writeup focused on intelligently separating the way different tests run in a CI pipeline. Very useful stuff.

>> 13 Decks Java Developers Must See to Stay Updated [takipi.com]

Some very interesting slide-decks worth going over. Not only for the subject matter, but also to see what the cadence of a good talk looks like.

Also worth reading:

Webinars and presentations:

Time to upgrade:

2. Technical

>> Cleanup Temp Files [techblog.bozho.net]

This is a quick writeup that I was thinking would make the “Also word reading” section below.

But, temporary files and applications that just keep growing and growing is such a common and overlooked problem that I think it’s really worth thinking about if you’re writing that kind of app.

Also worth reading:

3. Musings

>> Dirty Hacks Are OK [techblog.bozho.net]

I know this is not the best advice I’ve given” – that cracked me up.

But, in all seriousness, once you know the rules, yes, sometimes it’s definitely OK to break them.

>> CodeFX Leveled Up [codefx.org]

I thoroughly enjoyed reading this piece, from so many points of view.

First, it’s a clear, ambitious plan that I’m sure Nicolai is going to execute on well.

But more importantly – it represents forward movement in a space where so many people sit still for years and years – blogging. It’s quite easy to find yourself settle in a rhythm and doing the things that you’ve always been doing.

Shake things up!

>> The Gravitational Force of Wage Labor [daedtech.com]

An interesting read on the dynamics of longer term consulting engagements.

>> DDD Is Expensive Is A Myth [sapiensworks.com]

Like all the other DDs, Domain Driven Design may look like it’s more work at the beginning, but overall, the level of clarity that it brings into a system dwarfs the time it takes to understand and implement.

>> Simple Asynchronous Microservices using Lambda Architecture [vanillajava.blogspot.com]

A good first step towards understanding the Lambda architecture.

>> Lessons learned from delivering a test automation workshop [ontestautomation.com]

I’m doing more workshops this year, so I enjoyed going through this one. Have a look if you’re interested in either side of the workshop experience.

Also worth reading:

4. Comics

And my favorite Dilberts of the week:

>> I won’t bother using real words [dilbert.com]

>> OK, let’s begin wasting our time [dilbert.com]

>> Take your time. I’m good either way [dilbert.com]

5. Pick of the Week

>> Who wants to live in The Real World? [m.signalvnoise.com]

Get the early-bird price (20% Off) of my upcoming "Learn Spring Security" Course:

>> CHECK OUT THE COURSE

XML Serialization and Deserialization with Jackson

$
0
0

1. Overview

In this article, we are going to look at how to serialize a Java object to XML data using Jackson 2.x and deserialize it back to a POJO.

We’ll focus on the basic operation that don’t require a lot of complexity or customization.

2. XmlMapper Object

XmlMapper is the main class from Jackson 2.x that helps us in serialization, so we shall need to create an instance of it:

XmlMapper mapper = new XmlMapper();

XmlMapper is available in jackson-dataformat-xml jar, so we have to add it as a dependency in our pom.xml. In this tutorial we use the version 2.7.4, but you should always check for the latest version:

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
    <version>2.7.4</version>
</dependency>

3. Serialize Java to XML

XmlMapper is a subclass of ObjectMapper which is used in JSON serialization. However it adds some XML specific tweaks to the parent class.

We can now look at how to use it to do actual serialization. Let’s create the java class whose object to serialize:

class SimpleBean {
    private int x = 1;
    private int y = 2;
    //standard setters and getters
}

3.1. Serialize to XML String

We can serialize the Java object into an XML string:

@Test
public void whenJavaSerializedToXmlStr_thenCorrect() throws JsonProcessingException {
    XmlMapper xmlMapper = new XmlMapper();
    String xml = xmlMapper.writeValueAsString(new SimpleBean());
    assertNotNull(xml);
}

Resulting XML string (formatted for readability):

<SimpleBean>
    <x>1</x>
    <y>2</y>
</SimpleBean>

3.2. Serialize to XML file

We can also serialize the Java object to an XML file for later use:

@Test
public void whenJavaSerializedToXmlFile_thenCorrect() throws IOException {
    XmlMapper xmlMapper = new XmlMapper();
    xmlMapper.writeValue(new File("simple_bean.xml"), new SimpleBean());
    File file = new File("simple_bean.xml");
    assertNotNull(file);
}

The content of the resulting file simple_bean.xml :

<SimpleBean>
    <x>1</x>
    <y>2</y>
</SimpleBean>

4. Deserialize XML to Java

In this section, we shall look at how to obtain java objects from XML.

4.1. Deserialize From XML String

As with serialization, we can also deserialize an XML String back to a Java object like so:

@Test
public void whenJavaGotFromXmlStr_thenCorrect() throws IOException {
    XmlMapper xmlMapper = new XmlMapper();
    SimpleBean value = 
      xmlMapper.readValue("<SimpleBean><x>1</x><y>2</y></SimpleBean>", SimpleBean.class);
    assertTrue(value.getX() == 1 && value.getY() == 2);
}

4.2. Deserialize From XML File

Likewise, if we have an XML file, this section shows how to convert it back to a Java object.

Here we first read the file into an input stream and then convert the input stream to a string with a simple utility method.

The rest of the code is similar to that in section 4.1 above:

@Test
public void whenJavaGotFromXmlFile_thenCorrect() throws IOException {
    File file = new File("simple_bean.xml");
    XmlMapper xmlMapper = new XmlMapper();
    String xml = inputStreamToString(new FileInputStream(file));
    SimpleBean value = xmlMapper.readValue(xml, SimpleBean.class);
    assertTrue(value.getX() == 1 && value.getY() == 2);
}

The utility method:

public static String inputStreamToString(InputStream is) throws IOException {
    StringBuilder sb = new StringBuilder();
    String line;
    BufferedReader br = new BufferedReader(new InputStreamReader(is));
    while ((line = br.readLine()) != null) {
        sb.append(line);
    }
    br.close();
    return sb.toString();
}

5. Conclusion

This simple article illustrated how to serialize a simple POJO to XML and obtain a POJO from basic XML data.

The source code that accompanies this article is available on GitHub.

The Basics of JUnit 5 – A Preview

$
0
0

I just released the Starter Class of "Learn Spring Security":

>> CHECK OUT THE COURSE

1. Overview

JUnit is one of the most popular unit testing frameworks for Java, so it is a big deal in the developer community when new major versions come out. An alpha version of JUnit 5 was released in early February, and it contains a number of exciting innovations.

This article will explore the new features of this release, and the main differences with previous versions.

2. Dependencies and Setup

Installing JUnit 5 is pretty straightforward. Just add the following dependency to your pom.xml:

<dependency>
    <groupId>org.junit</groupId>
    <artifactId>junit5-api</artifactId>
    <version>5.0.0-ALPHA</version>
</dependency>

However, at the moment no IDEs support JUnit 5 yet, so you will also have to specify a build script:

<plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.19</version>
    <dependencies>
        <dependency>
            <groupId>org.junit</groupId>
            <artifactId>surefire-junit5</artifactId>
            <version>5.0.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
</plugin>

It is important to note that this version requires Java 8 to work.

When creating a test, make sure you import org.junit.gen5.api.Test, not org.junit.Test. Also, the test methods no longer need to be public; package local will do.

3. What’s New

JUnit 5 tries to take full advantage of the new features from Java 8, especially lambda expressions.

3.1. Assertions

Assertions have been moved to org.junit.gen5.api.Assertions and have been improved significantly. As mentioned earlier, you can now use lambdas in assertions:

@Test
void lambdaExpressions() {
    List<Integer> numbers = Arrays.asList(1, 2, 3);
    assertTrue(numbers
        .stream()
        .mapToInt(i -> i)
        .sum() > 5, () -> "Sum should be greater than 5");
}

Although the example above is trivial, one advantage of using the lambda expression for the assertion message is that it is lazily evaluated, which can save time and resources if the message construction is expensive.

It is also now possible to group assertions with assertAll() which will report any failed assertions within the group with a MultipleFailuresError:

 @Test
 void groupAssertions() {
     int[] numbers = {0, 1, 2, 3, 4};
     assertAll("numbers",
         () -> assertEquals(numbers[0], 1),
         () -> assertEquals(numbers[3], 3),
         () -> assertEquals(numbers[4], 1)
     );
 }

This means it is now safer to make more complex assertions, as you will be able to pinpoint the exact location of any failure.

3.2. Assumptions

Assumptions are used to run tests only if certain conditions are met. This is typically used for external conditions that are required for the test to run properly, but which are not directly related to whatever is being tested.

You can declare an assumption with assumeTrue(), assumeFalse(), and assumingThat(). 

@Test
void trueAssumption() {
    assumeTrue(5 > 1);
    assertEquals(5 + 2, 7);
}

@Test
void falseAssumption() {
    assumeFalse(5 < 1);
    assertEquals(5 + 2, 7);
}

@Test
void assumptionThat() {
    String someString = "Just a string";
    assumingThat(
        someString.equals("Just a string"),
        () -> assertEquals(2 + 2, 4)
    );
}

If an assumption fails, a TestAbortedException is thrown and the test is simply skipped.

Assumptions also understand lambda expressions.

3.3. Exceptions

JUnit 5 improves support for exceptions. An expectThrows() method has been added that verifies that an expression throws an expression of a given type:

@Test
void shouldThrowException() {
    Throwable exception = expectThrows(UnsupportedOperationException.class, () -> {
      throw new UnsupportedOperationException("Not supported");
    });
    assertEquals(exception.getMessage(), "Not supported");
}

As the example demonstrates, JUnit 5 offers more control over the thrown exceptions than JUnit 4 used to. The most obvious implication is that it is now possible to easily get any information we might need about the exception, as we did in our example by inspecting the exception message.

3.4. Nested Tests

Nested tests have been added to allow developers to express complex relationships between different groups of tests. The syntax is quite straightforward – all you have to do is annotate an inner class with @Nested.

The JUnit documentation offers an elaborate example, which illustrates one of the possible uses.

3.5. Disabling Tests

Tests can now be disable with the @Disabled annotation.

@Test
@Disabled
void disabledTest() {
    assertTrue(false);
}

This test will not be run. The @Disabled annotation can be applied to either a test case or a test method and is equivalent to @Ignore from JUnit 4.

3.6. Tagging

Tags are the replacement for Categories from JUnit 4. Tags can be applied with the @Tag annotation. These allow developers to group and filter tests.

@Tag("Test case")
public class TaggedTest {

    @Test
    @Tag("Method")
    void testMethod() {
        assertEquals(2+2, 4);
    }
}

4. Conclusion

The writeup was a quick overview of the changes that are coming with JUnit 5.

It is important to note that at the moment of writing only the Alpha build was available, so some things might still change before release.

The examples used in this article can be found in the linked GitHub project.

Get the early-bird price (20% Off) of my upcoming "Learn Spring Security" Course:

>> CHECK OUT THE COURSE

Introduction to Spring REST Docs

$
0
0

I just released the Starter Class of "Learn Spring Security":

>> CHECK OUT THE COURSE

1. Overview

Spring REST Docs generates documentation for RESTful services that is both accurate and readable. It combines hand-written documentation with auto-generated document snippets produced with Spring MVC tests.

2. Advantages

One major philosophy behind the project is the use of tests to produce the documentation. This ensures that the documentation generated always accurately matches the actual behavior of the API. Additionally, the output is ready to be processed by Asciidoctor, a publishing toolchain centered around the AsciiDoc syntax. This is the same tool that is used to generate the Spring Framework’s documentation.

These approaches reduce the limitations imposed by other frameworks. Spring REST Docs produces documentation that is accurate, concise, and well-structured. This documentation then allows the web service consumers to get the information they need with a minimum of fuss.

The tool has some other advantages, such as:

  • curl and http request snippets are generated
  • easy to package documentation in projects jar file
  • easy to add extra information to the snippets
  • supports both JSON and XML

3. Dependencies

The ideal way to get started using Spring REST Docs in a project is by using a dependency management system. Here, we are using Maven as build tool, so the dependency below can be copied and pasted into your POM:

<dependency>
    <groupId>org.springframework.restdocs</groupId>
    <artifactId>spring-restdocs-mockmvc</artifactId>
    <version>1.0.1.RELEASE</version>
</dependency>

You can also check Maven Central for a new version of the dependency here.

4. Configuration

Spring REST Docs can be created using the Spring MVC Test framework to make requests to the REST services which are to be documented. This produces documentation snippets for the request and the resulting response.

The very first step in generating documentation snippets is to declare a public RestDocumentation field that is annotated as a JUnit @Rule. The RestDocumentation rule is configured with the output directory into which the generated snippets should be saved. For example, this directory can be the build out directory of Maven:

@Rule
public RestDocumentation restDocumentation = new RestDocumentation("target/generated-snippets");

Next, we set up the MockMvc context so that it will be configured to produce documentation.

@Autowired
private WebApplicationContext context;

private MockMvc mockMvc;

@Before
public void setUp(){
    this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
      .apply(documentationConfiguration(this.restDocumentation))
      .build();
}

The MockMvc object is configured using a RestDocumentationMockMvcConfigurer. An instance of this class can be obtained from the static documentationConfiguration() method on org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.

Let’s create a CRUD RESTful service that we can document:

@RestController
@RequestMapping("/crud")
public class CRUDController {
	
    @RequestMapping(method=RequestMethod.GET)
    public List<CrudInput> read() {
        List<CrudInput> returnList=new ArrayList<CrudInput>();
        return returnList;
    }
	
    @ResponseStatus(HttpStatus.CREATED)
    @RequestMapping(method=RequestMethod.POST)
    public HttpHeaders save(@RequestBody CrudInput crudInput) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setLocation(linkTo(CRUDController.class).slash(crudInput.getTitle()).toUri());
        return httpHeaders;
    }
	
    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
    void delete(@PathVariable("id") long id) {
        // delete
    }
}

Back in the tests, a MockMvc instance has been already created. It can be used to call the service we just created, and will document the request and response. The method below will generate the document in the configured directory:


@Test
public void index() throws Exception {
    this.mockMvc.perform(
      get("/")
        .accept(MediaTypes.HAL_JSON))
        .andExpect(status().isOk())
        .andExpect(jsonPath("_links.crud", is(notNullValue())));
}

It is time to create the document snippets for the REST service:

@Test
public void indexExample() throws Exception {
    this.document.snippets(
      links(
        linkWithRel("notes").description("The <<resources-notes,Notes resource>>"), 
        linkWithRel("tags").description("The <<resources-tags,Tags resource>>")
      ),
      responseFields(
        fieldWithPath("_links").description("<<resources-index-links,Links>> to other resources")
      )
    );
    this.mockMvc.perform(get("/rest/api")).andExpect(status().isOk());
}

5. Output

Once the Maven build runs successfully, the output of the REST docs snippets will be generated and will be saved to the target/generated-snippets folder.

Screen Shot 2016-04-04 at 11.48.52 PM

The generated output will have the information about the service, how to call the REST service like ‘curl’ calls, the HTTP request and response from the REST service, and links/endpoints to the service:

<strong>CURL Command</strong>
----
$ curl 'http://localhost:8080/api' -i
----

<strong>HTTP - REST Response</strong>
[source,http]
----
HTTP/1.1 200 OK
Content-Type: application/hal+json
Content-Length: 160

{
  "_links" : {
    "notes" : {
      "href" : "http://localhost:8080/testapi"
    },
    "tags" : {
      "href" : "http://localhost:8080/testapi"
    }
  }
}
----

6. Using Snippets to Create Documentation

In order to use the snippets in a larger document, you can reference them using Asciidoc inlcudes. In our case, we have created a document in src/docs called api-guide.adoc:

Screen Shot 2016-05-01 at 8.51.48 PM

In that document, if we wished to reference the response headers snippet, we can include it, using a placeholder {snippets} that will be replaced by Maven when it processes the document:

[[overview-headers]]
== Headers

Every response has the following header(s):

include::{snippets}/headers-example/response-headers.adoc[]

7. Asciidocs Maven Plugins

To convert the API guide from Asciidoc to a readable format, we can add a Maven plugin to the build lifecycle. There are several steps to enable this:

  1. Apply the Asciidoctor plugin to the pom.xml
  2. Add a dependency on spring-restdocs-mockmvc in the testCompile configuration as mentioned in the dependencies section
  3. Configure a property to define the output location for generated snippets
  4. Configure the test task to add the snippets directory as an output
  5. Configure the asciidoctor task
  6. Define an attribute named snippets that can be used when including the generated snippets in your documentation
  7. Make the task depend on the test task so that the tests are run before the documentation is created
  8. Configure the snippets directory as an input. All the generated snippets will be created under this directory

Add the snippet directory as a property in pom.xml so the Asciidoctor plugin can use this path to generate the snippets under this folder:

<properties>
    <snippetsDirectory>${project.build.directory}/generated-snippets</snippetsDirectory>
</properties>

The Maven plugin configuration in the pom.xml to generate the Asciidoc snippets from the build is as below:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
        <plugin> 
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <configuration>
	        <includes>
                    <include>**/*Documentation.java</include>
	        </includes>
	    </configuration>
        </plugin>
        <plugin> 
            <groupId>org.asciidoctor</groupId>
	    <artifactId>asciidoctor-maven-plugin</artifactId>
	    <version>1.5.2</version>
	    <executions>
	        <execution>
	            <id>generate-docs</id>
	            <phase>package</phase> 
	            <goals>
	                <goal>process-asciidoc</goal>
	            </goals>
	            <configuration>
	                <backend>html</backend>
	                <doctype>book</doctype>
	                <attributes>
	                    <snippets>${snippetsDirectory}</snippets> 
	                </attributes>
	                <sourceDirectory>src/docs/asciidocs</sourceDirectory>
	                <outputDirectory>target/generated-docs</outputDirectory>
                    </configuration>
	        </execution>
	    </executions>
        </plugin>
    </plugins>
</build>

8. API Doc generation process

When the Maven build runs and the tests are executed, all the snippets will be generated in the snippets folder under the configured target/generated-snippets directory. Once the snippets are generated, the build process generates HTML output.

Screen Shot 2016-05-08 at 11.32.25 PM

The generated HTML file is formatted and readable, so the REST documentation is ready to use. Every time the Maven build runs, the documents also get generated with the latest updates.

Screen Shot 2016-05-08 at 11.36.36 PM

9. Conclusion

Having no documentation is better than wrong documentation, but Spring REST docs will help generate accurate documentation for RESTful services.

As an official Spring project, it accomplishes its goals by using the Spring MVC Test library. This method of generating documentation can help support a test-driven approach to developing and documenting RESTful APIs.

You can find an example project based on the code in this article in the linked GitHub repository.

Get the early-bird price (20% Off) of my upcoming "Learn Spring Security" Course:

>> CHECK OUT THE COURSE

Java Web Weekly, Issue 126

$
0
0

I just released the Starter Class of "Learn Spring Security":

>> CHECK OUT THE COURSE

At the very beginning of last year, I decided to track my reading habits and share the best stuff here, on Baeldung. Haven’t missed a review since.

Here we go…

1. Spring and Java

>> How We Migrated Our Backend to Spring Boot in 3 Weeks [stormpath.com]

Definitely an interesting writeup of how Stormpath basically migrated their entire codebase to Spring Boot.

>> We Crunched 1 Billion Java Logged Errors – Here’s What Causes 97% of Them [takipi.com]

Some fun numbers and insights, despite the link-baity title.

>> How to persist additional attributes for a relationship with JPA and Hibernate [thoughts-on-java.org]

Some advanced Hibernate/JPA goodness about more complex relationship information and understanding how to handle these well.

Also worth reading:

Webinars and presentations:

Time to upgrade:

2. Technical

>> Hash and Salt Your Users’ Passwords [martinfowler.com]

When it comes to password storage, this writeup covers the basics, sure – but it does so in a well structured, clear way. Definitely worth a quick read.

Also worth reading:

3. Musings

>> Observations and thoughts on the LinkedIn data breach [troyhunt.com]

Very interesting, in-depth analysis of the LinkedIn data breach.

>> Solve Small Problems [daedtech.com]

This is definitely one to read, as it sheds some light into how real progress is usually made – one unassuming brick at a time.

Also worth reading:

4. Comics

And my favorite Dilberts of the week:

>> Don’t turn your back [dilbert.com]

>> Just do your job and leave the strategy to management [dilbert.com]

>> I’ll use this dummy to demonstrate … [dilbert.com]

5. Pick of the Week

>> “We only hire the best” [signalvnoise.com]

Get the early-bird price (20% Off) of my upcoming "Learn Spring Security" Course:

>> CHECK OUT THE COURSE

JavaServer Faces (JSF) with Spring

$
0
0

I just released the Starter Class of "Learn Spring Security":

>> CHECK OUT THE COURSE

1. Overview

In this article we will look at a recipe for accessing beans defined in Spring from within a JSF managed bean and a JSF page, for the purposes of delegating the execution of business logic to the Spring beans.

This article presumes the reader has a prior understanding of both JSF and Spring separately. The article is based on the Mojarra implementation of JSF.

2. In Spring

Let’s have the following bean defined in Spring. The UserManagementDAO bean adds a username to an in-memory store, and its defined by the following interface:

public interface UserManagementDAO {
    boolean createUser(String newUserData);
}

The implementation of the bean is configured using the following Java config:

public class SpringCoreConfig {
    @Bean
    public UserManagementDAO userManagementDAO() {
        return new UserManagementDAOImpl();
    }
}

Or using the following XML configuration:

<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" />
<bean class="com.baeldung.dao.UserManagementDAOImpl" id="userManagementDAO"/>

We define the bean in XML, and register CommonAnnotationBeanPostProcessor to ensure that the @PostConstruct annotation is picked up.

3. Configuration

The following sections explain the configuration items that enable the integration of the Spring and JSF contexts.

3.1. Java Configuration Without web.xml

By implementing the WebApplicationInitializer we are able to programatically configure the ServletContext. The following is the onStartup() implementation inside the MainWebAppInitializer class:

public void onStartup(ServletContext sc) throws ServletException {
    AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext();
    root.register(SpringCoreConfig.class);
    sc.addListener(new ContextLoaderListener(root));
}

The AnnotationConfigWebApplicationContext bootstraps the Spring’g context and adds the beans by registering the SpringCoreConfig class.

Similarly, in the Mojarra implementation there is a FacesInitializer class that configures the FacesServlet. To use this configuration it is enough to extend the FacesInitializer. The complete implementation of the MainWebAppInitializer, is now as follows:

public class MainWebAppInitializer extends FacesInitializer implements WebApplicationInitializer {
    public void onStartup(ServletContext sc) throws ServletException {
        AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext();
        root.register(SpringCoreConfig.class);
        sc.addListener(new ContextLoaderListener(root));
    }
}

3.2. With web.xml

We’ll start by configuring the ContextLoaderListener in web.xml file of the application:

<listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>

This listener is responsible for starting up the Spring application context when the web application starts up. This listener will look for a spring configuration file named applicationContext.xml by default.

3.3. faces-config.xml

We now configure the SpringBeanFacesELResolver in the face-config.xml file:

<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>

An EL resolver is a pluggable component supported by the JSF framework, allowing us to customize the behavior of the JSF runtime when evaluating Expression Language (EL) expressions. This EL resolver will allow the JSF runtime access Spring components via EL expressions defined in JSF.

4. Accessing Spring Beans in JSF

At this point, our JSF web application is primed to access our Spring bean from either a JSF backing bean, or from a JSF page.

4.1. From a Backing Bean JSF 2.0

The Spring bean can now be accessed from a JSF backing bean. Depending on the version of JSF you’re running, there are two possible methods. With JSF 2.0, you use the @ManagedProperty annotation on the JSF managed bean.

@ManagedBean(name = "registration")
@RequestScoped
public class RegistrationBean implements Serializable {
    @ManagedProperty(value = "#{userManagementDAO}")
    transient private IUserManagementDAO theUserDao;

    private String userName;
    // getters and setters
}

Note that the getter and setter are mandatory when using the @ManagedProperty. 
Now – to assert the accessibility of a Spring bean from a managed bean, we will add the createNewUser() method:

public void createNewUser() {
    FacesContext context = FacesContext.getCurrentInstance();
    boolean operationStatus = userDao.createUser(userName);
    context.isValidationFailed();
    if (operationStatus) {
        operationMessage = "User " + userName + " created";
    }
}

The gist of the method is using the userDao Spring bean, and accessing its functionality.

4.2. From a Backing Bean in JSF 2.2

Another approach, valid only in JSF2.2 and above, is to use CDI’s @Inject annotation. This is applicable to JSF managed beans (with the @ManagedBean annotation), and CDI-managed beans (with the @Named annotation).

Indeed, with a CDI annotation, this is the only valid method of injecting the bean:

@Named( "registration")
@RequestScoped
public class RegistrationBean implements Serializable {
    @Inject
    UserManagementDAO theUserDao;
}

With this approach, the getter and setter are not necessary. Also note that the EL expression is absent.

4.3. From a JSF View

The createNewUser() method will be triggered from the following JSF page:

<h:form>
    <h:panelGrid id="theGrid" columns="3">
        <h:outputText value="Username"/>
        <h:inputText id="firstName" binding="#{userName}" required="true"
          requiredMessage="#{msg['message.valueRequired']}" value="#{registration.userName}"/>
        <h:message for="firstName" style="color:red;"/>
        <h:commandButton value="#{msg['label.saveButton']}" action="#{registration.createNewUser}"
          process="@this"/>
        <h:outputText value="#{registration.operationMessage}" style="color:green;"/>
    </h:panelGrid>
</h:form>

To render the page, start the server and navigate to:

http://localhost:8080/jsf/index.jsf

We can also use EL in the JSF view, to access the Spring bean. To test it it is enough to change the line number 7 from the previously introduced JSF page to:

<h:commandButton value="Save"
  action="#{registration.userDao.createUser(userName.value)}"/>

Here, we call the createUser method directly on the Spring DAO, passing the bind value of the userName to the method from within the JSF page, circumventing the managed bean all together.

5. Conclusion

We examined a basic integration between the Spring and JSF contexts, where we’re able to access a Spring bean in a JSF bean and page.

It’s worth noting that while the JSF runtime provides the pluggable architecture that enables the Spring framework to provide integration components, the annotations from the Spring framework cannot be used in a JSF context and vice versa.

What this means is that you’ll not be able to use annotations like @Autowired or @Component e.t.c. in a JSF managed bean, or use the @ManagedBean annotation on a Spring managed bean. You can however, use the @Inject annotation in both a JSF 2.2+ managed bean, and a Spring bean (because Spring supports JSR-330).

The source code that accompanies this article is available at GitHub.

Get the early-bird price (20% Off) of my upcoming "Learn Spring Security" Course:

>> CHECK OUT THE COURSE

Java Web Weekly, Issue 127

$
0
0

I just released the Starter Class of "Learn Spring Security":

>> CHECK OUT THE COURSE

At the very beginning of last year, I decided to track my reading habits and share the best stuff here, on Baeldung. Haven’t missed a review since.

Here we go…

1. Spring and Java

>> Zero Downtime Deployment with a Database [spring.io]

It’s no coincidence that this is first on the list this week – Marcin wrote a well researched, solid and referenceable resource for handling deployments in production.

>> Back to the CompletableFuture: Java 8 Feature Highlight [takipi.com]

Brushing up on the basics is always a good idea, and the CompletableFuture was such a useful addition in Java 8.

The fact that the examples are built using Marvel superheroes is just gravy.

>> JVM JIT optimization techniques [advancedweb.hu]

A comprehensive introduction to the underpinnings of how the JVM actually optimizes and runs code.

>> The Open Session In View Anti-Pattern [vladmihalcea.com]

A low level and highly useful deep-dive into how using the Open Session In View “solution” is essentially a code smell for a root problem in the architecture of the system.

>> Oracle Moves In Strange Ways [adam-bien.com]

A very interesting lesson in the history of Java EE and a quick read.

>> Why Microservices Should Be Event Driven: Autonomy vs Authority [christianposta.com]

As it’s becoming clearer and clearer after the ruckus has died down – microservices require a fundamentally different way of architecting our systems.

>> How to use PostgreSQL’s JSONB data type with Hibernate [thoughts-on-java.org]

Some Hibernate goodness with the JSON support in PostgreSQL.

Also worth reading:

Webinars and presentations:

Time to upgrade:

2. Technical

>> Modelling Microservice Patterns in Code [vanilla-java.github.io]

An writeup that can define and clarify the mental model of certain client-server interactions.

Also worth reading:

3. Musings

>> The emergence of historical mega breaches [troyhunt.com] and >> Dating the ginormous MySpace breach [troyhunt.com]

Some very interesting things happening in the security ecosystem this week, with a few unprecedented data breaches seeing the light of day all at once.

>> Bridging the Communication Gap Between Developers and Architects [daedtech.com]

Consensus about what an “architect” should be is unlikely, but defining a few useful things that they should definitely do is easier. Some interesting take-aways here.

>> OutcomeOriented [martinfowler.com] and >> ActivityOriented [martinfowler.com]

Organizing teams well is a tough nut to crack. If you’re working on cracking it – these two short writeups are a good read.

Also worth reading:

4. Comics

And my favorite Dilberts of the week:

>> How did people do sarcasm before the internet? [dilbert.com]

>> I remember a time when I had to listen [dilbert.com]

>> The least important thing I do is more important than all of you put together [dilbert.com]

5. Pick of the Week

>> Immortality Begins at Forty [ribbonfarm.com]

Get the early-bird price (20% Off) of my upcoming "Learn Spring Security" Course:

>> CHECK OUT THE COURSE


Multiple Buckets and Spatial View Queries in Spring Data Couchbase

$
0
0

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

1. Introduction

In this third tutorial on Spring Data Couchbase, we demonstrate the configuration required to support a Couchbase data model that spans multiple buckets, and we introduce the use of Spatial views for querying multi-dimensional data.

2. Data Model

In addition to the Person entity from our first tutorial and the Student entity from our second tutorial, we define a Campus entity for this tutorial:

@Document
public class Campus {
    @Id
    private String id;

    @Field
    @NotNull
    private String name;

    @Field
    @NotNull
    private Point location;

    // standard getters and setters
}

3. Java Configuration for Multiple Couchbase Buckets

In order to use multiple buckets in your project, you will need to use version 2.0.0 or later of the Spring Data Couchbase module, and you will need to use a Java-based configuration, because the XML-bsaed configuration supports only single-bucket scenarios.

Here is the dependency that we include in our Maven pom.xml file:

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-couchbase</artifactId>
    <version>2.1.1.RELEASE</version>
</dependency>

3.1. Defining the Bucket Bean

In our Introduction to Spring Data Couchbase tutorial, we designated “baeldung” as the name of our default Couchbase bucket for use with Spring Data.

We will store Campus entities in the “baeldung2” bucket.

To make use of a second bucket, we first must define a @Bean for the Bucket itself in our Couchbase configuration class:

@Bean
public Bucket campusBucket() throws Exception {
    return couchbaseCluster().openBucket("baeldung2", "");
}

3.2. Configuring the Template Bean

Next, we define a @Bean for the CouchbaseTemplate to be used with this bucket:

@Bean
public CouchbaseTemplate campusTemplate() throws Exception {
    CouchbaseTemplate template = new CouchbaseTemplate(
      couchbaseClusterInfo(), campusBucket(),
      mappingCouchbaseConverter(), translationService());
    template.setDefaultConsistency(getDefaultConsistency());
    return template;
}

3.3. Mapping the Repositories

Finally, we define a custom mapping of Couchbase repository operations so that the Campus entity class will use the new template and bucket, while other entity classes will continue to use the default template and bucket:

@Override
public void configureRepositoryOperationsMapping(
  RepositoryOperationsMapping baseMapping) {
    try {
        baseMapping.mapEntity(Campus.class, campusTemplate());
    } catch (Exception e) {
        //custom Exception handling
    }
}

4. Querying Spatial or Multi-Dimensional Data

Couchbase provides native support for running bounding box queries against two-dimensional data, such as geographical data, using a special type of view known as a Spatial view.

A bounding box query is a range query that uses the southwestern-most [x,y] point of the box as its startRange parameter and the northwestern-most [x,y] point as its endRange parameter.

Spring Data extends Couchbase’s native bounding box query feature to queries involving circles and polygons using an algorithm that seeks to eliminate false positive matches, and it also provides support for queries involving more than two dimensions.

Spring Data simplifies the creation of multi-dimensional queries through a set of keywords that can be used to define derived queries in Couchbase repositories.

4.1. Supported Data Types

Spring Data Couchbase repository queries support data types from the org.springframework.data.geo package, including Point, Box, Circle, Polygon, and Distance.

4.2. Derived Query Keywords

In addition to the standard Spring Data repository keywords, Couchbase repositories support the following keywords in derived queries involving two dimensions:

  • Within, InWithin (takes two Point parameters defining a bounding box)
  • Near, IsNear (takes a Point and Distance as parameters)

And the following keywords may be used for queries involving more than two dimensions:

  • Between (for adding a single numerical value to both the startRange and endRange)
  • GreaterThan, GreaterThanEqual, After (for adding a single numerical value to the startRange)
  • LessThan, LessThanEqual, Before (for adding a single numerical value to the endRange)

Here are some examples of derived query methods using these keywords:

  • findByLocationNear
  • findByLocationWithin
  • findByLocationNearAndPopulationGreaterThan
  • findByLocationWithinAndAreaLessThan
  • findByLocationNearAndTuitionBetween

5. Defining the Repository

Repository methods backed by Spatial views must be decorated with the @Dimensional annotation, which specifies the design document name, view name, and number of dimensions used to define the view’s key (default 2 if not otherwise specified).

5.1. The CampusRespository Interface

Here in our CampusRepository interface, we declare two methods — one that uses traditional Spring Data keywords, backed by a MapReduce view, and one that uses dimensional Spring Data keywords, backed by a Spatial view:

public interface CampusRepository extends CrudRepository<Campus, String> {

    @View(designDocument="campus", viewName="byName")
    Set<Campus> findByName(String name);

    @Dimensional(dimensions=2, designDocument="campus_spatial",
      spatialViewName="byLocation")
    Set<Campus> findByLocationNear(Point point, Distance distance);
}

5.2. Spatial Views

Spatial views are written as JavaScript functions, much like MapReduce views. Unlike MapReduce views, which consist of both a map function and a reduce function, Spatial views consist of only a spatial function and may not coexist in the same Couchbase design document as MapReduce views.

For our Campus entities, we will create a design document named “campus_spatial” containing a Spatial view named “byLocation” with the following function:

function (doc) {
  if (doc.location &&
      doc._class == "org.baeldung.spring.data.couchbase.model.Campus") {
    emit([doc.location.x, doc.location.y], null);
  }
}

As this example demonstrates, when you write a Spatial view function, the key used in the emit function call must be an array of two or more values.

5.3. MapReduce Views

To provide full support for our repository, we must create a design document named “campus” containing two MapReduce views: “all” and “byName”.

Here is the map function for the “all” view:

function (doc, meta) {
  if(doc._class == "org.baeldung.spring.data.couchbase.model.Campus") {    
    emit(meta.id, null);
  }
}

And here is the map function for the “byName” view:

function (doc, meta) {
  if(doc._class == "org.baeldung.spring.data.couchbase.model.Campus" &&
     doc.name) {    
    emit(doc.name, null);
  }
}

6. Conclusion

We showed how to configure your Spring Data Couchbase project to support the use of multiple buckets, and we demonstrated how to use the repository abstraction to write spatial view queries against multi-dimensional data.

You can view the complete source code for this tutorial in the github project.

To learn more about Spring Data Couchbase, visit the official Spring Data Couchbase project site.

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


Guide to Spring @Autowired

$
0
0

I just released the Starter Class of "Learn Spring Security":

>> CHECK OUT THE COURSE

1. Overview

Starting with Spring 2.5, the framework introduced a new style of Dependency Injection driven by @Autowired Annotations. This annotation allows Spring to resolve and inject collaborating beans into your bean.

In this tutorial, we will look at how to enable autowiring, various ways to wire in beans, making beans optional, resolving bean conflicts using @Qualifier annotation along with potential exception scenarios.

2. Enabling @Autowired Annotations

If you are using Java based configuration in your application you can enable annotation driven injection by using AnnotationConfigApplicationContext to load your spring configuration as below:

@Configuration
@ComponentScan("com.baeldung.autowire.sample")
public class AppConfig {}

As an alternative, in Spring XML, it can be enabled by declaring it in Spring XML files like so: <context:annotation-config/>

3. Using @Autowired

Once annotation injection is enabled, autowiring can be used on properties, setters and constructors.

3.1. @Autowired on Properties

The annotation can be used directly on properties, therefore eliminating need for getters and setters:

@Component("fooFormatter")
public class FooFormatter {

    public String format() {
        return "foo";
    }
}
@Component
public class FooService {
    
    @Autowired
    private FooFormatter fooFormatter;

}

In the above example, Spring looks for and injects fooFormatter when FooService is created.

3.2. @Autowired on Setters

The @Autowired annotation can be used on setter methods. In the below example, when the annotation is used on the setter method, the setter method is called with the instance of FooFormatter when FooService is created:

public class FooService {

    private FooFormatter fooFormatter;

    @Autowired
    public void setFooFormatter(FooFormatter fooFormatter) {
            this.fooFormatter = fooFormatter;
    }
}

3.3. @Autowired on Constructors

The @Autowired annotation can also be used on constructors. In the below example, when the annotation is used on a constructor,  an instance of FooFormatter  is injected as an argument to the constructor when FooService is created:

public class FooService {

    private FooFormatter fooFormatter;

    @Autowired
    public FooService(FooFormatter fooFormatter) {
        this.fooFormatter = fooFormatter;
    }
}

4. @Autowired and Optional Dependencies

Spring expects @Autowired dependencies to be available when the dependent bean is being constructed. If the framework cannot resolve a bean for wiring, it will throw the below quoted exception and prevent the Spring container from launching successfully:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No qualifying bean of type [com.autowire.sample.FooDAO] found for dependency: 
expected at least 1 bean which qualifies as autowire candidate for this dependency. 
Dependency annotations: 
{@org.springframework.beans.factory.annotation.Autowired(required=true)}

To avoid this from happening, a bean can optional be specified as below:

public class FooService {

    @Autowired(required = false)
    private FooDAO dataAccessor; 
    
}

5. Autowire Disambiguation

By default Spring resolves @Autowired entries by type. If more than one beans of same type is available in the container, the framework will throw a fatal exception indicating that more than one bean is available for autowiring.

5.1. Autowiring by @Qualifier

The @Qualifier annotation can be used to hint at and narrow down the required bean:

@Component("fooFormatter")
public class FooFormatter implements Formatter {

    public String format() {
        return "foo";
    }
}
@Component("barFormatter")
public class BarFormatter implements Formatter {

    public String format() {
        return "bar";
    }
}
public class FooService {
    
    @Autowired
    private Formatter formatter;

}

Since there are two concrete implementations of Formatter available for the Spring container to inject, Spring will throw a NoUniqueBeanDefinitionException exception when constructing the FooService:

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: 
No qualifying bean of type [com.autowire.sample.Formatter] is defined: 
expected single matching bean but found 2: barFormatter,fooFormatter

This can be avoided by narrowing the implementation using a @Qualifier annotation:

public class FooService {
    
    @Autowired
    @Qualifier("fooFormatter")
    private Formatter formatter;

}

By specifying the @Qualifier with the name of the specific implementation, in this case as fooFormatter, we can avoid ambiguity when Spring finds multiple beans of same type.

Please note that the value inside the @Qualifier annotation matches with the name declared in the @Component annotation of our FooFormatter implementation.

5.2. Autowiring by Custom Qualifier

Spring allows us to create our own @Qualifier annotation. To create a custom Qualifier, define an annotation and provide the @Qualifier annotation within the definition as below:

@Qualifier
@Target({
  ElementType.FIELD, ElementType.METHOD, ElementType.TYPE, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface FormatterType {
    
    String value();

}

Once defined, the FormatterType can be used within various implementations to specify custom value:

@FormatterType("Foo")
@Component
public class FooFormatter implements Formatter {

    public String format() {
        return "foo";
    }
}
@FormatterType("Bar")
@Component
public class BarFormatter implements Formatter {

    public String format() {
        return "bar";
    }
}

Once the implementations are annotated, the custom Qualifier annotation can be used as below:

@Component
public class FooService {
    
    @Autowired
    @FormatterType("Foo")
    private Formatter formatter;
    
}

The value specified in the @Target annotation restrict where the qualifier can be used to mark injection points.

In the above code snippet the qualifier can be used to disambiguate the point where Spring can inject the bean into a field, a method, a type and a parameter.

5.2. Autowiring by Name

As a fall back Spring uses the bean name as a default qualifier value.

So by defining the bean property name, in this case as fooFormatter, Spring matches that to the FooFormatter implementation and injects that specific implementation when FooService is constructed:

public class FooService {
    
    @Autowired
    private Formatter fooFormatter;
    
}

6. Conclusion

Although both @Qualifier and bean name fallback match can be used to narrow down to a specific bean, autowiring is really all about injection by type and this is how best to use this container feature.

The source code of this 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.

Get the early-bird price (20% Off) of my upcoming "Learn Spring Security" Course:

>> CHECK OUT THE COURSE

REST API Testing with Cucumber

$
0
0

I just announced the Master Class of my "REST With Spring" Course:

>> THE "REST WITH SPRING" CLASSES

1. Overview

This tutorial gives an introduction to Cucumber, a commonly used tool for user acceptance testing, and how to use it in REST API tests.

In addition, to make the article self-contained and independent of any external REST services, we will use WireMock, a stubbing and mocking web service library. If you want to know more about this library, please refer to the introduction to WireMock.

2. Gherkin – The Language of Cucumber

Cucumber is a testing framework that supports Behavior Driven Development (BDD), allowing users to define application operations in plain text. It works based on the Gherkin Domain Specific Language (DSL). This simple but powerful syntax of Gherkin lets developers and testers write complex tests while keeping it comprehensible to even non-technical users.

2.1. Introduction to Gherkin

Gherkin is a line-oriented language using line endings, indentations and keywords to define documents. Each non-blank line usually starts with a Gherkin keyword, followed by an arbitrary text, which is usually a description of the keyword.

The whole structure must be written into a file with the feature extension to be recognized by Cucumber.

Here is a simple Gherkin document example:

Feature: A short description of the desired functionality

  Scenario: A business situation
    Given a precondition
    And another precondition
    When an event happens
    And another event happens too
    Then a testable outcome is achieved
    And something else is also completed

The subsections below will describe a couple of the most important elements in a Gherkin structure.

2.2. Feature

A Gherkin file is used to describe an application feature that needs to be tested. The file contains the Feature keyword at the very beginning, followed up by the feature name on the same line and an optional description that may span multiple lines underneath.

All the text, except for the Feature keyword, is skipped by the Cucumber parser and included for the purpose of documentation only.

2.3. Scenarios and Steps

A Gherkin structure may consist of one or more scenarios, recognized by the Scenario keyword. A scenario is basically a test allowing users to validate a capability of the application. It should describe an initial context, events that may happen and expected outcomes created by those events.

These things are done using steps, identified by one of the five keywords: Given, When, Then, And, and But.

  • Given: This step is to put the system into a well-defined state before users start interacting with the application. A Given clause can by considered a precondition for the use case.
  • When: A When step is used to describe an event that happens to the application. This can be an action taken by users, or an event triggered by another system.
  • Then: This step is to specify an expected outcome of the test. The outcome should be related to business values of the feature under test.
  • And and But: These keywords can be used to replace the above step keywords when there are multiple steps of the same type.

Cucumber does not actually distinguish these keywords, however they are still there to make the feature more readable and consistent with the BDD structure.

3. Cucumber-JVM Implementation

Cucumber was originally written in Ruby and has been ported into Java with Cucumber-JVM implementation, which is the subject of this section.

3.1. Maven Dependencies

In order to make use of Cucumber-JVM in a Maven project, the following dependency needs to be included in the POM:

<dependency>
    <groupId>info.cukes</groupId>
    <artifactId>cucumber-java</artifactId>
    <version>1.2.4</version>
    <scope>test</scope>
</dependency>

To facilitate JUnit testing with Cucumber, we need to have one more dependency:

<dependency>
    <groupId>info.cukes</groupId>
    <artifactId>cucumber-junit</artifactId>
    <version>1.2.4</version>
</dependency>

Alternatively, we can use another artifact to take advantage of lambda expressions in Java 8, which will not be covered in this tutorial.

3.2. Step Definitions

Gherkin scenarios would be useless if they were not translated into actions and this is where step definitions come into play. Basically, a step definition is an annotated Java method with an attached pattern whose job is to convert Gherkin steps in plain text to executable code. After parsing a feature document, Cucumber will search for step definitions that match predefined Gherkin steps to execute.

In order to make it clearer, let’s take a look at the following step:

Given I have registered a course in Baeldung

And a step definition:

@Given("I have registered a course in Baeldung")
public void verifyAccount() {
    // method implementation
}

When Cucumber reads the given step, it will be looking for step definitions whose annotating patterns match the Gherkin text. In our illustration, the testMethod method is found to be a match and its code is then executed, resulting in the Let me in! string printed out on the console.

4. Creating and Running Tests

4.1. Writing a Feature File

Let’s start with declaring scenarios and steps in a file with the name ending in the .feature extension:

Feature: Testing a REST API
  Users should be able to submit GET and POST requests to a web service, 
  represented by WireMock

  Scenario: Data Upload to a web service
    When users upload data on a project
    Then the server should handle it and return a success status

  Scenario: Data retrieval from a web service
    When users want to get information on the Cucumber project
    Then the requested data is returned

We now save this file in a directory named Feature, on the condition that the directory will be loaded into the classpath at runtime, e.g. src/main/resources.

4.2. Configuring JUnit to Work with Cucumber

In order for JUnit to be aware of Cucumber and read feature files when running, the Cucumber class must be declared as the Runner. We also need to tell JUnit the place to search for feature files and step definitions.

@RunWith(Cucumber.class)
@CucumberOptions(features = "classpath:Feature")
public class CucumberTest {
    
}

As you can see, the features element of CucumberOption locates the feature file created before. Another important element, called glue, provides paths to step definitions. However, if the test case and step definitions are in the same package as in this tutorial, that element may be dropped.

4.3. Writing Step Definitions

When Cucumber parses steps, it will search for methods annotated with Gherkin keywords to locate the matching step definitions. In this tutorial, these step definitions are defined in a class within the same package with CucumberTest.

The following is a method that fully matches a Gherkin step. The method will be used to post data to a REST web service:

@When("^users upload data on a project$")
public void usersUploadDataOnAProject() throws IOException {
    
}

And here is a method matching a Gherkin step and takes an argument from the text, which will be used to get information from a REST web service:

@When("^users want to get information on the (.+) project$")
public void usersGetInformationOnAProject(String projectName) throws IOException {
    
}

As you can see, the usersGetInformationOnAProject method takes a String argument, which is the project name. This argument is declared by (.+) in the annotation and over here it corresponds to Cucumber in the step text.

The working code for both above methods will be provided in the next section.

4.4. Creating and Running Tests

First, we will begin with a JSON structure to illustrate the data uploaded to the server by a POST request, and downloaded to the client using a GET. This structure is saved in the jsonString field, and shown below:

{
    "testing-framework": "cucumber",
    "supported-language": 
    [
        "Ruby",
        "Java",
        "Javascript",
        "PHP",
        "Python",
        "C++"
    ],

    "website": "cucumber.io"
}

To demonstrate a REST API, a WireMock server comes into play:

WireMockServer wireMockServer = new WireMockServer();

In addition, this tutorial will make use of Apache HttpClient API to represent the client used to connect to the server:

CloseableHttpClient httpClient = HttpClients.createDefault();

Now, let’s move on to writing testing code within step definitions. We will do this for the usersUploadDataOnAProject method first.

The server should be running before the client connects to it:

wireMockServer.start();

Using the WireMock API to stub the REST service:

configureFor("localhost", 8080);
stubFor(post(urlEqualTo("/create"))
  .withHeader("content-type", equalTo("application/json"))
  .withRequestBody(containing("testing-framework"))
  .willReturn(aResponse().withStatus(200)));

Now, send a POST request with the content taken from the jsonString field declared above to the server:

HttpPost request = new HttpPost("http://localhost:8080/create");
StringEntity entity = new StringEntity(jsonString);
request.addHeader("content-type", "application/json");
request.setEntity(entity);
HttpResponse response = httpClient.execute(request);

The following code asserts that the POST request has been successfully received and handled:

assertEquals(200, response.getStatusLine().getStatusCode());
verify(postRequestedFor(urlEqualTo("/create"))
  .withHeader("content-type", equalTo("application/json")));

The server should stop after being used:

wireMockServer.stop();

The second method we will implement herein is usersGetInformationOnAProject(String projectName). Similar to the first test, we need to start the server and then stub the REST service:

wireMockServer.start();

configureFor("localhost", 8080);
stubFor(get(urlEqualTo("/projects/cucumber"))
  .withHeader("accept", equalTo("application/json"))
  .willReturn(aResponse().withBody(jsonString)));

Submitting a GET request and receiving a response:

HttpGet request = new HttpGet("http://localhost:8080/projects/" + projectName.toLowerCase());
request.addHeader("accept", "application/json");
HttpResponse httpResponse = httpClient.execute(request);

We will convert the httpResponse variable to a String using a helper method:

String responseString = convertResponseToString(httpResponse);

Here is the implementation of that conversion helper method:

private String convertResponseToString(HttpResponse response) throws IOException {
    InputStream responseStream = response.getEntity().getContent();
    Scanner scanner = new Scanner(responseStream, "UTF-8");
    String responseString = scanner.useDelimiter("\\Z").next();
    scanner.close();
    return responseString;
}

The following verifies the whole process:

assertThat(responseString, containsString("\"testing-framework\": \"cucumber\""));
assertThat(responseString, containsString("\"website\": \"cucumber.io\""));
verify(getRequestedFor(urlEqualTo("/projects/cucumber"))
  .withHeader("accept", equalTo("application/json")));

Finally, stop the server as described before.

5. Conclusion

This tutorial covered the basics of Cucumber and how this framework uses the Gherkin domain specific language for testing a REST API.

The implementation of all these examples and code snippets can be found in a GitHub project.

The Master Class of my "REST With Spring" Course is finally out:

>> CHECK OUT THE CLASSES

Introduction to WireMock

$
0
0

I just announced the Master Class of my "REST With Spring" Course:

>> THE "REST WITH SPRING" CLASSES

1. Overview

WireMock is a library for stubbing and mocking web services. It constructs a HTTP server that we could connect to as we would to an actual web service.

When a WireMock server is in action, we can set up expectations, call the service, and then verify its behaviors.

2. Maven Dependencies

In order to be able to take advantage of the WireMock library, we need to include the following dependency in the POM:

<dependency>
    <groupId>com.github.tomakehurst</groupId>
    <artifactId>wiremock</artifactId>
    <version>1.58</version>
    <scope>test</scope>
</dependency>

3. Programmatically Managed Server

This section will cover the way to manually configure a WireMock server. i.e. without the support of JUnit auto-configuration. The usage is demonstrated by a very simple stub.

3.1. Server Setting-Up

A WireMock server can be instantiated like this:

WireMockServer wireMockServer = new WireMockServer(String host, int port);

In case no arguments are provided, the server host defaults to localhost and the server port to 8080.

The server may then be started and stopped using two simple methods:

wireMockServer.start();

And:

wireMockServer.stop();

3.2. Basic Usage

The WireMock library will be firstly demonstrated by a basic usage, where a stub for an exact URL without any further configuration is provided. Let’s create a server instance:

WireMockServer wireMockServer = new WireMockServer();

WireMock server must be running before the client connects to it:

wireMockServer.start();

The web service is then stubbed:

configureFor("localhost", 8080);
stubFor(get(urlEqualTo("/baeldung")).willReturn(aResponse().withBody("Welcome to Baeldung!")));

This tutorial makes use of the Apache HttpClient API to represent a client connecting to the server:

CloseableHttpClient httpClient = HttpClients.createDefault();

A request is executed and a response is returned, respectively, afterwards:

HttpGet request = new HttpGet("http://localhost:8080/baeldung");
HttpResponse httpResponse = httpClient.execute(request);

We will convert the httpResponse variable to a String using a helper method:

String responseString = convertResponseToString(httpResponse);

Here is the implementation of that conversion helper method:

private String convertResponseToString(HttpResponse response) throws IOException {
    InputStream responseStream = response.getEntity().getContent();
    Scanner scanner = new Scanner(responseStream, "UTF-8");
    String responseString = scanner.useDelimiter("\\Z").next();
    scanner.close();
    return responseString;
}

The following code verifies that the server has got a request to the expected URL and the response arriving at the client is exactly what was sent:

verify(getRequestedFor(urlEqualTo("/baeldung")));
assertEquals("Welcome to Baeldung!", stringResponse);

Finally, the WireMock server should be stopped to release system resources:

wireMockServer.stop();

4. JUnit Managed Server

In contrast to section 3, this section illustrates the usage of a WireMock server with the help of JUnit Rule.

4.1. Server Setting-Up

A WireMock server can be integrated into JUnit test cases by using the @Rule annotation. This allows JUnit to manage the lifecycle, starting the server prior to each test method and stopping it after the method returns.

Similar to the programmatically managed server, a JUnit managed WireMock server can be created as a Java object with the given port number:

@Rule
public WireMockRule wireMockRule = new WireMockRule(int port);

If no arguments are supplied, server port will take the default value, 8080. Server host, defaulting to localhost, and other configurations may be specified using the Options interface.

4.2. URL Matching

After setting up a WireMockRule instance, the next step is to configure a stub. In this subsection, we will provide a REST stub for a service endpoint using regular expression:

stubFor(get(urlPathMatching("/baeldung/.*"))
  .willReturn(aResponse()
  .withStatus(200)
  .withHeader("Content-Type", "application/json")
  .withBody("\"testing-library\": \"WireMock\"")));

Let’s move on to creating an HTTP client, executing a request and receive a response:

CloseableHttpClient httpClient = HttpClients.createDefault();
HttpGet request = new HttpGet("http://localhost:8080/baeldung/wiremock");
HttpResponse httpResponse = httpClient.execute(request);
String stringResponse = convertHttpResponseToString(httpResponse);

The above code snippet takes advantage of a conversion helper method:

private String convertHttpResponseToString(HttpResponse httpResponse) throws IOException {
    InputStream inputStream = httpResponse.getEntity().getContent();
    return convertInputStreamToString(inputStream);
}

This in turn makes use of another private method:

private String convertInputStreamToString(InputStream inputStream) {
    Scanner scanner = new Scanner(inputStream, "UTF-8");
    String string = scanner.useDelimiter("\\Z").next();
    scanner.close();
    return string;
}

The stub’s operations are verified by the testing code below:

verify(getRequestedFor(urlEqualTo("/baeldung/wiremock")));
assertEquals(200, httpResponse.getStatusLine().getStatusCode());
assertEquals("application/json", httpResponse.getFirstHeader("Content-Type").getValue());
assertEquals("\"testing-library\": \"WireMock\"", stringResponse);

4.3. Request Header Matching

Now we will demonstrate how to stub a REST API with the matching of headers. Let’s start with the stub configuration:

stubFor(get(urlPathEqualTo("/baeldung/wiremock"))
  .withHeader("Accept", matching("text/.*"))
  .willReturn(aResponse()
  .withStatus(503)
  .withHeader("Content-Type", "text/html")
  .withBody("!!! Service Unavailable !!!")));

Similar to the preceding subsection, we illustrate HTTP interaction using the HttpClient API, with help of the same helper methods:

CloseableHttpClient httpClient = HttpClients.createDefault();
HttpGet request = new HttpGet("http://localhost:8080/baeldung/wiremock");
request.addHeader("Accept", "text/html");
HttpResponse httpResponse = httpClient.execute(request);
String stringResponse = convertHttpResponseToString(httpResponse);

The following verification and assertions confirm functions of the stub we created before:

verify(getRequestedFor(urlEqualTo("/baeldung/wiremock")));
assertEquals(503, httpResponse.getStatusLine().getStatusCode());
assertEquals("text/html", httpResponse.getFirstHeader("Content-Type").getValue());
assertEquals("!!! Service Unavailable !!!", stringResponse);

4.4. Request Body Matching

The WireMock library can also be used to stub a REST API with body matching. Here is the configuration for a stub of this kind:

stubFor(post(urlEqualTo("/baeldung/wiremock"))
  .withHeader("Content-Type", equalTo("application/json"))
  .withRequestBody(containing("\"testing-library\": \"WireMock\""))
  .withRequestBody(containing("\"creator\": \"Tom Akehurst\""))
  .withRequestBody(containing("\"website\": \"wiremock.org\""))
  .willReturn(aResponse()
  .withStatus(200)));

Now, it is time to create a StringEntity object that will be used as the body of a request:

InputStream jsonInputStream 
  = this.getClass().getClassLoader().getResourceAsStream("wiremock_intro.json");
String jsonString = convertInputStreamToString(jsonInputStream);
StringEntity entity = new StringEntity(jsonString);

The code above uses one of the conversion helper methods define before, convertInputStreamToString.

Here is content of the wiremock_intro.json file on the classpath:

{
    "testing-library": "WireMock",
    "creator": "Tom Akehurst",
    "website": "wiremock.org"
}

HTTP requests and responses can be configured and executed as follows:

CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost request = new HttpPost("http://localhost:8080/baeldung/wiremock");
request.addHeader("Content-Type", "application/json");
request.setEntity(entity);
HttpResponse response = httpClient.execute(request);

This is the testing code used to validate the stub:

verify(postRequestedFor(urlEqualTo("/baeldung/wiremock"))
  .withHeader("Content-Type", equalTo("application/json")));
assertEquals(200, response.getStatusLine().getStatusCode());

4.5. Stub Priority

The previous subsections deal with situations where an HTTP request matches only a single stub. It would be more complicated if there is more than a match for a request. By default, the most recently added stub will take precedence in such a case. However, users are allowed to customize that behavior to take more control of WireMock stubs.

We will demonstrate operations of a WireMock server when a coming request matches two different stubs, with and without setting the priority level, at the same time. Both scenarios will use the following private helper method:

private HttpResponse generateClientAndReceiveResponseForPriorityTests() throws IOException {
    CloseableHttpClient httpClient = HttpClients.createDefault();
    HttpGet request = new HttpGet("http://localhost:8080/baeldung/wiremock");
    request.addHeader("Accept", "text/xml");
    return httpClient.execute(request);
}

Firstly, configure two stubs without consideration of the priority level:

stubFor(get(urlPathMatching("/baeldung/.*"))
  .willReturn(aResponse()
  .withStatus(200)));
stubFor(get(urlPathEqualTo("/baeldung/wiremock"))
  .withHeader("Accept", matching("text/.*"))
  .willReturn(aResponse()
  .withStatus(503)));

Next, create an HTTP client and execute a request using the helper method described right above:

HttpResponse httpResponse = generateClientAndReceiveResponseForPriorityTests();

The following code snippet verifies that the last configured stub is applied regardless of the one defined before when a request matches both of them:

verify(getRequestedFor(urlEqualTo("/baeldung/wiremock")));
assertEquals(503, httpResponse.getStatusLine().getStatusCode());

Let’s move on to stubs with priority levels being set, where a lower number represents a higher priority:

stubFor(get(urlPathMatching("/baeldung/.*"))
  .atPriority(1)
  .willReturn(aResponse()
  .withStatus(200)));
stubFor(get(urlPathEqualTo("/baeldung/wiremock"))
  .atPriority(2)
  .withHeader("Accept", matching("text/.*"))
  .willReturn(aResponse()
  .withStatus(503)));

Creation and execution of an HTTP request:

HttpResponse httpResponse = generateClientAndReceiveResponseForPriorityTests();

The following code validates the effect of priority levels, where the first configured stub is applied instead of the last:

verify(getRequestedFor(urlEqualTo("/baeldung/wiremock")));
assertEquals(200, httpResponse.getStatusLine().getStatusCode());

5. Conclusion

This tutorial introduced WireMock and how to set up as well as configure this library for testing of REST APIs using various techniques, including matching of URL, request headers and body.

The implementation of all the examples and code snippets can be found in a GitHub project.

The Master Class of my "REST With Spring" Course is finally out:

>> CHECK OUT THE CLASSES

Spring Boot Support for jOOQ

$
0
0

I just released the Starter Class of "Learn Spring Security":

>> CHECK OUT THE COURSE

1. Overview

This tutorial is a follow-up to the Introduction to jOOQ with Spring article, covering the ways that jOOQ can be used within a Spring Boot application.

If you have not gone through that tutorial, please take a look at it and follow the instructions in section 2 on Maven Dependencies and in section 3 on Code Generation. This will generate source code for Java classes representing tables in the sample database, including Author, Book and AuthorBook.

2. Maven Configuration

In addition to the dependencies and plugins as in the previous tutorial, several other components needs to be included in the Maven POM file to make jOOQ work with Spring Boot.

2.1. Dependency Management

The most common way to make use of Spring Boot is to inherit from the spring-boot-starter-parent project by declaring it in the parent element. However, this method is not always suitable as it imposes an inheritance chain to follow, which may not be what users want in many cases.

This tutorial uses another approach: delegating the dependency management to Spring Boot. To make it happen, just adds the following dependencyManagement element to the POM file:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>1.3.5.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

2.3. Dependencies

In order for Spring Boot to control jOOQ, a dependency on the spring-boot-starter-jooq artifact needs to be declared:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jooq</artifactId>
    <version>1.3.5.RELEASE</version>
</dependency>

3. Spring Boot Configuration

3.1. Initial Boot Config

Before we get to the jOOQ support, we’re going to start preparing things with Spring Boot.

First, we’re going to take advantage of the persistence support and improvements in Boot and our data access information in the standard application.properties file. That way, we can skip over defining the beans and making these configurable via a separate properties file.

We’ll add the URL and credentials here to define our embedded H2 database:

spring.datasource.url=jdbc:h2:~/jooq
spring.datasource.username=sa
spring.datasource.password=

We’re also going to define a simple Boot application:

@SpringBootApplication
@EnableTransactionManagement
public class Application {
    
}

We’ll leave this one simple and empty and we’ll define all other bean declarations in another configuration class –  InitialConfiguration.

3.2. Bean Configuration

Let’s now define this InitialConfiguration class:

@Configuration
public class InitialConfiguration {
    // Other declarations
}

Spring Boot has automatically generated and configured the dataSource bean based on properties set in the application.properties file, so we do not need to register it manually. The following code lets the auto-configured DataSource bean to be injected into a field, and shows how this bean is used:

@Autowired
private DataSource dataSource;

@Bean
public DataSourceConnectionProvider connectionProvider() {
    return new DataSourceConnectionProvider
      (new TransactionAwareDataSourceProxy(dataSource));
}

Since a bean named transactionManager has also been automatically created and configured by Spring Boot, we do not need to declare any other bean of the DataSourceTransactionManager type as in the previous tutorial to take advantage of Spring transaction support.

DSLContext bean is created in the same way as in the PersistenceContext class of the preceding tutorial:

@Bean
public DefaultDSLContext dsl() {
    return new DefaultDSLContext(configuration());
}

Lastly, a Configuration implementation needs to be provided to DSLContext. Since Spring Boot is able to recognize the SQL dialect in use through the existence of H2 artifact on the classpath, a dialect configuration is no longer necessary:

public DefaultConfiguration configuration() {
    DefaultConfiguration jooqConfiguration = new DefaultConfiguration();
    jooqConfiguration.set(connectionProvider());
    jooqConfiguration
      .set(new DefaultExecuteListenerProvider(exceptionTransformer()));

    return jooqConfiguration;
}

4. Using Spring Boot with jOOQ

To make the demonstration of Spring Boot support for jOOQ easier to be followed, the test cases in the prequel of this tutorial are reused with a little change to its class-level annotations:

@SpringApplicationConfiguration(Application.class)
@Transactional("transactionManager")
@RunWith(SpringJUnit4ClassRunner.class)
public class SpringBootTest {
    // Other declarations
}

It is clear that rather than adopting the @ContextConfiguration annotation, Spring Boot uses @SpringApplicationConfiguration to take advantage of SpringApplicationContextLoader context loader to test applications.

Test methods for inserting, updating and deleting data are exactly the same as in the previous tutorial. Please have a look at section 5 of that article on Using jOOQ with Spring for more information. All the tests should be successfully executed with the new configuration, proving that jOOQ is fully supported by Spring Boot.

5. Conclusion

This tutorial dug deeper into the use of jOOQ with Spring. It introduced the ways for a Spring Boot application to take advantage of jOQQ to interact with a database in a type-safe manner.

The implementation of all these examples and code snippets can be found in a GitHub project.

Get the early-bird price (20% Off) of my upcoming "Learn Spring Security" Course:

>> CHECK OUT THE COURSE

Viewing all 3761 articles
Browse latest View live


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