JavaRush/Java Blog/Random EN/Introduction to Maven, Spring, MySQL, Hibernate and the f...
Макс
Level 41

Introduction to Maven, Spring, MySQL, Hibernate and the first CRUD application (part 1)

Published in the Random EN group
members
Good afternoon. In this article I would like to share my first encounter with things like Maven, Spring, Hibernate, MySQL and Tomcat in the process of creating a simple CRUD application. This is the first part of 4. The article is intended primarily for those who have already completed 30-40 levels here, but have not yet ventured beyond pure Java and are just beginning (or are about to begin) to enter the open world with all these technologies, frameworks and other unfamiliar words. Introduction to Maven, Spring, MySQL, Hibernate and the first CRUD application (part 1) - 1

Content:

Introduction

I started getting acquainted with technologies and frameworks that were new to me by studying various examples in which they were used, because usually I understand something best when I see it in action using an example of a full-fledged application. Typically, such examples are CRUD applications ( C reate, Read , U pdate, D elete), the Internet is full of such examples of varying degrees of complexity. The problem is that they usually don’t explain in detail how, what and why was done there, why such and such a dependency was added, why such and such a class is needed, etc. In most cases, they take a completely finished application, with a final POM file, with final versions of classes, and simply run through each one, without focusing on the little things that probably seem obvious to an experienced person. I’ve looked at a lot of such examples and it’s usually clear how everything works, but how they came to this is not entirely clear. Therefore, I decided that such an example would be useful, not from the position of an experienced developer, but from the position of a beginner who has never dealt with Spring, Hibernate and other things.
Introduction to Maven, Spring, MySQL, Hibernate and the first CRUD application (part 1) - 2
I will try to describe in as much detail as possible (as far as my understanding allows me) my entire path of creating a CRUD application, starting with something at the simplest Hello World level. First of all, I do this for myself, because when you try to describe, tell, explain something, it is much better absorbed and organized in your head. But if this is useful to someone and helps them figure something out, I will be very glad. In this example, let's try to create a simple CRUD application using Maven , Tomcat , Spring , Hibernate and MySQL . Preliminary steps such as installing Maven , MySQL , using the Ultimate version of the idea, etc. I think there is no need to describe in detail, there should be no problems with this. It is worth noting that in this example, the configuration will be configured using Java classes (called JavaConfig) without using xml.

Creating a Project

So, since I’m a newbie, we won’t use any obscure archetypes. Spring initializr still sounds too scary. Therefore, we will create the most ordinary simple Maven project. I don’t have a domain name, so in groupid I’ll just write testgroup, and in artifactid I’ll write the name, for example, filmography(this will be a list of films). We create a project and choose Enable auto-importwhen the idea suggests it. Thanks to this, every time we make any changes to the POM file (Project Object Model, this file describes the entire structure of the Maven project), everything will immediately be automatically applied to the project. The libraries will be taken from our local repository if we already have them, or if we use some new dependencies that we have not dealt with before, Maven will simply download them via the Internet from the central repository. Maven also has a function to download sources and documentation (Download Sources and/or Documentation). It’s also very convenient, if something is not clear with some class or method, you can go to the source code and see how it all works inside. Let's add a couple of details. This will be a web application and we will use Tomcat . To deploy an application to Tomcat, you need to transfer it there in the form of a war archive (Web Application Resource, a special format for web applications). To do this, add the following line to the POM file so that the application is compiled into a war archive:
<packaging>war</packaging>
Well, you will also need a special directory for web sources, in our case there will be jsp pages and some web resources. Let's create a maindirectory webapp. It should be called exactly that and be located in exactly mainthe same way as java, resourcesbecause this is the standard Maven directory structure. Once we have installed the package in warand thus determined that this is a web project, the directory webappwill be automatically marked as Web application sources (there will be a blue dot on it) and everything related to the web will be searched in this folder. And one moment. By default, Maven uses language version 1.5, but I want to use, for example, version 1.8 - Java 8 (You can take 10, or 11, but still there are no plans to use any features from there, so let it be 8). This can be solved very simply, we write in Google something like “Maven java 8” and see what needs to be added to the POM file so that Maven compiles our classes for the required version. As a result, we have the following: Introduction to Maven, Spring, MySQL, Hibernate and the first CRUD application (part 1) - 3

