Java

Server Side Rendering with Spring Boot and React

Server Side Rendering with Spring Boot and React

Server side rendering of React apps in Spring Boot is supported using Spring’s script template views. Although still young, script template views provide the foundation for building isomorphic React apps. I will show you how this is done using React’s server side rendering capabilities and later I will explain how to add support for React Router and Redux.

In a previous post I wrote a little over a year ago, I covered the very basics of Spring’s script template views with a small app that used EJS script templates. If you followed a link from somewhere expecting that post, you’ve been redirected here because this post will be much more complete.

You can find the full source of the sample application I built on my GitHub repo. If you’d like to see an alternative to JSR-223, be sure to check out the J2V8 branch of the project. The J2V8 version performs better than the Nashorn version.

Basic Setup

The basic setup is still the same. First I’ve defined a ViewResolver typed bean which returns a new ScriptTemplateViewResolver with prefix of /public/ and suffix of .html. Next I’ve defined a ScriptTemplateConfigurer bean. The recommended approach is to instruct Spring to create a non-shared ScriptEngine when using libraries like React that are not designed for concurrency.

Lastly, I’ve defined a couple of scripts that are on the classpath named polyfill.js and server.js, and told Spring that the render method is called simply render.

@Bean
public ViewResolver viewResolver() {
    return new ScriptTemplateViewResolver("/public/", ".html");
}

@Bean
public ScriptTemplateConfigurer scriptTemplateConfigurer() {
    ScriptTemplateConfigurer configurer = new ScriptTemplateConfigurer();
    configurer.setEngineName("nashorn");
    configurer.setScripts(
            "static/polyfill.js",
            "public/server.js"
    );
    configurer.setRenderFunction("render");
    configurer.setSharedEngine(false);
    return configurer;
}

Handling Requests

Handing requests to render the script templates is done by creating a root or index controller. I can’t simply setup a root @GetMapping or @GetMapping("/") because that will intercept the client side assets. When requests come in for client.js or client.css for example, the response body would be the contents of a script template. To circumvent this, the get mapping uses a regex negative lookahead to ensure it does not match against any static assets. It’s certainly not a very friendly solution, but it works for this example.

@Controller
puglic class IndexController
    @GetMapping("/{path:(?!.*.js|.*.css|.*.jpg).*$}")
    public String index() {
        return "index";
    }
}

Server Side Scripts

First is the server.js script which will be built using Webpack and written to src/main/resources/public. Using a bundling utility like Webpack makes it easier to use libraries like React in server side rendering, because you don’t have to tell Nashorn about them when initializing a script engine.

Using renderToString from ReactDOM, I can render the App component server side. I’ve attached the render function to window which will make it visible to the script engine when it needs to render the templates. The result will be injected into the template where the SERVER_RENDERED_HTML placeholder exists and the final result of the render function will be written to the view.

import React from 'react';
import {renderToString} from 'react-dom/server';
import App from 'components/App';

window.render = (template) => template.replace('SERVER_RENDERED_HTML', renderToString(<App/>));

Next is the polyfill.js script which I’ll place in src/main/resources/static so that it doesn’t get clobbered by the Webpack build. This script doesn’t need to ever get rebuilt, it’s simply there to provide alternatives to variables that are not available on the server.

var window = this;
var console = {
  error: print,
  debug: print,
  warn: print,
  log: print
};
window.setTimeout = function() {};
window.Promise = {
  resolve: function() {},
  reject: function() {}
};

The Template

The next piece of the puzzle is a template called index.html. This sample shows the result of a Webpack build. The template has been written to src/main/resources/public and the static assets have been injected. What’s important to take note of is that these assets are being resolved to an absolute path. No matter what page gets visited, they will always be resolved from the root path and not relative. Also worth mentioning is the SERVER_RENDERED_HTML placeholder that I spoke about earlier. This is where the result of the server side render function will be injected.

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link href="/client.css?9486db0c3127751c07bf" rel="stylesheet"></head>
<body>
<!--[if lt IE 7]>
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
<![endif]-->

