Explore the changes for Servlet 3.1 and Servlet 4.0 specifications in Spring 5.x.
- [Instructor] As we jump into some of the more concrete changes of Spring 5.0, we're going to start with Spring Web and specifically, we're going to look at some of the major changes to the servlets. Now, with Spring 5.0, we got full support for Servlet 3.1. Now, prior to this full support, some of the filter methods were not fully compliant with the spec, and as such, there were some issues with the way that it actually implemented Servlet 3.1. Now, these commonly are used in things like Spring Security, but not every developer was actually impacted by these changes.
But it's just good to know that it is now compatible fully with Servlet 3.1. A much more interesting change came from the PushBuilder API and that's part of the HTTP 2.0 spec. We can now push resources to the client from the server, which of course, improves download speed. And this is especially important for dealing with something like an e-commerce site, where page loads directly translate to capitalization within our website. By being able to push resources to the client instead of have it pull, we can get a much better page load time and ultimately, have a much better user experience for our customers.
Now, in order to use this API, we have to be using Servlet 4.0, which means we need to a container like Tomcat 9. And essentially, you're going to inject PushBuilder into any method that has RequestMapping on it and then you can set up the push operation from there. So let's take a look at what that looks like in code. I've loaded up a base application from the exercise files and it's a Spring Boot application that I've added a few things to. Now, though this is really about Spring 5.0, we're going to use Spring Boot because setting up a web application is much easier in Spring Boot.
And we're using an embedded Tomcat 9 to do this. So let's take a look at some of the changes that I had to make. In src, main, resources, I want you to take a look. We've got a couple of files here. One of them is the keystore. Now, in order to use Tomcat 9 and to do HTTP 2.0, you have to be using HTTPS, so you have to provide it a keystore. So I've gone ahead and created a self-signed keystore and we'll look at that here in moment. I've also added some application properties in order to enable HTTP2 to load that keystore in and to set some keystore password information.
And you can set those properties in your application.properties. Or if you're using YAML, you can do the same thing. I've also added a template. And this is just a basic HTML template that has an h1 tag and it loads an image and that image, we're loading from our static images. Now, I'm using Thymeleaf as a view resolver. Even though we're not using any Thymeleaf-specific annotations here, it's still involved as doing the view resolution. All right, so let's jump into actually implementing this. So the first thing that we're going to do is we're going to create a new class and that class is going to be in com.frankmoley.lil in src, main, java.
And we're going to call this PushController. Okay, so let's go ahead and shrink our window here, so we can actually see our code. Now, to this class, we're going to add a couple annotations. The first annotation is going to be @Controller and then we're going to add an @RequestMapping and we're going to send this to push. Go ahead and import that in. Now, we're going to add a couple methods. So the first one, we're going to annotate with @GetMapping and we're going to call this one with, so this will be the one that has our PushBuilder actually on it.
So we're going to give that method a signature. Public String demoWithPush. And we will set in the PushBuilder as a parameter and Spring will go ahead and inject that in as part of the servlet request. Go ahead and make sure that it's populated. So if null does not equal PushBuilder, we're going to do a PushBuilder.path. And the path we're going to set is actually the same that's in our template.
And it's going to be an absolute path, so /img/LinkedInLearning.jpg and then .push. And then we will simply return our push view. Now, we're going to replicate basically the same method here but this time, we're going to do it on without. Public String demoWithoutPush. This time, we're not going to pass in a parameter and we will simply return our view.
Right, so that's all there is to it. Make sure you put in your semicolons. Now, I have a feature in IntelliJ Ultimate Edition that allows me to just run a Spring application. If you're not using IntelliJ Ultimate Edition, you may not have something like this. What essentially it does is it goes to this NewFeaturesApp. You're just going to run the main method. Now, I get this built-in with IntelliJ Ultimate Edition. It does all of that configuration for me. So I'm going to go ahead and leverage that. We'll allow Maven to do the compilation and build of our application and start up.
And once it's got started here, we'll jump over into Chrome. And in our Chrome window, I want you to go ahead and open up Developer Tools. And we're first going to navigate to https://localhost:8080/pushwithout. Now, you're going to notice first thing is that you're going to get a Connection is not Private warning and that's because we're using a self-signed certificate. Go ahead and accept that.
In the real world, I wouldn't recommend doing that, but for the purpose of this demo, we're fine. Now, what you'll see here is that there's this big latency as I was waiting for that, so let's go ahead and remove our resource from the cache. Just going to right-click on it and remove it from cache and we'll do the same for the HTML. And now, we'll reload our page. Now, we get a more realistic image of what time it actually took to load this. So this loaded up at 114 milliseconds. And you'll see that we loaded the page and then we actually had the loading of the image and it was pull after the fact.
And that's what we're trying to avoid by doing this. So just to make everything good, let's go ahead and remove our HTML and remove our image from our browser cache once again. Now, this time, we'll go to the with page and you'll see we have a much different view on our waterfall here in DevTools. Let me go and expand this out a little bit. You'll see that we actually have now pushed the resource to the page instead of pulled it. Another thing I want you to notice, I added in a protocol column into my view, which shows that this is HTTP2 by showing this h2 value.
But the really important thing here is this actual view of the waterfall showing me how the content was pushed to our application instead of actually having it pulled. So you'll see we see Receiving Push. Now, while our time didn't really improve by doing this, the simple fact is we're only loading one resource. Imagine a page with lots of resources, like an e-commerce application that shows lots of product images. This is where you start to really see the value of push in a real world application.
So give it a try. It may help you have some page load time improvements, which will always make your customers happy and your boss happy.
- Spring core changes
- Spring web changes
- Spring test changes
- Spring Boot changes