Spring MVC connection

You have to start somewhere. According to the plan, we will connect the database and use Hibernate, but this all sounds a little too scary for now. We need to do something simpler first. Spring MVC, this is already better, we have been familiar with the MVC pattern for a long time, it was used in half of the large tasks of the course. From here we will start dancing. To create a web application with Spring MVC, we also need a Servlet-API, i.e. that thing with the help of which the request-response interaction will take place. Let's try to connect this. We go to Google, look for the necessary dependencies in the Maven repository and add them to the pom.xml. Introduction to Maven, Spring, MySQL, Hibernate and the first CRUD application (part 1) - 4In the External Libraries section you can see that not only spring-webmvc was loaded , but also a bunch of other things. Those. we don't need to additionally include dependencies for spring core , context , beans , etc. that we need, everything we needed was pulled up along with spring-webmvc .

We need to make a small disclaimer. It is usually recommended to still add a dependency separately for each library used, even if they are already bundled with those already added, because this can help avoid some problems and glitches.

A simple example. Let's say we added a dependency that uses some API, and at the same time it will pull up some kind of implementation for this API. And then we added another dependency that uses the same API and also pulls up some of its implementation for this, but this time it’s different. Thus, we will have 2 different implementations of the same API. And if we ourselves want to use some methods of this API somewhere, then a problem will arise, because the system will not know which implementation to use, it will choose randomly, perhaps not the one we expected. And if you explicitly specify a dependency for one of the implementations, then priority will be given to it.

However, this is not such a strict recommendation; it mainly applies to large projects where many different libraries from different companies are used. We won’t do that here, so as not to load the POM file too much; no problems are expected. But nevertheless, it is still worth keeping this in mind.

One more note. What does provideddepending mean javax.servlet-api? Scope is the scope of the dependency, providedwhich means that the dependency will be available at the stage of compiling and testing the application, but it will not be archived. The fact is that to deploy the application we will use a servlet container, Tomcat, and it already has such libraries inside, so there is no need to transfer them there and burden the archive with unnecessary load. Looking ahead, for the same reason we will do without the usual method main, because it already exists inside Tomcat.

Creating Pages and Controller

Let's try to cook up something simple now. First, let's create an webappadditional directory, for example pages, in which our views will be stored, i.e. jsp pages, and create a couple of pages. We will need a page on which in the future a list of films will be displayed, for example films.jsp, and perhaps we can make a separate page for editing, let it be editPage.jsp. We won’t fill them in with anything serious for now; just for testing, we’ll make a link on one page to another. Now we need a class that will process requests, i.e. controller. Let's add a new package controllerand create a class in it FilmController(in general, it is not necessary to package everything in different packages, this application will be very small and simple, but in a normal project there can be many controllers, configuration classes, models, etc., so even starting with small projects, it’s better to immediately get used to doing everything in an orderly and structured manner so that there is no mess). In this class we will create methods that will return our views in response to requests.
package testgroup.filmography.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class FilmController {

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public ModelAndView allFilms() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("films");
        return modelAndView;
    }

    @RequestMapping(value = "/edit", method = RequestMethod.GET)
    public ModelAndView editPage() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("editPage");
        return modelAndView;
    }
}
What's the point? Spring MVC has a thing called DispatcherServlet. This is like the main controller, all incoming requests pass through it and it then passes them on to a specific controller. The annotation @Controllerjust tells Spring MVC that this class is a controller (well, logical in general), the dispatcher will check the annotations @RequestMappingto call the appropriate method. The annotation @RequestMappingallows you to set addresses for controller methods, by which they will be available in the client (browser). It can also be applied to the controller class to set, so to speak, the root address for all methods. allFilms()The parameter for the method valueis set to " /", so it will be called immediately when the combination http://host:port/ is entered in the browser (i.e., by default it is http://localhost:8080/ or http://127.0 .0.1:8080/ ). The parameter methodspecifies what type of request is supported (GET, POST, PUT, etc.). Since here we only receive data, GET is used. Later, when methods for adding and editing appear, there will already be POST requests. (By the way, instead of an annotation @RequestMappingindicating a method, you can use annotations @GetMapping, @PostMappingetc. @GetMappingequivalently @RequestMapping(method = RequestMethod.GET)). In our methods, we create an object ModelAndViewand set the name of the view that needs to be returned.