<div id="app">SERVER_RENDERED_HTML</div>

<script type="text/javascript" src="/client.js?9486db0c3127751c07bf"></script></body>
</html>

Rendering Client Side

The client.js script is very similar to the server.js script. The main difference is that it uses the browser side render function from ReactDOM and renders the App inside an actual HTML element.

import React from 'react';
import {render} from 'react-dom';
import App from 'components/App';

render(<App/>, document.getElementById('app'));

Let’s Add Routing

This is where the benefits of server side rendering become more obvious. I’m using React Router 4, which is still in alpha stage, but works for this example. I tried really hard to make this work with React Router 3, but I kept hitting one road block after the next. React Router 4’s major implementation change is that it’s now more focused on being component based and embracing the React way of doing things. You can read more about why here.

Let’s start by installing React Router 4 with the command npm install --save [email protected].

Populate The Model

In the index request mapping, I need to add the model information which will be made available to the server side render function when the view is resolved. The only thing I’m adding is a Java Map which is serialized to a JSON encoded string using Jackson’s ObjectMapper.

Contained inside the map is a single key named location which maps to the servlet path from the request, as well as any query string parameters. This value will be used by the server render function to initialize the ServerRouter.

@GetMapping("/{path:(?!.*.js|.*.css|.*.jpg).*$}")
public String index(Model model, HttpServletRequest request) throws JsonProcessingException {
    ObjectMapper mapper = new ObjectMapper();
    Map<String, Object> req = new HashMap<>();

    String root = request.getServletPath().equals("/index.html") ? "/" : request.getServletPath();

    if(request.getQueryString() != null)
        req.put("location", String.format("%s?%s", root, request.getQueryString()));
    else
        req.put("location", root);

    model.addAttribute("req", mapper.writeValueAsString(state));
    return "index";
}

Revisiting the Server Side Render Function

The server.js script requires some additional instrumentation to support React Router. The main difference is that the render function now accepts a second argument containing a model that I just populated in the index request mapping. I will retrieve the location property and use it to initialize the ServerRouter component. The result will be injected into the template at the same placeholder as before. The location will get passed down the component tree and any child routing components looking for that specific location will render.

import React from 'react';
import {renderToString} from 'react-dom/server';
import {ServerRouter, createServerRenderContext} from 'react-router';
import App from 'components/App';

window.render = (template, model) => {
  const context = createServerRenderContext();
  const req = JSON.parse(model.get('req'));
  const markup = renderToString(
    <ServerRouter location={req.location} context={context}>
      <App/>
    </ServerRouter>
  );
  return template.replace('SERVER_RENDERED_HTML', markup);
};

Time to Update the Client

The client.js script needs to be changed as well. It’s still quite similar to the server.js script, but uses a BrowserRouter instead of a ServerRouter. I don’t need to initialize any location this time because it will listen to the browser URL to determine what to render when the client side takes over.

import React from 'react';
import {render} from 'react-dom';
import {BrowserRouter} from 'react-router';
import App from 'components/App';

const markup = (
  <BrowserRouter>
    <App/>
  </BrowserRouter>
);

render(markup, document.getElementById('app'));

Preloading State with Redux

Now that the app is capable of rendering server side and can handle routing as well, it’s time to add preloaded state to the mix using Redux on the server. To get things started, I’ve added Spring Data JPA and Spring Data REST to the project. I’ve also added an H2 in-memory database and setup an Item entity with a REST repository providing HAL formatted output. Be sure to refer to my GitHub repository as I’ll only be showing key elements here.

I’ve setup the REST repository with a basePath of /api. In order to prevent the index request mapping from intercepting those calls, I need to update the @GetMapping. You’ll also see that I’m adding a new model attribute named initialState which contains some data from the item repository.

