Spring Tips: @Controllers: the "C" in Model-2 MVC

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi spring fans welcome to another installment of spring tips you know what i found to be a lot of fun recently graphql you know why graphql is awesome because it makes it easy to build client friendly views of data to support an integration layer for downstream microservices graphql answers a few problems i had with our socket i love our socket for individual services but when it comes time to expose my services over the network to a particular client then i'll probably need to work with http now our socket in turn answered a few concerns i had with http1.x and even 2.x and grpc http1.x in particular is inefficient slow less resilient payload specific and inflexible in terms of the message exchange patterns that were supported so i like these different technologies and i like that spring has made it easy for me to approach all these different approach technologies in a familiar consistent programming model that of a controller i love working with graphql because it's an idiomatic approach to graphql in terms of the spring at controller component model i was talking to spring guru rason styanchev whose work you may recognize if you've ever used spring nbc spring web flow spring web flux the r socket support and now spring graphql among a million others and by the by he's worthy of a whole discussion in of himself i even did an interview with him on my podcast a beautiful podcast in which we delve into some of the amazing things he's done go check that out but anyway he reminded me that springs controller annotation is actually a generic stereotype annotation not tied to any particular protocol not http not r socket or anything else spring stereotype annotations are to my mind fairly new the spring framework committer mark fisher contributed them in version 2.5 of spring framework there are stereotype annotations in the uml sense that is they indicate the role of a component in the code base which is by the way yet another reason why you needn't worry about putting your your components in packages named by role because it's redundant the annotations already tell the story it's always been the intention that a controller would be agnostic of a particular protocol controllers are the c and mvc which of course stands for model view controller and it's hard to believe that i've been doing these spring tips videos for nyon six years and never done a dedicated video on spring nbc before we've certainly looked at spring mvc in the context of http rest applications i think i've probably even demonstrated some spring web tier goodness and i probably have conjured up a spring nbc view or two at some point but i've never done a dedicated episode about it before now one of the reasons is that i never thought i'd have to i mean who doesn't know about spring nbc ridiculous right spring mvc along with spring's jdbc support are some of the things that made spring so appealing way back when spring debuted in the early 2000s struck out 2002. it's come a long way at the time spring nbc was an alternative to frameworks like apache struts which made the idea of a jsp2 or jsp model 2 nbc architecture possible and popular you see way back in the halcyon days of the 1990s sun published a jsp reference dock that laid out two possible architectures for jsp jsp of course is the java server pages specification uh it's a hopefully long forgotten templating technology that relied on the mixing or interspersing of java code and markup you know actual html templating markup in the same artifact it was an easy way to create a tangled horrible mess and because it required a compiler to actually turn your template into a java class it was also fragile the first model laid out in this reference document model one was basically uh typical of contemporary template templating technologies like js like asp and php basically you'd have a jsp uh page that contained scriptlets of of logic that were associated with that page and that lived in line with a markup uh it was a thing it wasn't i'm not proud we were there it was mistakes were made okay the second possible architecture uh would become js jsp model 2 mvc not because it was i don't know why it was called two i think it's just because it was literally the second option laid out in that document but the second option was a little bit more elegant the idea was that you would have a servlet intercept incoming requests and do the work of populating the request and then forwarding that request onto a jsp to produce the output html in this model the servlet acted as both the model in that the request parameters from the request uh were were routed to the uh servlet and the controller in the mvc pattern and the jsp page acted as the view in december 1999 java world published an article by govid sestradi entitled understanding java server pages model 2 architecture this article clarified the approach a little and made explicit the idea that the servlet would act as a sort of controller in the mvc paradigm and the model could be anything a vector of data an ejb the match was lit craig mclanahan built the first version of struts around this time formalizing the distinction between model view and controller action forms would be the model in this struts world actions the controllers and templating technologies like velocity and jsps the views i loved struts right there's a lot of interesting activity around that because it was the first time that we had a clear-cut architecture for building successful scalable applications on the jvm and at the time by the way when we talked about what would satisfy the role of your model well at the time you know originally the discussion was around ejbs but then we discovered after a while that you know you could probably get it done with just hibernate right and you didn't really need ejbs you could actually do a lot of interesting stuff with just the web framework inside of tomcat not inside of an application server and some sort of data access layer so apache ljb mybatis or ibatis you know hibernate also jdo all sorts of things were were equally as interesting and spring came along and made that you know made the possibilities even more concise with the smart support for jdbc and so on so stress was really empowering because it meant that people had a template they could follow to build applications that would survive scale uh and it just ran in open source tomcat or you know at least very lightweight containers like tomcat you didn't need a full-on application server if you didn't want it stressed did for java what ruby on rails did for the ruby community later on now spring was born in 2001 so this is a couple years after struts would have been around the earliest code in spring if you check the javadocs by date has to do with http web support there was even an integration that made using spring and struts together as easy as can be you could use spring to manage your action beans what a time to be alive it was really cool i actually really enjoyed that particular integration spring mec was developed and included in spring framework itself because it was considered so vital to spring's value proposition that of course it would evolve along with spring itself and evolve it did the original spring mvc relied upon concrete-based classes and interfaces that all mvc components had to implement when spring 205 introduced an annotation-centric component model along with the now ubiquitous stereotype annotations it started the process of jettisoning those concrete-based classes and embracing a completely pogo-centric and declarative framework for building http endpoints all rooted in the ad controller stereotype annotation a few years later in spring 3.0 spring nbc uh debuted proper support for building http rest endpoints building upon essentially the same component model so spring nbc is still one of the most popular modules in the spring ecosystem even if people aren't building mvc model 2 applications as much anymore indeed today's in spring mvc applications are using this the http rest support right spring mvc is a workhorse for building spring mvc based http rest applications and instead of building server-side html views they're probably building rich clients in the in the browser or you know your your typical ios or android or uh clients and and connecting those clients to http rest endpoints or now graphql endpoints on the server all of that is really exciting because it means that there's now a new role for spring nbc to play but in this video i want to kind of revisit what it looks like to build a web application a model 2 mvc kind of application using spring mvc where mvc was what you were going to do with it right obviously we're going to look at other ones here in fact this is just the beginning of a small series where we look at different uses of ad controller because i think it's really quite compelling what's possible in the spring ecosystem with but one little annotation and once you've understood what's possible with one uh you know implementation of that annotation you'll be surprised at how many doors open for you when it comes time to build these other kinds of applications so let's dive right into it all right let's go ahead and build a new uh spring mvc application using the server stacks or call this mvc i'll be using kotlin we're going to bring in the web support and we're going to bring in the time leaf view templating engine we'll hit generate and we're going to open this up in the ide [Music] all right let's load this up and in the root of the project we have our source main resources templates directory okay and that's where we're going to put our time leaf templates we're going to build a controller and we're going to call this the greetings mvc controller and here we're going to have an endpoint that returns uh a view a template right when somebody goes to greetings right let's say greetings.html it's arbitrary it could be greetings.asp right it does it doesn't matter right greetings.xhtml or whatever or dot do do you remember for many years there was struts and the convention was was to use dot do so this is the url right and then we're going to say when this gets called when somebody makes an http get request to a url ending with greeting.due we're going to return a model and this model is going to be kind of like a key value pair it's a dictionary that contains information that should be rendered to the client in the template so we'll say model we'll say model dot add attribute greeting i'm going to pass in a greetings object here now we need a d we don't have a greetings object so i'll create that right now uh var name string question mark okay equals null so it's a it can have nothing or it can have a field and then we're gonna return a value we'll say return um let's just call this render okay we'll have a view logically named render what that means what that means is that we're going to need to go to source main resources templates and create a file called render.html and for render.html we'll have a form so that you can fill out some data have it submit be bound to a java object in the request and then make it made available for the controller handler method to process it in this case we're using timeless tags so you saw i just pasted in the html template for the render page so what this is going to do is it's going to render an html form the form will call greeting what do we call it we called it uh greetings greeting.do okay so it'll call it'll go to that endpoint and by the way if the reason you have this special syntax here is because it'll actually resolve you know the context path if you're running inside of a servlet container or something like that then we're going to say when this form gets submitted bind its fields its constituent form fields to the properties or the java fields on the the object you know the the object's uh properties so the object in this case is what's in the model which is called greeting so we have greeting it's an empty greetings it's got a setter and a getter for a field called name and we're going to say that we accept a post and then we're going to bind the contents of this input text field to greeting.name and then we can submit okay so that's the post side let's go ahead and run that and see what we get okay let's go here localhost greeting dot do all right so that's worked we've got a field but nothing to submit to so let's go ahead and add that now or create a new endpoint that responds to a post for the same url right greeting dot do and here i'm going to say um post right we're just going to call this handler method post and it's going to return a string and it'll accept a a form value of type greeting okay greeting and the model will be model right so we're going to use the model to populate the data that gets sent back to the client but to to process the incoming data spring mvc is nice enough to convert the form data into a java object or the kotlin object in this case the data class called greeting so i'm going to return post okay and we're gonna add an attribute here we'll say add attribute and it'll just be another greeting just like before except this time we're gonna send the result directly right back okay nothing fancy we're not doing anything with it you know we can say print line uh processing incoming greeting there you go so now you'll be able to see that this is actually happening and we need a new template here a new file called post dot html and we'll paste that template as well there we go so there's our then we're going to paste that template as well okay so we'll paste that template as well and here we're just saying render the page with the object in the model attribute called greeting render the field called name in this just a text element just a span there's nothing there's no form field or anything we're just printing out data that was given to us from the server side right so in the render case we're rendering a default form we're doing basically nothing with the incoming requests uh here we're rendering the data after it's been given to us we're rendering the same data as a view okay let's try this all right so now refresh this this is greetings that do we're going to say spring fans all right submit and there it says hello spring fans so we've just built a simple mvc you know flow right the model come the model uh gets submitted via post uh from that original page which i get to by going to uh you know making an hp get the model is populated it goes into the server the server then responds to the data uh by by adding it to another model and then you know printing out processing incoming reading and then returning to a different view all right now couple things uh what if i wanted to actually have data you know on the first load would if i what if i want to pre-populate that data if it's if it's possible you know based on the presence of it right well i can do that using a request pram so i can say request param name string okay and here i can say okay um this is nullable right and it's not required so i can say required is false and here i'll say if name does not equal null then this one else no name right very simple so there's my default flow let's try this one now okay so now just refresh this no problem it works just fine but name equals world and there it gets pre-populated out of the box not bad huh and then i can submit that and i can say hello world so you can see that spring mvc makes it really simple to build html views and of course i'm using a view resolver here for time leaf but you can use any kind of content type right you can actually use you can generate spreadsheets excel spreadsheets and pdfs and you can generate uh all sorts of different things right there's all sorts of different content types that can be served from a spring mvc endpoint you can create images right dynamically write the bytes to to create a jpeg or something and then send that back anything is really uh possible at this point okay now one thing i want to take care of of course is what happens if there's an error right what happens if we add a um a name to the incoming data and the name isn't capital letters well of course in this case i want to do some validation right so uh at a minimum i'll have a um an assertion right assert dot is true and i'll say character is uppercase greeting dot name dot car at and let's see zero okay let's see the name might be nullable so i say that and i'll say that um actually i want the first character okay so if that first character is capital letters great otherwise i'm going to throw an exception the name must start with a capital letter okay now what happens if that throws an exception well i want to have some some handling to make sure that i do the right thing now you can do this a number of different ways you could actually have a try catch in the handler method itself uh you can actually create another thing called an exception handler in the class right exception hender and you'll see that exception handlers are pretty common across all the different controller implementations and so the basic approach is you create a method that looks like any other method you know there was an error and exception utils dot oops nope we want to what do i want to use i want to use a let's just do this ex stack trace or message there you go let's just use the message okay so you create a method that looks like any other handler method but it only gets invoked when there's an exception right and so here i'm saying i want to resolve any exception you can be very specific about it you can say i want to to resolve only a legal access error you know that kind of thing if you want and then this of course would be down type to that and if you don't care about the method if you don't care about the exception you don't care about using or getting a pointer to that method uh to that exception if you don't care about getting access to a pointer to that exception then you can just declare the type that you want here and then omit it from the signatures but i care so i'd rather just do that that's what that works fine okay so now i'm throwing an exception when i am submitting anything where the first name is not a capital letter let's try that okay refresh let's say jane okay throws an error right you can of course do visual validation here as well but i just wanted to show you that you can easily center your exception handling logic you can go a step further you'll see that this is pretty common across all the different controller implementations where i want to say exception handling exception handler controller advice all right and here you can create you know just copy and paste that same thing so there you go so the controller device gets invoked uh for generic things like model binding and exception handling but not for actual routes not for not enough for resolving the views right so let's restart and same basic flow lowercase jane acceptance there's an error let's start with the capital letter so this can apply to all controllers this is a kind of a way to introduce common behavior uh across all the different controllers you could even go a step further here i'm just doing void but you can actually have this return of view or something like that and so you can actually populate a view page you can also listen for things based on what um what uh you know the exception handling and all that stuff you can actually inject the current request you can produce a response status you can do all sorts of amazing things with exceptional handlers what you can do of course varies from one protocol to another but it's nice to know that you can alright good stuff huh we looked at how to use spring mvc to build mvc applications as in model 2 mvc now obviously this is but one application of ad controller and it's arguably the oldest and you know possibly even the less the least used today i don't know i have no idea but spring nbc is certainly used a lot it's still by far the most popular web framework in the java ecosystem but these days as i said earlier it's a workhorse for rest applications so it's very interesting that you can still build this stuff and other frameworks have actually gone the other way there's there's uh you know there are other frameworks out there that built a rest framework but then realized they also needed to support uh mvc style applications and so they grafted that on uh eventually right so we did this uh the other way around we supported mvc when it was popular and appropriate to do so and then we added rest support to the same framework and this meant that if you had a conceptual model for one you could easily apply those skills in the other this is one of the things i love about spring is that you get rewarded for investing a little bit of time and learning the approach because that idiom that that muscle memory still works it still applies in these new contexts in the next videos we'll look at things like graphql http rest reactive web applications websockets and our socket and then we'll look at some things that only apply when you start to mix and match these things in the same application as always thanks for watching and we'll see you next time
Info
Channel: SpringDeveloper
Views: 5,673
Rating: undefined out of 5
Keywords: Web Development (Interest), spring, pivotal, Web Application (Industry) Web Application Framework (Software Genre), Java (Programming Language), Spring Framework, Software Developer (Project Role), Java (Software), Weblogic, IBM WebSphere Application Server (Software), IBM WebSphere (Software), WildFly (Software), JBoss (Venture Funded Company), cloud foundry, spring boot, spring cloud
Id: hUBrFekxn0Y
Channel Id: undefined
Length: 23min 18sec (1398 seconds)
Published: Wed Oct 27 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.