Configuration

Let's move on to setting up the configuration. configLet's create a class in the package WebConfig. It will have only one method that returns an object of type ViewResolver, this is the interface necessary to find a representation by name.
package testgroup.filmography.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "testgroup.filmography")
public class WebConfig {

    @Bean
    ViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setPrefix("/pages/");
        viewResolver.setSuffix(".jsp");
        return viewResolver;
    }
}
@Configurationtells Spring that this class is a configuration class and contains the definitions and dependencies beanof the components. Beans are objects that are managed by Spring. The annotation is used to define a bean @Bean. @EnableWebMvcallows you to import Spring MVC configuration from the WebMvcConfigurationSupport. You can also implement, for example, an interface WebMvcConfigurerthat has a whole bunch of methods, and customize everything to your liking, but we don’t need to go into that yet, the standard settings will suffice. @ComponentScantells Spring where to look for the components it should manage, i.e. classes marked with an annotation @Componentor its derivatives such as @Controller, @Repository, @Service. These annotations automatically define the class bean. In the method, viewResolver()we create its implementation and determine where exactly to look for representations in webapp. Therefore, when in the controller method we set the name " films" the view will be found as " /pages/films.jsp" So, we have a configuration class, but for now it is just some kind of separate class, it does not affect our application in any way. We need to register this configuration in the Spring context. For this you need a class AbstractAnnotationConfigDispatcherServletInitializer. In the package, configwe create its successor, say AppInitializer , and implement its methods.
package testgroup.filmography.config;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[0];
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{WebConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}
The last method registers addresses and there are 2 more methods for registering configuration classes. Web configurations, where ViewResolver's and the like are defined, are placed in getServletConfigClasses(). It’s better to read about all this in the documentation and various guides, but in our case it’s not necessary to delve into this yet, ours, WebConfigin principle, can be RootClassesdefined in both, you can even define both at once, it will still work. One more thing. There may be problems with encoding when, when sending values ​​with Russian characters from the form, the result will be scribbles. To solve this problem, we will add a filter that will pre-process requests. We go to the AppInitializer class and override the method getServletFilters, in which we indicate the desired encoding, it, of course, should be the same as everywhere else, as on the pages and in the database:
protected Filter[] getServletFilters() {
        CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
        characterEncodingFilter.setEncoding("UTF-8");
        characterEncodingFilter.setForceEncoding(true);
        return new Filter[] {characterEncodingFilter};
    }
