1 00:00:01,000 --> 00:00:04,900 So now you've had a chance to see the full flow of data from the storage of GIF 2 00:00:04,900 --> 00:00:09,060 details in a GIF object to the adding of a GIF object to a model map and 3 00:00:09,060 --> 00:00:12,540 finally the access of that object from a timely template for display. 4 00:00:13,680 --> 00:00:16,700 There's one problem with our GIF detail page at this point and 5 00:00:16,700 --> 00:00:20,820 that is it's only able to display the details of one hard coded GIF. 6 00:00:20,820 --> 00:00:21,540 The compiler bot. 7 00:00:22,660 --> 00:00:24,650 But what if we want the controller method and 8 00:00:24,650 --> 00:00:29,960 template to control the display of any GIF object according to the URL requested? 9 00:00:29,960 --> 00:00:31,640 For that, we'll need to step up our game. 10 00:00:33,020 --> 00:00:36,650 In particular, we'll need to store a collection of GIF objects in memory 11 00:00:36,650 --> 00:00:38,100 that our application can choose from. 12 00:00:39,330 --> 00:00:42,955 Next, we'll be adding what's called a repository of GIF objects. 13 00:00:44,120 --> 00:00:48,260 A repository is essentially a collection that we've stored somewhere in memory or 14 00:00:48,260 --> 00:00:49,540 in a database. 15 00:00:49,540 --> 00:00:54,620 For this simpler application, we'll store it in memory using a standard Java list. 16 00:00:54,620 --> 00:00:55,190 Let's get started. 17 00:00:56,520 --> 00:01:00,070 Before we make our GIF repository, I'm going to create a package that would hold 18 00:01:00,070 --> 00:01:03,780 any data repositories we might want to include in our application. 19 00:01:03,780 --> 00:01:07,020 So I'm going to right-click on the giflib package, and 20 00:01:07,020 --> 00:01:11,340 choose New, Package, and call it data. 21 00:01:12,950 --> 00:01:15,480 In this package is where I'll put the GIF repository, 22 00:01:15,480 --> 00:01:20,325 which will be a new Java class named, not surprisingly, GifRepository. 23 00:01:24,170 --> 00:01:26,700 This class will act as both our storage device for 24 00:01:26,700 --> 00:01:31,260 GIF objects as well as methods for interacting with those GIF objects. 25 00:01:31,260 --> 00:01:35,180 In a future course we'll show you how to shift your storage mechanism to a database 26 00:01:35,180 --> 00:01:37,780 but that's a bit outside the scope of the current course. 27 00:01:37,780 --> 00:01:42,030 So for now we'll stick with storing our GIF objects into a static Java list. 28 00:01:42,030 --> 00:01:43,970 To begin, I'll create that list as a field. 29 00:01:47,791 --> 00:01:51,719 Make sure to import java.util.List and 30 00:01:51,719 --> 00:01:56,240 com.teamtreehouse.giflib.model.gif. 31 00:01:56,240 --> 00:01:59,740 And I'll call this ALL_GIFS. 32 00:01:59,740 --> 00:02:02,840 Notice I'm using the all caps naming convention because this 33 00:02:02,840 --> 00:02:04,780 is a class constant. 34 00:02:04,780 --> 00:02:07,850 In this course, we're going to predefine our GIFs. 35 00:02:07,850 --> 00:02:12,000 Though in a production application, again, this would likely come from a database. 36 00:02:12,000 --> 00:02:16,580 For this I'm going to use a convenience method offered by the arrays class called 37 00:02:16,580 --> 00:02:17,970 asList. 38 00:02:17,970 --> 00:02:20,830 In to it I can pass any number of GIF objects. 39 00:02:24,135 --> 00:02:32,470 So arrays, it comes from the java.util package, .asList. 40 00:02:32,470 --> 00:02:35,690 This is, as opposed to constructing a new array list, 41 00:02:35,690 --> 00:02:39,550 then using the add method a bunch of times to add individual objects. 42 00:02:40,620 --> 00:02:43,200 I'll include six GIF objects here, one for 43 00:02:43,200 --> 00:02:46,050 each image I've given you in the GIFS directory. 44 00:02:46,050 --> 00:02:48,900 In the teacher's notes I've given you this block of code 45 00:02:48,900 --> 00:02:51,200 in case you wanna save yourself some typing. 46 00:02:51,200 --> 00:02:53,190 I'll go ahead and copy and paste that now so 47 00:02:53,190 --> 00:02:56,040 that you don't have to watch me type all that code. 48 00:02:56,040 --> 00:02:58,030 Give myself some space there. 49 00:02:58,030 --> 00:03:03,710 Copy that I will get back in here and I will paste that right inside there. 50 00:03:03,710 --> 00:03:07,130 Now, there's one import I need to resolve and that's of the local date class. 51 00:03:07,130 --> 00:03:11,750 So I'll hit option enter in Inteli J its automatically take its first suggestion. 52 00:03:13,010 --> 00:03:14,780 Might move this back one tab as well. 53 00:03:16,040 --> 00:03:18,570 Cool, and that's our storage device. 54 00:03:18,570 --> 00:03:20,550 I simple JAVA list. 55 00:03:20,550 --> 00:03:23,520 But I also mentioned that the beyond storing our data, 56 00:03:23,520 --> 00:03:26,420 this class would offer us methods for retrieving that data. 57 00:03:27,420 --> 00:03:30,780 Because this list is private, we'll need to add some public 58 00:03:30,780 --> 00:03:34,210 methods in order to access this list outside of the class. 59 00:03:35,290 --> 00:03:37,290 Let's add one of those methods now. 60 00:03:37,290 --> 00:03:40,930 We'll make a method that allows us to retrieve a GIF object with a given name. 61 00:03:42,530 --> 00:03:45,060 So it will return a GIF object. 62 00:03:45,060 --> 00:03:47,475 And I'm gonna call it findByName. 63 00:03:49,760 --> 00:03:54,500 I'll give it a String parameter, so that the collar of this method can 64 00:03:54,500 --> 00:03:58,610 pass at the name to retrieve the GIF object associated with that name. 65 00:03:59,700 --> 00:04:02,200 So inside this method, I'm going to iterate over 66 00:04:02,200 --> 00:04:07,500 all of my GIF objects in the list, so I'll use this enhanced for loop. 67 00:04:07,500 --> 00:04:09,160 Oops, I forgot the name of my variable here. 68 00:04:10,318 --> 00:04:15,050 Gif in ALL_GIFS, so it's a for 69 00:04:15,050 --> 00:04:18,860 each loop or enhanced for loop for every GIF object. 70 00:04:18,860 --> 00:04:22,710 In all GIFS I want to do the following. 71 00:04:22,710 --> 00:04:29,360 If the particular GIF object I'm looking at has a name that equals the name 72 00:04:29,360 --> 00:04:33,890 that was passed in, well then what I wanna do is return exactly that GIF object. 73 00:04:34,900 --> 00:04:38,890 Now, if I get through the entire list without ever finding a GIF 74 00:04:38,890 --> 00:04:42,290 matching this name, then what I want to do is return null. 75 00:04:45,160 --> 00:04:46,250 We'll leverage this method for 76 00:04:46,250 --> 00:04:48,720 our GIF controller class, which I'll switch to now. 77 00:04:52,110 --> 00:04:56,780 We'll want to leverage that method we just wrote from the GIF details method here so 78 00:04:56,780 --> 00:05:00,740 that we can feed the GIF details template with any GIF object instead of 79 00:05:00,740 --> 00:05:02,980 this one that we've hard coded. 80 00:05:02,980 --> 00:05:07,140 In order to have access to the GIF repository we'll need a reference to a GIF 81 00:05:07,140 --> 00:05:11,540 repository object, since we'll likely access this from any controller method 82 00:05:11,540 --> 00:05:13,410 I'll add it as an instance field. 83 00:05:13,410 --> 00:05:14,759 And we'll do that up top. 84 00:05:14,759 --> 00:05:18,508 Private GifRepository and 85 00:05:18,508 --> 00:05:23,402 I'll just call it GifRepository. 86 00:05:23,402 --> 00:05:26,930 Of course, without assigning anything to GifRepository, 87 00:05:26,930 --> 00:05:30,040 if we try to call any of its methods like the find my name 88 00:05:30,040 --> 00:05:33,998 method in any of our controller methods, we'll fall on our faces. 89 00:05:33,998 --> 00:05:35,930 Because the field will be null and 90 00:05:35,930 --> 00:05:41,036 we'll encounter a null pointer exception as I'm sure you've seen many times before. 91 00:05:41,036 --> 00:05:45,774 There are a couple of ways we could go about initializing this GifRepository 92 00:05:45,774 --> 00:05:46,310 field. 93 00:05:46,310 --> 00:05:49,270 One way would be to use a constructor in this class. 94 00:05:49,270 --> 00:05:53,000 And when the constructor is called we'd assign the GifRepository 95 00:05:53,000 --> 00:05:56,067 field a new instance of a GifRepository class. 96 00:05:57,150 --> 00:06:00,380 But there's actually another feature in spring that we can leverage here to 97 00:06:00,380 --> 00:06:02,040 reduce our coding. 98 00:06:02,040 --> 00:06:04,370 It turns out that Spring can initialize fields for 99 00:06:04,370 --> 00:06:10,240 us as long as it can find a spring component of the same class for the field. 100 00:06:10,240 --> 00:06:13,736 In our case it needs a spring component for GifRepository. 101 00:06:13,736 --> 00:06:17,370 To tell spring that we want it to auto assign our field, 102 00:06:17,370 --> 00:06:19,670 we use the autowired annotation. 103 00:06:20,990 --> 00:06:22,660 This tells Spring to construct and 104 00:06:22,660 --> 00:06:28,440 assign a GifRepository object to this instance field as soon as it's needed. 105 00:06:28,440 --> 00:06:30,970 The next question is, how will Spring know that 106 00:06:30,970 --> 00:06:35,090 the GifRepository class is a valid Spring component, as I mentioned? 107 00:06:36,440 --> 00:06:39,760 Here's a surprise, we'll use an annotation. 108 00:06:39,760 --> 00:06:43,350 Remember how we annotated our AppConfig class with ComponentScan? 109 00:06:44,440 --> 00:06:49,403 Because of this, Spring will scan that same package and all of it's sub packages. 110 00:06:49,403 --> 00:06:53,503 And consider all classes annotated with component as valid 111 00:06:53,503 --> 00:06:56,130 options depending on the class name. 112 00:06:57,130 --> 00:07:02,189 So all we need to do is switch to the GifRepository 113 00:07:02,189 --> 00:07:04,720 class and add the component annotation. 114 00:07:05,900 --> 00:07:11,540 So that's applied at the class level and it also comes from the Spring framework. 115 00:07:11,540 --> 00:07:12,920 There we go. 116 00:07:12,920 --> 00:07:17,540 Now, Spring will pick this up during the initial component scan as a result of our 117 00:07:17,540 --> 00:07:19,830 app config being loaded. 118 00:07:19,830 --> 00:07:22,980 And when the GIF controller needs a GifRepository class, 119 00:07:22,980 --> 00:07:27,820 Spring will create one for us or use one that's already been created. 120 00:07:27,820 --> 00:07:32,380 The process of this runtime creation of objects that is the injection 121 00:07:32,380 --> 00:07:34,910 using the Autowired annotation. 122 00:07:34,910 --> 00:07:38,810 This process without explicitly writing code to construct and 123 00:07:38,810 --> 00:07:44,580 assign objects is called dependency injection or DI for short. 124 00:07:44,580 --> 00:07:49,260 That is, we didn't ever write code that calls the GifRepository constructor and 125 00:07:49,260 --> 00:07:53,220 assign the resulting object to our GifRepository field. 126 00:07:53,220 --> 00:07:58,880 Instead, we let Spring wire our objects together with Autowire. 127 00:07:58,880 --> 00:08:01,600 As you continue your study of Java development, and 128 00:08:01,600 --> 00:08:05,460 especially with Spring, you'll be seeing much more DI. 129 00:08:05,460 --> 00:08:08,770 It's one of Spring's most powerful and core features. 130 00:08:08,770 --> 00:08:11,710 Now, back to our gifDetail's controller method. 131 00:08:11,710 --> 00:08:15,760 What we can do at this point is replace the creation of our GIF object with a call 132 00:08:15,760 --> 00:08:19,068 to the findByName method of the GifRepository field. 133 00:08:19,068 --> 00:08:24,880 So instead of creating a new object here, I will call on a gifRepository object, 134 00:08:24,880 --> 00:08:28,850 the findByName method. 135 00:08:28,850 --> 00:08:31,860 And to it we'll pass the name of the GIF that we'd like 136 00:08:31,860 --> 00:08:34,310 to grab from our gifRepository. 137 00:08:34,310 --> 00:08:38,940 Here, I'll use android-explosion. 138 00:08:38,940 --> 00:08:40,280 Forget my semi colon there. 139 00:08:41,330 --> 00:08:44,630 While this replacement will produce the same result, it represents 140 00:08:44,630 --> 00:08:48,410 a giant step in the direction of creating a dynamic detail page. 141 00:08:49,720 --> 00:08:53,710 Let's reboot and redeploy our app to make sure that we haven't broken everything. 142 00:08:53,710 --> 00:08:55,910 So I'll start my boot run task, and 143 00:08:55,910 --> 00:09:00,230 remember it could take a moment, you start it too soon you might see an error. 144 00:09:00,230 --> 00:09:02,580 Sometimes it's definitely safe to wait for 145 00:09:02,580 --> 00:09:07,210 that message in your console saying that the task has been complete. 146 00:09:08,450 --> 00:09:13,801 So I'll click bootRun again, And 147 00:09:13,801 --> 00:09:18,723 after I see all my output come through and see that Tomcat has started, I will switch 148 00:09:18,723 --> 00:09:24,220 back to my browser, and I'll refresh this to make sure nothing is yet broken. 149 00:09:24,220 --> 00:09:25,610 Excellent. 150 00:09:25,610 --> 00:09:26,280 All is well. 151 00:09:27,310 --> 00:09:30,470 It looks like our web app is still intact from the user's standpoint, so 152 00:09:30,470 --> 00:09:32,450 we're in great shape! 153 00:09:32,450 --> 00:09:35,520 Well, that was quite a bit of information in coding. 154 00:09:35,520 --> 00:09:37,980 It may seem like a lot to digest right now, so 155 00:09:37,980 --> 00:09:40,770 if you're feeling a bit overwhelmed don't panic. 156 00:09:40,770 --> 00:09:45,270 You can always go back in the video to re-watch the parts that are still unclear. 157 00:09:45,270 --> 00:09:48,850 Or you can come back to them after you finish the course. 158 00:09:48,850 --> 00:09:52,150 Also, as you're coding the application on your own machine, 159 00:09:52,150 --> 00:09:56,870 if you run into any problems, please use the forum to post your questions, and 160 00:09:56,870 --> 00:09:59,140 include your code as necessary. 161 00:09:59,140 --> 00:10:03,210 Let's take a break now before finishing the task of making our detail page, 162 00:10:03,210 --> 00:10:06,490 present the GIF details given by a specific GIF's URI.