1 00:00:00,200 --> 00:00:04,290 With our model and data repository in place, let's move on to the controller. 2 00:00:05,300 --> 00:00:09,440 We'll need a controller for categories that can capture requests to a URI for 3 00:00:09,440 --> 00:00:13,590 all the categories and a URI for a single category. 4 00:00:13,590 --> 00:00:16,080 So, here's your next task. 5 00:00:16,080 --> 00:00:20,791 Create a Category Controller with one method [SOUND] that captures requests to 6 00:00:20,791 --> 00:00:23,046 /categories and returns a String. 7 00:00:23,046 --> 00:00:26,966 This method should fetch the entire list of category objects from 8 00:00:26,966 --> 00:00:30,680 an auto-wired category repository and add it to a ModelMap. 9 00:00:30,680 --> 00:00:35,427 [SOUND] Then, the method should return the string categories to associate it 10 00:00:35,427 --> 00:00:37,962 with the provided Thymeleaf Template. 11 00:00:37,962 --> 00:00:39,600 Are you ready for this? 12 00:00:39,600 --> 00:00:40,200 Okay. 13 00:00:40,200 --> 00:00:41,930 Go ahead, have at it. 14 00:00:41,930 --> 00:00:46,150 But wait, remember to use the GIF controller as an example to follow. 15 00:00:46,150 --> 00:00:47,160 Ready, set, code. 16 00:00:48,840 --> 00:00:52,170 >> All right, what you're looking at here is my category controller class, 17 00:00:52,170 --> 00:00:55,660 which I put in the controller package with the other controller. 18 00:00:55,660 --> 00:01:00,540 You can see that I've annotated the class with Controller and included an Autowired 19 00:01:00,540 --> 00:01:05,310 category repository that I can use in the controller method down here. 20 00:01:05,310 --> 00:01:09,950 As for this method, I've annotated it with request mapping to capture 21 00:01:09,950 --> 00:01:14,790 any requests for the category list page, which is /categories. 22 00:01:14,790 --> 00:01:19,077 Here is my modelMap parameter, and inside is the the call to the repository's 23 00:01:19,077 --> 00:01:21,830 getALLCategories method that we wrote together earlier. 24 00:01:22,900 --> 00:01:27,440 I added the list that was returned by this method to the modelMap using 25 00:01:27,440 --> 00:01:28,960 modelmap.put here. 26 00:01:28,960 --> 00:01:34,520 And here I've returned the name of the time leave template, or categories. 27 00:01:34,520 --> 00:01:37,930 This is will ensure that it's the categories.html template that will be 28 00:01:37,930 --> 00:01:40,360 rendered when this page is requested. 29 00:01:41,490 --> 00:01:44,070 The last piece of this controller, we'll do together. 30 00:01:44,070 --> 00:01:46,990 We'll need another method that will capture requests to an individual 31 00:01:46,990 --> 00:01:47,628 category. 32 00:01:47,628 --> 00:01:52,715 To start that, I'll request a mapping to a single category page, 33 00:01:52,715 --> 00:01:57,930 category/, and here we're going to use an integer id. 34 00:01:57,930 --> 00:02:00,590 The name won't work well as a URI placeholder 35 00:02:00,590 --> 00:02:03,520 here because names could have spaces in them. 36 00:02:03,520 --> 00:02:06,220 So instead, I'll use the integer id as a placeholder. 37 00:02:08,130 --> 00:02:14,350 Then we'll start typing the method public String category. 38 00:02:14,350 --> 00:02:17,875 And the first parameter I'm going to list is our @PathVariable. 39 00:02:18,970 --> 00:02:21,930 That will capture the value that's passed into 40 00:02:21,930 --> 00:02:26,020 the id placeholder that's in our RequestMapping annotation. 41 00:02:26,020 --> 00:02:27,190 So I will call it id. 42 00:02:27,190 --> 00:02:31,490 And of course, we'll include an instance of a modelMap that'll 43 00:02:31,490 --> 00:02:33,070 be passed in by the Spring framework. 44 00:02:35,040 --> 00:02:38,570 >> Now, I know I'm going to return the single categories template, 45 00:02:38,570 --> 00:02:44,310 which is given in category.html, so I'll type in that return value right now. 46 00:02:44,310 --> 00:02:47,200 That's going to be return "category". 47 00:02:49,030 --> 00:02:52,160 Now I know the category page in the browser should probably 48 00:02:52,160 --> 00:02:54,880 contain the category name, as well as 49 00:02:54,880 --> 00:02:59,860 all GIFs related to that category, >> So by the time we reach the return 50 00:02:59,860 --> 00:03:04,350 statement we better have added to the model map, both a category object 51 00:03:04,350 --> 00:03:11,110 associated with this ID as well as a list of GIFs associated with this category. 52 00:03:11,110 --> 00:03:12,520 Let's tackle each of those now. 53 00:03:13,520 --> 00:03:15,130 First, the category object. 54 00:03:15,130 --> 00:03:17,160 You just wrote a findById method, so 55 00:03:17,160 --> 00:03:19,990 we'll call that now and add the result to the model map. 56 00:03:19,990 --> 00:03:22,463 I'll create the category object, 57 00:03:27,462 --> 00:03:32,243 And use the categoryRepository field and call its findById method 58 00:03:32,243 --> 00:03:37,440 passing it the integer id that came into our path variable. 59 00:03:37,440 --> 00:03:41,620 Then I'll add the category object that was returned by the findById method to 60 00:03:41,620 --> 00:03:46,240 the model, using modelMap.put. 61 00:03:46,240 --> 00:03:50,830 The name I'll give it will be simply category, and I'll pass category. 62 00:03:50,830 --> 00:03:54,450 Whatever value was stored in there as a result of this return value, 63 00:03:54,450 --> 00:03:55,600 I will add to the ModelMap. 64 00:03:57,120 --> 00:03:58,720 Now onto the next item. 65 00:03:58,720 --> 00:04:03,080 For a list of the GIFs associated with this category, we'll need to use a GIF 66 00:04:03,080 --> 00:04:09,040 repository to fetch all those GIFs within a certain category ID, like this. 67 00:04:10,070 --> 00:04:13,120 I'll give myself a couple lines to separate this code. 68 00:04:13,120 --> 00:04:15,960 And the first thing I'll do is define a list that'll 69 00:04:15,960 --> 00:04:19,620 hold that list of GIFs that comes back from the GIF repository. 70 00:04:19,620 --> 00:04:22,780 Make sure to import the GIF class there, since we haven't done that yet. 71 00:04:24,520 --> 00:04:28,269 And I'll call the gifRepositories, 72 00:04:28,269 --> 00:04:33,130 findByCategoryId method, passing it the id. 73 00:04:33,130 --> 00:04:38,685 And finally, adding that list to the model map with modelMap.put. 74 00:04:38,685 --> 00:04:45,684 I'll call that "gifs" in the map key, and pass it the object gifs. 75 00:04:47,545 --> 00:04:50,505 But wait, there are two problems with this. 76 00:04:50,505 --> 00:04:53,545 First, there is no GIF repository variable defined. 77 00:04:53,545 --> 00:04:57,485 And second, there is no findByCategoryId method defined for 78 00:04:57,485 --> 00:04:59,322 a GIF repository object. 79 00:04:59,322 --> 00:05:00,877 The first one we can fix right here. 80 00:05:00,877 --> 00:05:04,552 We'll simply add an Autowired gift repository to the object. 81 00:05:06,292 --> 00:05:12,546 So I'll add that with the @Autowired annotation, add a GifRepository. 82 00:05:14,461 --> 00:05:16,746 That fixes the first error, but 83 00:05:16,746 --> 00:05:21,680 we still have this error with the missing findByCategoryId method. 84 00:05:21,680 --> 00:05:23,120 This one will take a bit more work. 85 00:05:23,120 --> 00:05:24,730 But it's still pretty quick. 86 00:05:24,730 --> 00:05:30,380 We'll hop over to the GifRepository class, and add a findByCategoryId method. 87 00:05:32,370 --> 00:05:35,610 So let's scroll down here and I'll just add it to the bottom. 88 00:05:35,610 --> 00:05:37,129 That'll return a list. 89 00:05:41,087 --> 00:05:48,587 FindByCategoryId, and let's have it accept a single end parameter. 90 00:05:48,587 --> 00:05:53,343 So this method, given some int id, will essentially iterate over our 91 00:05:53,343 --> 00:05:58,220 list up here looking for objects that have a given category id. 92 00:05:58,220 --> 00:06:00,085 If they haven't given a category id, 93 00:06:00,085 --> 00:06:03,210 I will include those in the list that I return. 94 00:06:03,210 --> 00:06:07,350 So to start, we better initialize a brand new empty list. 95 00:06:08,380 --> 00:06:16,035 I'll make it a list of GIFs and initialize it as a new ArrayList. 96 00:06:18,800 --> 00:06:21,340 Make sure to import those classes, excellent. 97 00:06:22,900 --> 00:06:28,170 Now, let's use a for each loop to iterate over the list of ALL_GIFS. 98 00:06:28,170 --> 00:06:33,000 So for every Gif, I keep typing Fig, how about Gif? 99 00:06:33,000 --> 00:06:38,048 For every Gif in ALL_GIFS Let's 100 00:06:38,048 --> 00:06:43,027 check to see if the category id of the Gif object in this iteration of the loop is 101 00:06:43,027 --> 00:06:46,568 equal to the id value that was passed in as a parameter. 102 00:06:46,568 --> 00:06:51,128 So, if gif.getCategoryId ==, 103 00:06:51,128 --> 00:06:54,930 I can use double equals here. 104 00:06:54,930 --> 00:06:55,840 It's a primitive value. 105 00:06:55,840 --> 00:06:57,209 I don't need to use dot equals. 106 00:06:59,030 --> 00:07:05,338 Then what I want to do is add that to the list. 107 00:07:05,338 --> 00:07:10,168 So, by the time we get through this loop, any Gif in the list that has the category 108 00:07:10,168 --> 00:07:12,727 ID that was passed in as a parameter value, 109 00:07:12,727 --> 00:07:14,879 will be added to the list name Gifs. 110 00:07:14,879 --> 00:07:19,564 And once I get through my loop, what I'd like to do is return 111 00:07:19,564 --> 00:07:24,020 whatever list has resulted by iterating over all gifs. 112 00:07:24,020 --> 00:07:28,475 Now that we've coded this method, after we jumped back to the category controller 113 00:07:28,475 --> 00:07:33,425 class, we should see that that error right there has been resolved, 114 00:07:33,425 --> 00:07:34,730 since we created that method. 115 00:07:36,150 --> 00:07:40,810 At this point, we should at least be able to see the category list page, 116 00:07:40,810 --> 00:07:44,100 even if it hasn't been infused with live data. 117 00:07:44,100 --> 00:07:46,210 Let's redeploy and check it out. 118 00:07:46,210 --> 00:07:48,990 So if your boot run task is still running, go ahead and stop it. 119 00:07:50,870 --> 00:07:52,080 And after a few moments, 120 00:07:52,080 --> 00:07:58,110 you can rerun that bootRun task to reboot your server and redeploy your web app. 121 00:07:58,110 --> 00:08:03,340 And it looks like I have a compiler error. 122 00:08:06,962 --> 00:08:08,418 I see what happened here. 123 00:08:08,418 --> 00:08:12,590 So this error right here says that I can't 124 00:08:12,590 --> 00:08:16,760 leave this generic between these angle brackets here empty. 125 00:08:16,760 --> 00:08:18,250 And why does it say that? 126 00:08:18,250 --> 00:08:22,735 Well, it says that because in my build file, if I go to my build file, 127 00:08:22,735 --> 00:08:28,140 build.gradle, I said I wanted my Java source code to 128 00:08:28,140 --> 00:08:33,433 be compatible with Java five, that is version 1.5, and 129 00:08:33,433 --> 00:08:39,040 I have to use source 7 or higher to enable the diamond operator. 130 00:08:39,040 --> 00:08:42,170 That's the operator that allows us to leave that generic empty. 131 00:08:43,560 --> 00:08:47,600 So, what I'm going to do is, well, I could do one of two things, I could remove 132 00:08:47,600 --> 00:08:52,200 the source compatibility here, I could increase the source compatibility here, or 133 00:08:52,200 --> 00:08:59,432 I could go back to this line right here, and actually add gif right there. 134 00:08:59,432 --> 00:09:02,176 I'm simply actually going to delete the source compatibility. 135 00:09:02,176 --> 00:09:03,703 Delete that. 136 00:09:03,703 --> 00:09:08,550 We'll save it and now I'm going to rerun the bootRun task. 137 00:09:09,990 --> 00:09:13,040 And there it looks like the compilation has succeeded. 138 00:09:13,040 --> 00:09:14,710 And the web server's up and running. 139 00:09:14,710 --> 00:09:16,800 My application is deployed. 140 00:09:16,800 --> 00:09:17,710 Let's check it out. 141 00:09:19,250 --> 00:09:22,220 So I'm going to go back to my main page. 142 00:09:22,220 --> 00:09:24,940 There's the home page, we didn't touch it in this last task. 143 00:09:24,940 --> 00:09:28,500 What we did touch, though, is the Categories page. 144 00:09:28,500 --> 00:09:29,690 And there it is! 145 00:09:29,690 --> 00:09:31,140 It's working! 146 00:09:31,140 --> 00:09:35,480 We see that the template is actually displayed, though it has static HTML. 147 00:09:35,480 --> 00:09:39,300 And from this, you can probably guess what your final task is going to be.