@GetMapping("/{path:(?!.*.js|.*.css|.*.jpg|api).*$}")
public String index(Model model, HttpServletRequest request) throws JsonProcessingException {
  ObjectMapper mapper = new ObjectMapper();

  Map<String, Object> req = new HashMap<>();
  String root = request.getServletPath().equals("/index.html") ? "/" : request.getServletPath();
  if(request.getQueryString() != null)
    req.put("location", String.format("%s?%s", root, request.getQueryString()));
  else
    req.put("location", root);
  model.addAttribute("req", mapper.writeValueAsString(req));

  Map<String, Object> initialState = new HashMap<>();
  initialState.put("items", itemRepository.findAll());
  model.addAttribute("initialState", mapper.writeValueAsString(initialState));
  return "index";
}

Rendering the Preloaded State on the Server

In order to preload the state in Redux and maintain server side rendering, I will create a store and pass it the initial state from the model. The markup is only slightly different, there’s now a top level Provider component which receives the store. Lastly, I’m injecting the initial state into the template using the SERVER_RENDERED_STATE placeholder.

When I first published this post, I was using JSON.stringify(initialState) to replace SERVER_RENDERED_STATE. After reading an interesting post on how this introduces an XSS vulnerability, I’ve updated it to use serialize-javascript.

import React from 'react';
import {renderToString} from 'react-dom/server';
import {ServerRouter, createServerRenderContext} from 'react-router';
import {createStore, applyMiddleware} from 'redux';
import thunkMiddleware from 'redux-thunk';
import {Provider} from 'react-redux';
import serialize from 'serialize-javascript';
import reducer from './reducers';
import App from 'components/App';

window.render = (template, model) => {
  const context = createServerRenderContext();
  const req = JSON.parse(model.get('req'));
  const initialState = JSON.parse(model.get('initialState'));

  const store = createStore(reducer, initialState, applyMiddleware(thunkMiddleware));

  const markup = renderToString(
    <Provider store={store}>
      <ServerRouter location={req.location} context={context}>
        <App/>
      </ServerRouter>
    </Provider>
  );

  return template
    .replace('SERVER_RENDERED_HTML', markup)
    .replace('SERVER_RENDERED_STATE', serialize(initialState, {isJSON: true}));
};

Adding Preloaded State to the Template

The only thing I need to do in the template is define a script at the end of the body which defines the __PRELOADED_STATE__ variable who’s value will be injected using the SERVER_RENDERED_STATE placeholder.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title></title>
  <meta name="description" content="">
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<!--[if lt IE 7]>
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
<![endif]-->

<div id="app">SERVER_RENDERED_HTML</div>
<script>
  window.__PRELOADED_STATE__ = SERVER_RENDERED_STATE;
</script>

</body>
</html>

Rendering the Preloaded State on the Client

Yet again, the client is similar to the server. It also wraps the existing markup with a Provider component that receives an Redux store. The main difference is where the preloaded state comes from. This time it comes from the __PRELOADED_STATE__ variable that I just defined in the template.

import React from 'react';
import {render} from 'react-dom';
import {BrowserRouter} from 'react-router';
import {createStore, applyMiddleware} from 'redux';
import thunkMiddleware from 'redux-thunk';
import {Provider} from 'react-redux';
import reducer from './reducers';
import App from 'components/App';

const store = createStore(reducer, window.__PRELOADED_STATE__, applyMiddleware(thunkMiddleware));

const markup = (
  <Provider store={store}>
    <BrowserRouter>
      <App/>
    </BrowserRouter>
  </Provider>
);

render(markup, document.getElementById('app'));

Conclusion

That’s it! This was quite a learning experience for me. I tried several things along the way that failed, but never lost sight of my goal. The index request mapping saw several iterations, because I’m not a regex expert, but who is? Perhaps Spring even offers a better approach that I’m ignorant of.

I also spent a lot of time trying to make this work with React Router 3, which ultimately proved to be unfruitful. Adding Redux was pretty straight forward with a little guidance from their documentation. As always, I welcome any feedback. If you think this post needs some improvements, feel free to comment.

