[MUSIC] We've refactored the video service that we built with servelets to use the Spring framework. And what we're going to see is that spring vastly simplifies our lives. Particularly with respect to getting data from the client and ensuring that it's at least minimally validated and in a format that we expect. And also for getting that data into objects that we can actually use and do something with. So what we're going to see is in this version, before we had the servlet container That was directly talking to our servlet which was the video servlet. This time, the Spring dispatcher servlet, which we're not even going to see in our code, is what the client is going to be talking to. And then that dispatcher servlet is going to be actually routing requests to our video service controller. So we have a video service controller object. And this is just, a controller is just a java object, with the Spring at controller annotation which is what you'll see. But the key thing to focus on here is how much simpler this version of the service is going to be. All we're going to focus on writing is really this video service down here. There's not going to be a web.xml anymore. There's not going to be any servlet that we're going to have to write. Spring's going to provide all of that for us. And what we're going to focus on is our actual logic to do something with the data that we're getting from the clients. So let's take a look at this video service controller. So if you go to the project it's in the video controller and retrofit project. The first thing we want to go and look at is in the source main java folder this video service class. And if you open this class up what you'll see is, is just a standard java class that implements an interface, and this interface is one that we define. It's nothing special from Spring. So this is just a plain old java object, or a pojo, so nothing is, we're not being required to inherit from anything. The only thing that's different is we're going to mark this class with an annotation that tells spring that it's a controller. In this case it's an at controller annotation. So this one little annotation right there is giving us a huge amount of power. It's telling Spring here is a class that doesn't inherit from anything that you know about, but you need to look at it and use it like it's a controller. So this ability to mark up standard Java objects with annotations and provide metadata on them, that otherwise we would have to express somehow through inheritance or the implementation of interfaces, gives us greater flexibility in how we implement and create our classes. So this simple Java object that's annotated with that controller is going to be discovered and loaded by spring, just because of the simple annotation If we look at the video service we'll actually see this is an a remarkably simple class. Just like in the servelet we're going to create a list that we're going to store the videos in and this is just a standard array list nothing special and then lower down in the file we have two methods that are the equivalent of the methods that we had in the servlet for doGet and doPost. In the case, we have an add video method, so one of the things to immediately note is that Spring isn't enforcing any naming conventions on our methods, we've got methods that make sense for that object, addVideo. So, the fact that we're not being forced to inherit from anything in particular, and that we're not being enforced on any particular naming conventions in this example, it allows us to write an object that makes much more sense. You look at this object and you understand what the addVideo method Is going to do even if you don't have the source code. It's much more explanatory. Now what we'll see is that this method, because it doesn't have to follow any naming conditions, it does have to provide some metadata to spring to tell it how to use it. So the first thing we see is the annotation at request mapping. And what this does is, the at request mapping tells Spring that this is a method that we want you to route some HTTP request into. So, whenever you see a request where the path is video service path, and if we see this constant just expands to slash video. Whenever you see a request sent to slash video that is of type POST, which we see here, you should invoke this method. So we're rather than expressing doGet, doPost, and changing our method to take a servlet request. And a servlet response so we can read from the request parameters, the strings, and get a writer and write a response back out. It's just a primitive string. We're suddenly writing a method that looks like a standard method that you would write in Java to do something useful. Now where it also gets interesting is the next parameter, or the next annotation at request body. Which is attached to the video parameter. So we're expecting this method to take a video as input and what we need to do is we need to tell Spring where it should get that video from. In this case, what we're doing is we're telling Spring that we want you to go and look at the body of the HTTP request. And we want you to automatically try to convert that body into a video object. And there's a lot of different ways that you can tell Spring how to convert a body into an object. By default, however, Spring knows how to convert JSon, or the JavaScript object notation, into objects. So if we have a request body, that has a JSon object encoded into it, not URL encoded, but just JSON directly in the request body. The controller can automatically have that data extracted as an object by spring, and then passed into the method that we've mapped with that request mapping. So we don't have to worry about going and figuring out how we take some request, servlet request, and extract parameters from it, and extract the object. We can just tell Spring, we want whatever's in the body of that request to be interpreted as a video object, and extracted for us. And, Spring is doing this all behind the scenes for us. So, if we see now, this method is simple even if we didn't have HV-request we would still interact with this method and create video objects and use the logic in it. So it's also decoupling us in some degree from the idea of HV-request. And then we're just adding the video to the list of videos we've created. So our logic is incredibly simple. We're focusing only on the things that we care about. The taking a video and adding it to the list. And so if you compare this to our original code which is in the video servlet, look at all the work that we had to do in the video servlet to handle the post request, to get all the parameters out, to validate some minimal information about them, and then to actually construct a video. And then finally, down here, actually add the video. All of this was overhead for this tiny little method call down here. But if we look in our current version with the controller, everything is about this one thing that we were actually trying to accomplish. So suddenly we can focus on the logic that we actually care about. This taking a video and adding it to the list of videos. We don't have to focus on all the logic to construct that video that we're going to add to the list. So Spring is taking over that work of unmarshalling all of that data from the request body into an object that we can actually operate on. The other interesting thing to note is this at response body annotation. You'll notice that we're not taking an HTTP response that we can write to anymore as a parameter. We're not getting a writer and writing out what we want to go back to the client or setting the content type even. All we're doing is saying at response body, which tells spring that I'm going to return an object or a value of some kind and whatever the return type of this method is, I want you to take it and convert it back into a response body automatically, using the same conversion that you used To take the parameter in. So in this case, what that means is, is that whatever boolean we return, Spring is automatically going to convert it into a JSON representation, and return it to the client. So we don't even have to worry anymore about taking our return value and writing it back to the client. We just return something, and tell Spring to go figure out how do you make whatever we return into a HTTP response that can go back to the client. And, as you can imagine, if you threw an exception, Spring is automatically going to be smart, and figure out, oh, this method threw an exception, I need to return an error 500. Similarly, you notice we're not returning the error 400 if the client provides invalid data. What's nice is if the client doesn't send valid data that can be converted into a video, Spring is automatically going to tell the client and generate that error 400 for it to tell it that it sent an invalid request. Then, if we go down and look at the get request, again we see a request mapping. Again, to the video service path, which is slash video, and this is the equivalent of the do get method that we saw before, except that we're scoping this request mapping specifically to the get method of HD request. But the method itself is not polluted with any change in our logic. We're just adding metadata that Spring can find. And, in this case, we have a simple method that takes no arguments, so we're not even going to look at the data that's in the request that we're getting and instead, all we're going to do is return a list of videos. And here again, we're using the at response body, to tell Spring, go and take whatever list of videos I returned to you, an automatically convert it back into a JSon list of objects, that can be returned to the client. In the HTTP response body. So Spring is doing the heavy lifting here of setting the appropriate content type for the response. Converting your list of objects into JSON. Encoding those, those, that JSON into the HTTP response, and then sending it back to the client. But in your code right here, you're not seeing any of that. You don't have to go and pollute your code. You're just working with standard Java objects that look much more natural than they did when you were trying to write all this special logic for HTTP. So we've decoupled how we access these methods and how we encode and decode requests and responses Into just simple logic, where just adding some meta data to our class, and suddenly spring does all the work for us. If we go and look at our video object, and see that we still get the member variables, we still have a constructor. The only thing that we've done new, is we've added a default constructor that takes no parameters. And this is just to help the underlying spring framework infrastructure being able to instantiate our objects and then set all of these values programmatically. Now its possible to also have the not have the default constructor but it just takes a little bit more annotation that I decided to skip for this example. Now the final thing that we need to note is we don't have a web.xml file anymore. We've removed that extra piece of infrastructure that we had to have and understand how to build to tell the servlet container about our servlets and how to map requests into them. So how does Spring figure out where our controllers are and how they should be put together. That is what's this application class is that we are going. The application class is now our entry point into our application. We simply have a public static void main method just like we would with other applications we would with other applications we would want to be able to have the executable, and then we ask Spring to go and run our application. Now, what this is going to do is Spring is going to look at our application and the configuration that we're expressing in it, and then automatically, in this case, create a web container put a dispatcher servlet in that web container, and then auto discover all of our controllers in our application. So what this application class primarily serves to do at this point is to provide these annotations to spring, telling it information about how to construct our application. So the first annotation that we see up here is app configuration. And all this is is an annotation that's provided to Spring to tell it when you are expressing configuration information in a class. So Spring will look at this class and know that it should interpret it as a configuration. The next thing we're doing, is we're saying at enable web NVC. And what this does, is, it tells Spring to set up a web container with a dispatcher servlet inside of it. And that dispatcher servlet, should be configured to be able to route request to controllers. So this one annotation is doing a huge amount of work. It's going and setting up a dispatcher servlet, making sure that the web container knows about it, and that the web container will route request to that servlet. So this is almost taking the place, this one line of our entire web.xml file. The next line is telling Spring that we want you to go and look in this Java package for all of the objects in there that are important to Spring and are annotated with Spring information that it needs to know. So, in this case the at component scan is telling spring to go and automatically look at this package down here. And I'm going to close this up to make this a little easier to see. This controller package, which is specified right here. And discover any controllers that are in here. So this the one line tells Spring, no matter how many controllers do you have in this package. Go and look through all the classes and discover any class, that is a controller and set it up. And then the final one is add enable auto-configuration. And that tells Spring that if I have asked for any type of objects that I need for dependencies, to automatically go and configure them. And we'll talk more dependency injection later. But these four annotations on this configuration class go and set up an entire web container they create the DispatcherServlet that we need to route requests to our controllers. They automatically scan the appropriate packages that we want to discover our controllers, and then they'll automatically configure our controllers with any dependencies that we want them to have. So if you look at this application and the source code for this, it's actually remarkably simple. It looks like a bigger application than it is. Just because there's so many comments in here describing what the different lines do. But the actual logic is remarkably simple. This configuration is a simple class called application that has four annotations with it. And a main method that delegates to a run method in spring application. It's incredibly simple. The video service class now is really just a list with two methods that either add an object to the list or return the list. That's it. And then our video class is just simple java object. That can be constructed and given some information about a video. So what you can see that we have vastly simplified the logic for this video service. By building on top of Spring. And then it's starting to do a lot of the hard work and boiler plate code with respect to how we take HD requests. Turn them into objects and invoke methods that we care about, return objects from those methods, and then convert them back into HP responses. So we think back to that original vision and where we want to allow our clients to essentially send commands two are objects that are sitting on the server, through the network. So this is sent via HTTP. Suddenly, we've got all of this covered for us except that we can solely focus on writing logic that can receive commands. And we can, as we'll see in a minute, do the same thing on the client side, so that all of this work, to take HTTP, transport the commands, and get the responses back, we can hide a lot of the complexities of the underlying HTTP protocol, by using a framework like Spring.