Well, everything seems to be set up, you can try to run it and see what happens. Run -> Run -> Edit Configurations -> Add New Configuration -> Tomcat Server -> Local Next, you need to select an artifact to deploy. The idea itself will give a hint Warning: No artifacts marked for deployment . Click the fix button and select ...: war exploded . Or you can go to Deployment -> add -> Artifact -> ...: war exploded . Introduction to Maven, Spring, MySQL, Hibernate and the first CRUD application (part 1) - 5And you also need to go to Deployment and set the Applecation context field (this will be part of the url address where the application will be available in the browser) to " /". Introduction to Maven, Spring, MySQL, Hibernate and the first CRUD application (part 1) - 6Then our application will be immediately available at http://localhost:8080/ (but you can also specify something there, for example " /filmography", and then you will just need to add this to all addresses, i.e. for example there will be no " http://localhost:8080/edit" , but it will be "http://localhost:8080/filmography/edit" ). Click Run and wait until it starts. Here's what I got: Introduction to Maven, Spring, MySQL, Hibernate and the first CRUD application (part 1) - 7Everything seems to be fine, but there is one caveat. The fact is that our pages are now publicly accessible and can be accessed directly by writing the path in the address bar. We enter http://localhost:8080/pages/films.jsp and now we have received our page without the controller’s knowledge. Somehow this is not very correct, so we will create a webappspecial directory WEB-INF. What's inside will be hidden from the public and can only be accessed through a controller. We place the directory with our views ( pages) in WEB-INF, and ViewResolveraccordingly add it to the prefix:
viewResolver.setPrefix("/WEB-INF/pages/");
Now we get our page at http://localhost:8080 , but if we try directly to http://localhost:8080/WEB-INF/pages/films.jsp we get a 404 error. Well, great, we have the simplest web -application, Hello World as they say. The project structure currently looks like this:
Introduction to Maven, Spring, MySQL, Hibernate and the first CRUD application (part 1) - 8

Model

We already have views and a controller, but in MVC there is also a 3rd letter, so to complete the picture we will also add a model. In the package, modellet's create a class Film, for example, with the following fields: int id, String title(title), int year(year of release), String genre(genre) and boolean watched(i.e. have you already watched this film or not).
package testgroup.filmography.model;

public class Film {
    private int id;
    private String title;
    private int year;
    private String genre;
    private boolean watched;
// + Getters and setters
}
Nothing special, just an ordinary class, private fields, getters and setters. Objects of such classes are also called POJO(Plain Old Java Object), well, i.e. "simple java object". Let's now try to create such an object and display it on the page. For now, we won’t worry too much about how to create it and initialize it. To try it out, let’s just stupidly create it directly in the controller, for example, like this:
public class FilmController {
    private static Film film;

    static {
        film = new Film();
        film.setTitle("Inception");
        film.setYear(2010);
        film.setGenre("sci-fi");
        film.setWatched(true);
    }
And add this object to ours ModelAndViewusing the method addObject:
@RequestMapping(method = RequestMethod.GET)
    public ModelAndView allFilms() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("films");
        modelAndView.addObject("film", film);
        return modelAndView;
    }
Now we can display this object on our page. In films.jspinstead of Hello World we will write ${film}and the object corresponding to the attribute name " film" will be substituted here. Let's try to run it and see what happened (for clear output of the object, the class Filmwas redefined toString()):
Introduction to Maven, Spring, MySQL, Hibernate and the first CRUD application (part 1) - 9

Model-View-Controller

At this stage, we already seem to have a full-fledged Spring MVC application. Before moving on, it would be good to take a look at everything again and figure out how it all works. On the Internet you can find many pictures and diagrams about this, I like this one:
Introduction to Maven, Spring, MySQL, Hibernate and the first CRUD application (part 1) - 10
When we write a request in the browser line, it is accepted Dispatcher Servlet, then it finds a suitable controller to process this request using HandlerMapping(this is an interface for selecting a controller, checks which of the available controllers has a method that accepts such an address), calls a suitable method and Controllerreturns information about the view, then the dispatcher finds the desired view by name using ViewResolver'a, after which the model data is transferred to this view and we get our page as output. Something like this. To be continued... Introducing Maven, Spring, MySQL, Hibernate and the first CRUD application (part 1) Introducing Maven, Spring, MySQL, Hibernate and the first CRUD application (part 2) Introducing Maven, Spring, MySQL, Hibernate and the first CRUD application (part 3) Introduction to Maven, Spring, MySQL, Hibernate and the first CRUD application (part 4)
Comments
  • Popular
  • New
  • Old
You must be signed in to leave a comment
This page doesn't have any comments yet