Posted by Patrick Grimard in Programming, 0 comments
Cross-Origin Resource Sharing (CORS) with Spring

Cross-Origin Resource Sharing (CORS) with Spring

The Spring team has made CORS implementation much easier in recent versions of Spring, so I’ll try to simply not repeat what the docs already cover.

Deconstructing the AJAX Request

The basic idea of CORS is to declaratively allow client applications to make AJAX requests originating outside of the service application’s domain. By default, if CORS is not setup, then no requests originating outside of the domain will be permitted. When a client application makes an AJAX request, the browser initially sends a preflight OPTIONS request to determine what the client is permitted to do. This is true for all requests except a GET request. The server response to the OPTIONS request contains headers that instruct the browser on what the client is allowed to do when making the actual AJAX request. These response headers each serve a specific purpose.

The first header is Access-Control-Allow-Origin which tells the browser which origins can make AJAX requests. The value of this header could be * which indicates all origins can make requests, or it could contain an actual domain such as http://example.com which specifies only requests originating from http://example.com are permitted.

Next is the Access-Control-Expose-Headers header which tells the browser which headers it is allowed to access when receiving responses from the server.

The Access-Control-Max-Age header is used to tell the browser how long it can cache the results of the OPTIONS request in seconds. Setting this value to a reasonable amount of time means the browser won’t need to make an OPTIONS request every time until the time expires.

The Access-Control-Allow-Credentials is a bit more interesting. This header tells the browser if the response to the AJAX request can be exposed to the client when the credentials flag is set to true on the AJAX request. This header also allows the client to send cookies to the server, such as authentication cookies. When a client makes an AJAX request with credentials set to true, the response from the server must contain the Access-Control-Allow-Credentials with value true, otherwise the response is ignored by the browser and not available to the client. This has certain implications when making CORS GET requests. Like I mentioned earlier, a GET request does not invoke an OPTIONS preflight request first. So when making a GET request with credentials set to true, the server must respond with the header Access-Control-Allow-Credentials set to true as well in order for the response to be made available to the client. Another point to note is if the Access-Control-Allow-Credentials is set to true, then the Access-Control-Allow-Origin header coming back from the server must not contain the wildcard *. It must contain an actual domain, otherwise the browser will ignore the response.

The Access-Control-Allow-Methods header tells the browser which methods are permitted when making an AJAX request. This header can contain 1 or more methods, ie: GET, POST, etc.

The Access-Control-Allow-Headers header tells the browser which headers can be used when making an AJAX request.

CORS Global Configuration

When I originally wrote this post, I attempted to keep CORS configuration out of my controllers. Although Spring has made adding CORS to a controller much cleaner, I’ll talk about global configuration first which has also seen it’s fair share of improvements. The following global configuration enables CORS requests from any origin to any endpoint in the application.

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
  @Override
  public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/**");
  }
}

If you want to lock this down a bit more, the registry.addMapping method returns a CorsRegistration object which can be used for additional configuration. There’s an allowedOrigins method which you can use to specify an array of allowed origins. This can be useful if you need to load this array from an external source at runtime. There’s also allowedMethods, allowedHeaders, exposedHeaders, maxAge and allowCredentials which can be used to set the response headers as I’ve described them above.

CORS Fine Grain Configuration

Spring has recently added the @CrossOrigin annotation which can be used in controllers. This allows for a more fine grain configuration.

@RestController
@RequestMapping("/orders")
public class OrderController {
  @CrossOrigin
  @RequestMapping(value = "/{orderNumber}", method = RequestMethod.GET)
  public Order order(@PathVariable long orderNumber) {
    // lookup the order and return it
  }
}

As you can see, all we’ve done here is add the @CrossOrigin annotation to an ordinary request mapping method. With no additional attributes, this would expose the /orders/{orderNumber} endpoint to any origin. You may also use a combination of controller level and method level annotations. As a result, Spring combines the controller level and method level annotations when building the response headers. The @CrossOrigin annotation also contains attributes very similar to the the global configuration methods, such as origins, methods, allowedHeaders, exposedHeaders, maxAge and allowCredentials.

Conclusion

Hopefully I’ve done a better job explaining CORS concepts in this updated post. As well I hope that I’ve shown you how much simpler it is to configure CORS in a Spring application using all the improvements that have been made.

Happy Coding!

Posted by Patrick Grimard in Programming, 0 comments
Encrypting and Decrypting Configuration Property Values in Spring Cloud

Encrypting and Decrypting Configuration Property Values in Spring Cloud

As a follow up to my recent post on Microservices with Spring Cloud, this post will cover encrypting and decrypting config property values.  The Spring Cloud docs cover this aspect briefly, so I’ll go through the steps I took to get this working both in test on my laptop, and on a dev server.  I’ll be using the same environment as my last blog post, so that is a standalone Eureka server, a config server, and simple microservice.  Full disclosure, I am by no means a security expert, so if you see something wrong, feel free to let me know.

Install JCE

In order to enable encryption and decryption of config property files, you need to install the unlimited strength Java Cryptography Extension (JCE) in your config server environment.  This doesn’t come with the JVM by default.  The one that comes with the JVM is of limited strength.

Head on over to Oracle’s website and download the unlimited strength JCE.  Once downloaded, you’ll need to extract the zip file somewhere and the result will be three files.

local_policy.jar
README.txt
US_export_policy.jar

You need to copy the local_policy.jar and US_export_policy.jar into $JAVA_HOME/jre/lib/security directory.  Before doing this though, you should make a backup copy of the existing policy files.  I’m running on OSX, so for me it’s as easy as this.  The same applies to doing this on a Linux server, as is the case for me.

sudo mv US_export_policy.jar US_export_policy.jar.bak
sudo mv local_policy.jar local_policy.jar.bak

Now you can safely copy the JCE policy files you downloaded into $JAVA_HOME/jre/lib/security.

Create an encryption key or keystore

Depending on your needs, you can create a symmetric (shared) or asymmetric (RSA) key.  The Spring Cloud docs point out that the symmetric key is convenient as you merely need to provide a secret key to the environment, but that comes at the expense of being less secure.  So for a symmetric key, either add an encrypt.key property to application.yml with a secret key, or add an environment variable ENCRYPT_KEY.  For this blog post, I’ll focus on the asymmetric key approach which uses a keystore file.

The JDK comes with the keytool utility which allows you to create a keystore.  This example is copied directly from the Spring Cloud docs.  So you should use a different password, alias and secret key.

keytool -genkeypair -alias mytestkey -keyalg RSA \
  -dname "CN=Web Server,OU=Unit,O=Organization,L=City,S=State,C=US" \
  -keypass changeme -keystore server.jks -storepass letmein

By default, this command will create a key that is valid for only 90 days.  If you want something longer than that, you’ll need to add the validity argument which takes a value in days.

keytool -genkeypair -alias mytestkey -keyalg RSA \
  -dname "CN=Web Server,OU=Unit,O=Organization,L=City,S=State,C=US" \
  -keypass changeme -keystore server.jks -storepass letmein \
  -validity 365

The simple approach to using this new keystore from your config server would be to include the password, alias and secret key in application.yml.

encrypt:
  key-store:
    location: file://${user.home}/server.jks
    password: letmein
    alias: mytestkey
    secret: changeme

A better approach would be to use environment variables.  The location property is probably safe in the application.yml file, but you could also control it with an environment variable.

ENCRYPT_KEY_STORE_PASSWORD=letmein
ENCRYPT_KEY_STORE_ALIAS=mytestkey
ENCRYPT_KEY_STORE_SECRET=changeme

Let’s encrypt!

Now that we have a config server that’s able to encrypt and decrypt data, let’s start by encrypting a property value.  The config server exposes a couple of handy endpoints.  There’s the /encrypt endpoint to encrypt data, and the /decrypt endpoint to decrypt data.

curl localhost:8888/encrypt -d 'Hello Spring Boot!'

The result of this command will be the Hello Spring Boot! string as an encrypted string that we can add to the git repository backing the config server. Here’s the application.yml file served by my config server, but now updated with the encrypted message.

message: '{cipher}AQCLJG5FvxQrLAC6Q9iDmkegrIh1yJ4K2BeRzNdu3PkMZXv1cMSJ/C3flllHITinxgKecX3I8MPIf6sSsSIaZCV9YW/MzQ6VYVQ8Mt4GIxbPfFRFpvOhBmsCDomZ5lQ5eWoDmS1yHpIMeES37YVLW/uM8LJTNRg16ywFy/pdxbhzQt5g0KEe8N8FIDk32lrvo5qB3e0hYv3gOfUAEYzt9ZjyQmXJqpAgWB+85Su7gIyxW7f5Q20hNoA5RgG87ofrmFD2M0LgcjQMbeEKIUqYAZjOYKAJG/xUwU9WEkTgw8nKgSmkkPxMPorSIBwwgXlYDGlLU3DM+lT91Nky8ydH3CTuKSN1j7OhfRRLWPcYLNFC+BLqT/4tjcCrVP2tvCepN/yZ9pN8eA6L1zQqoHPzpBkj'

Notice the {cipher} prefix.  This is a hint to the config server that this property needs to be decrypted before sending it to a client application.

Let’s decrypt!

The Spring Cloud docs for Brixton.M5 mention that any client needs to include spring-security-rsa on it’s classpath in order to decrypt the encrypted properties.

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-rsa</artifactId>;
</dependency>

If you’re application connects to Eureka to get it’s configuration from a remote config server, then the encrypted properties will be returned to your application already decrypted during the bootstrap phase of your application, before the main application context is initialized.  So this dependency is not needed in your application.

This has been my own observation without seeing anything explicitly mentioned in the docs.  I believe this dependency is only required if your application connects to the config server directly, if you’ve included spring-cloud-starter-config as a dependency.

Use decrypted properties

The following is a simple message service.  The only real difference is the @RefreshScope annotation on the service.  This annotation will create a proxy that caches the configuration properties in the environment.  When this application’s context is refreshed, the cache will be invalidated and repopulated with the most current configuration properties, making those new values available to the application.  In this case, the value of message will be the decrypted string Hello Spring Boot!

@Service
@RefreshScope
public class MessageServiceImpl implements MessageService {

  private Environment env;

  @Inject
  public MessageServiceImpl(Environment env) {
    this.env = env;
  }

  public String getMessage() {
    return env.getProperty("message");
  }
}

Congratulations!

You now have a config server that’s able to decrypt encrypted property values.  The real benefit to this is that you can centralize sensitive information that multiple services can consume and you don’t need to configure these values in every application that needs them.

Posted by Patrick Grimard in Programming, 0 comments
How to build a Spring Boot application using IntelliJ IDEA

How to build a Spring Boot application using IntelliJ IDEA

Welcome back!  This tutorial will be a basic introduction to creating a Spring Boot application using IntelliJ IDEA.  No prior knowledge is expected, the main purpose of this post is to help anyone new to Spring get rolling quickly writing Spring applications with Spring Boot in IntelliJ.  For further reading, be sure to check out Spring’s Guide section for other tutorials on writing Spring Boot applications.

Update 2015-08-26: This tutorial has been updated with the latest version of IntelliJ 15 EAP at the time of writing and describes building an app with IntelliJ’s built in support for Spring Initializr.

Create your new project with IntelliJ

Open up IntelliJ and click on the Create New Project option.

Next, select Spring Initializr from the project type in the left panel, select your Project SDK and then click Next.  The Initializr Service URL should already be populated.

Next enter your Maven project properties including name, project type, packaging, Java version, group ID, artifact ID and version for your application.  Complete this step by entering a project description and root package.  Then click Next.

Next select your Spring Boot version and any Spring Framework dependency your project will require.  All of Spring’s projects are available from web, security, cloud, database and so on.  Click Next once you’ve selected all your dependencies.

The final step is entering your IntelliJ IDEA project settings.  Click Finish when complete.

At this point, IntelliJ may prompt you to add your pom.xml as a managed Maven project.  Click Add as Maven Project to dismiss this prompt and have your Maven dependencies automatically synced with your IntelliJ build path.  You’ll see that using Spring Boot, there’s many dependencies you don’t have to add yourself thanks to Spring Boot’s starter POMs.

Exploring the Project

Open up your project’s pom.xml and you’ll see what we just built.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.patrickgrimard</groupId>
    <artifactId>spring-boot-hello-world</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>spring-boot-hello-world</name>
    <description>Sample Spring Boot Project</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.2.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

The generated application class

@SpringBootApplication
public class SpringBootHelloWorldApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootHelloWorldApplication.class, args);
    }
}

This class although very simple looking has a lot going on.  First, it’s been annotated with the @SpringBootApplication annotation. This declares the class as a @Configuration class for your application.  You can define additional @Bean definitions in it if you like.  It adds @ComponentScan to locate any other beans you define in your project.  Finally it adds @EnableAutoConfiguration in order to enable automatic configuration of your Spring application context by determining what you have available on your classpath.

Create a REST Controller

The next thing you may want to do at this point is add a controller to your application to handle servlet requests.

@RequestMapping("/api")
@RestController
public class WidgetController {

    @RequestMapping(method = RequestMethod.GET, produces = {MediaType.APPLICATION_JSON_VALUE})
    public Widget index() {
        return new Widget("green", 10, 7);
    }
}

The first annotation on this controller is @RequestMapping("/api") and it tells us that this controller will handle all requests beginning with /api in our application.  The second annotation @RestController tells Spring two things.  First this class is a controller bean that should be managed by Spring and will be picked up by component scanning.  Secondly, all methods inherently use @ResponseBody semantics which means the return value will become the body of our servlet response.

I’ve only defined a single method in this controller responding to the GET HTTP method, and it produces JSON output.  My method merely returns a new instance of the Widget class.  Your controller will return something else that’s related to your business case.

Running your Application

At this point, you can run your application simply by right clicking inside your application class and selecting Run SpringBootHelloWorldApplication.main().  Then browse to http://localhost:8080/api and you’ll see the response from the controller and request mapping we just created.

Wrapping Up!

By now, you should know how to create a new Spring Boot application from scratch using IntelliJ, it’s really quite simple with the introduction of Spring Initializr built into the IDE.  I’ve also provided a very brief introduction to writing a Spring Boot app to get you started.

If you’d like to view the source code of this application, it’s available on Github https://github.com/pgrimard/spring-boot-hello-world.

Posted by Patrick Grimard in Programming, 0 comments
String to Date Conversion with Spring

String to Date Conversion with Spring

Recently I was working on a Spring MVC project.  I had an @RequestMapping where one of the method’s @RequestParam arguments was a java.util.Date type.  I didn’t think much of it as I was writing the method, until when I tested the application, it threw an exception.  I quickly discovered that there’s no String to Date converter registered by default.

public class ApplicationConversionServiceFactoryBean extends FormattingConversionServiceFactoryBean {

  @Override
  protected void installFormatters(FormatterRegistry registry) {
    super.installFormatters(registry);
    registry.addConverter(getStringToDateConverter());
  }

  public Converter<String, Date> getStringToDateConverter() {
    return new Converter<String, Date>() {

      @Override
      public Date convert(String source) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
          return sdf.parse(source);
        } catch (ParseException e) {
          return null;
        }
      }
    };
  }
}

And that’s all there is to it.  Simply replace the SimpleDateFormat pattern with the pattern you need in your application, register the conversion service in your MVC config as mentioned in my previous post and voila!

Posted by Patrick Grimard in Programming, 0 comments