Spring Boot foundation Ch04

Spring Boot foundation Ch04

Simple understanding

Since the B/S architecture (Browser/Server, Browser/Server mode) was invented, because of its cross platform, easy migration, easy to use and other characteristics, it has rapidly become the first choice of technical architecture, and the front-end Web technology has developed rapidly. People use front-end Web technology to build various application scenarios, such as e-commerce platform, online chat room, background management system, etc. Page technology has also evolved from the original JSP to the template engine; information interaction has developed from the previous XML to the more popular JSON; the development of concepts such as Spring IoC and Aop is more convenient for people to build Web systems.

Spring Boot provides comprehensive support for Web development, including development, testing and deployment. Spring Boot starter Web is a component that Spring Boot provides support for Web development, mainly including JSON, RESTful, using Tomcat as an embedded container and other functions.

Quick start

  1. Create project

  2. Import dependency in pom.xml file

     	<!-- Spring Boot web starter -->
     	<dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
         </dependency>
    
         <!-- MySQL drive,According to their own MySQL Version depends. -->
         <dependency>
             <groupId>mysql</groupId>
             <artifactId>mysql-connector-java</artifactId>
             <version>5.1.18</version>
         </dependency>
         
         <!-- Lombok Plug in, support generation setter/getter -->
         <dependency>
             <groupId>org.projectlombok</groupId>
             <artifactId>lombok</artifactId>
             <optional>true</optional>
         </dependency>
         
         <!-- Mybatis-Plus starter -->
         <dependency>
             <groupId>com.baomidou</groupId>
             <artifactId>mybatis-plus-boot-starter</artifactId>
             <version>3.1.1</version>
         </dependency>
    
  3. Configure the data source in application.properties

# data source
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/boot?useUnicode=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=123456

After completing the above steps - > create entity class - > create Dao layer interface (need to inherit BaseMapper) - > create business logic layer - > test

Note: the @ MapperScan("com.ymq.demo") annotation needs to be added to the test class to scan Mapper files.

First, write the most commonly used add, delete, modify and query (because after inheriting BaseMapper, there will be many commonly used methods, all of which can be called directly)

Service layer (business logic layer)

public interface StudentService {
    //Query all
    public List<Student> findByAll();

    //Newly added
    public Integer InsertByStudent(Student student);

    //modify
    public Integer UpdateByStudent(Student student);

    //delete
    public Integer DeleteByStuId(Integer stuId);
}
@Service
public class StudentServiceImpl implements StudentService {
    @Resource
    private StudentDao studentDao;
    
    /**
     * Query all: selectList(null), return List collection type
     * Add: insert(), parameter is object type, return int type
     * Delete: deleteById(), parameter is id type, return int type
     * Modify: updateById(), parameter is object type, return int type
     */
}

JSON support

JSON (JavaScript Object Notation) is a lightweight data exchange format, easy to read and write, and also easy to machine parse and generate. JSON adopts a text format completely independent of the language, but it also uses habits similar to the C language family (including C, C + +, C ා, Java, JavaScript, Perl, Python, etc.), which make JSON an ideal data exchange language.

In the early days, people used to use XML for information interaction. Later, JSON was used more simply. Up to now, most of the information interaction is based on JSON. In the early days, using JSON in the Spring system was more complex, requiring configuration of multiple XML and annotations. Now, in the Spring Boot system, JSON support is simple and complete, and only one annotation is needed in the Web layer.

Controller layer (control layer)

@RestController
public class StudentController {
    @Resource
    public StudentService studentService;

    @RequestMapping(value = "/select",method = RequestMethod.GET)
    public List<Student> toAll(){
        //Call the business logic layer method or directly call the method implementation provided by Dao layer
        List<Student> list = studentService.findByAll();
        return list;
    }
    
    /**
     * Here only demonstrates a query method, the rest of the methods want to know about Baidu, the general methods are almost the same.
     */
}

Annotation analysis:

  1. @RestController: it is equivalent to the combination of @ ResponseBody + @ Controller. If @ RestController annotation is used on the Web layer class, it means that all methods in this class will return results in the form of JSON, which is also a shortcut to JSON.
  2. @RequestMapping(value="/select", method= RequestMethod.GET): request by / select. method= RequestMethod.GET means that you can only use GET to request. If you use POST to request, you will GET 405 no access error.

Finally, run the startup class, open the browser and enter localhost:8080/select in the address bar to preview the query results. The port number is 8080 by default, or you can modify it in the configuration file yourself!

RESTful support

What is RESTful?

  1. RESTful is the most popular Internet software architecture. The term "Representational State Transfer" was put forward by Roy Thomas Fielding in his doctoral dissertation in 2000. It defines his architectural principles for Internet software. If an architecture conforms to the principle of REST, it is called a RESTful architecture.

  2. A core concept of RESTful architecture is Resource. From a RESTful point of view, everything in the network is a Resource. It can be a piece of text, a picture, a song, a service, etc. each Resource corresponds to a specific URI (uniform Resource locator) and is marked with it. Access to this URI can obtain this Resource.

Difference between URI and URL:

Uri: URI, a Uniform Resource Identifier (URI), which means that every available resource on the web, such as HTML documents, images, video clips, programs, etc., is located by a URI.

URL: a URL is a subset of a URI. It is the abbreviation of Uniform Resource Locator, translated as "Uniform Resource Locator". Generally speaking, URL is a string describing information resources on the Internet, which is mainly used in various WWW client programs and server programs. URL can be used to describe all kinds of information resources in a unified format, including file, server address and directory. URL is an implementation of URI concept.

  1. Resources can have many forms of Representation, that is, Representation of resources. For example, a picture can be in JPEG format or PNG format. URI only represents the entity of a resource, not its Representation.

  2. In the Internet, the interaction between the client and the server only conveys the expression of resources. The process of getting online is the process of calling the URI of resources and obtaining its different forms of expression. This interaction can only use the stateless protocol HTTP, that is, the server must save all the States. The client can use several basic operations of HTTP, including GET (GET), POST (create), PUT (update) and DELETE (DELETE), so that the resources on the server have a "State Transfer", that is to say, the so-called "Representational State Transfer".

Spring Boot's support for RESTful

Spring Boot fully supports the development of RESTful programs and supports front-end requests through different annotations. In addition to the frequently used annotations, Spring Boot also provides some combination annotations. These annotations help simplify the mapping of commonly used HTTP methods and better express the semantics of the annotated methods.

  1. @GetMapping: Processing Get requests

  2. @PostMapping: processing Post requests

  3. @PutMapping: for updating resources

  4. @DeleteMapping: Processing delete requests

  5. @PatchMapping: used to update some resources. In fact, these combined annotations are the shorthand version of @ RequestMapping we use. RESTful specifies the manipulation of resources in the request type.

For example, @ GetMapping(value="/xxx") is equivalent to @ RequestMapping(value = "/ xxx", method = RequestMethod.GET).

If you want to write a jsp page, you need to complete the following operations:

  1. Add configuration

    # Add a prefix to the jsp file
    spring.mvc.view.prefix=/WEB-INF/jsp/
    spring.mvc.view.suffix=.jsp
    
  2. Create webapp folder

    First select File - "Project Structure -" as shown in the figure


Then add webapp after selecting the path of the folder, and click OK to automatically make the created webapp folder effective. There will be a small blue dot on the effective folder.

Here are the created directories

  1. Import dependency (jsp will not work properly without import)

    <!-- Add to jstl Tag library dependency -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
    </dependency>
        
    <!-- Add to jsp Engine dependency, Spring Boot Built-in tomcat No such dependency -->
    <dependency>
        <groupId>org.apache.tomcat.embed</groupId>
        <artifactId>tomcat-embed-jasper</artifactId>
    </dependency>
    

Then you can write jsp pages in webapp

Example (user login):

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<! -- ${pagecontext. Request. Contextpath} is the relative path of the project -- >
<form action="${pageContext.request.contextPath}/stu/toLogin" method="post">
    User name:
    	<input type="text" name="stuName" required ><br/>
    Password:
    	<input type="password" name="stuPassword" required ><br/>
    < input type = "submit" value = "login" >
</form>

Controller layer

@Controller
@RequestMapping("/stu")
public class StudentController {
    @Resource
    public StudentDao studentDao;
    
    //validate logon
	@PostMapping(value = "/Login")
    public String Login(String stuName,String stuPassword,HttpSession session){
        //This step can be completed in the business logic layer. I omitted the business logic layer here, so I wrote it directly in the control layer
        QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("stu_name",stuName);	//The first value is the database field name, and the second is the parameter name
        queryWrapper.eq("stu_password",stuPassword);
        
		//How to log in
        Student student = studentDao.selectOne(queryWrapper);
        //How to query all users
        List<Student> list = studentDao.selectList(null);
        
        //Verify whether the login is successful; if it is successful, it will jump to the main page (mian.jsp) and if it fails, it will jump to the failed page (error.jsp)
        if (student != null){
            System.err.println("Login succeeded!");
            //Return the value to the main page, realize the function of welcome XXX, and then display the information of all users
            session.setAttribute("student",student); 
            session,setAttribute("StudentList",list);
            return "main";
        }else {
            System.err.println("Login failed!");
            return "error";
        }
    }
}

JSP main page

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <h3>Welcome: ${student.stuName}</h3>
    <table>
        <tr>
            <th>Id</th>
            <th>User name</th>
            <th>Password</th>
            <th>operation</th>
        </tr>
		<!-- Use c Loop through the queried data -->
        <c:forEach var="stu" items="${StudentList}">
            <tr>
                <td>${stu.stuId}</td>
                <td>${stu.stuName}</td>
                <td>${stu.stuPassword}</td>
                <td>
                    <a href="${pageContext.request.contextPath}/stu/findByStuId?stuId=${stu.stuId}">modify</a>
                    <a href="#" onclick="expurgate(this,${stu.stuId})">delete</a>
                </td>
            </tr>
        </c:forEach>
    </table>

This completes a simple login function. In addition, it can be directly run in the test layer. The results will be directly output to the console without using the browser to preview. Next, I will give you a brief explanation.

Example (test using the test layer):

Controller layer

@RestController
public class StudentController {
    //Query method
    @GetMapping(value = "/select")
    public List<Student> findAllStudent(){
        //Because this is a simple demonstration, I directly omit the code of business logic layer and use dao. Method to implement it
        List<Student> list = studentDao.selectList(null);
        return list;
    }

    //New method
    @PostMapping(value = "/toInsert")
        public void toInsert(Student student){
            studentDao.insert(student);
    }
}

Add dependency

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <scope>test</scope>
</dependency>

test level

@RunWith(SpringRunner.class)
@SpringBootTest
public class StudentTest {
    @Resource
    private WebApplicationContext wac;

    private MockMvc mockMvc;

    @Before
    public void setup(){
        //Configure MVC environment
        this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
    }

    //Query all users
    @Test
    public void All() throws Exception {
        String mvc= mockMvc.perform(MockMvcRequestBuilders.get("/select")).andReturn().getResponse().getContentAsString();
        //Direct output
        System.err.println(mvc);
    }
    
    @Test
    public void testInsert() throws Exception {
        final MultiValueMap<String, String> mvm = new LinkedMultiValueMap<>();
        mvm.add("stuName","wangwu");
        mvm.add("stuPassword", "12345");

        mockMvc.perform(MockMvcRequestBuilders.post("/toInsert").params(mvm))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andDo(MockMvcResultHandlers.print());
    }
}

Attribute resolution:

  1. Perform(... )Build a request and return the ResultActions instance, which can get the return content of the request.

  2. WebApplicationContext: the context environment injected into Spring Web

  3. MockMvc: MockMvc realizes the simulation of Http request, which can directly use the form of network and convert to the call of Controller, so that the test speed is faster and does not depend on the network environment, and provides a set of verification tools, which can make the request verification unified and more convenient.

  4. @Before note: represents the content that needs to be loaded in advance when the test starts.

  5. Mockmvrequestbuilders. Get ("/ select"): the path of the test, corresponding to the path set in the controller layer.

  6. andExpect(… )The expected result judgment can be called multiple times.

  7. andReturn() returns the MvcResult object, which can obtain the returned view name, the returned Response status and the interceptor collection to intercept the request.

  8. andDo(... )Continue with actions such as mockmvresulthandlers. Print() to print response information.

In addition to the above two ways, you can also use external tools to test, such as Postman, PostWoman, etc. if you are interested, you can try it.

Next, I'm going to show you the deletion and modification of JSP page (modification is similar to addition, so here's a brief introduction of modification)

  1. Delete users (ajax required)

    controller layer

    //delete user
    @DeleteMapping(value = "/toDelete/{id}")
    @ResponseBody	//You need to add
    public Integer toDelete(@PathVariable("id") Integer id) throws IOException {
        Integer row = studentDao.deleteById(id);
    	return row;
    }
    

    Import jQuery dependency

    <!-- jQuery rely on -->
    <dependency>
        <groupId>org.webjars</groupId>
        <artifactId>jquery</artifactId>
        <version>3.4.1</version>
    </dependency>
    

    Configure filters (required for ajax local refresh)

    # Enable hiddenMethod filter
    spring.mvc.hiddenmethod.filter.enabled=true
    

    Main page delete click event (local refresh with ajax)

    <script src="${pageContext.request.contextPath}/webjars/jquery/3.4.1/jquery.js"></script>
    <script>
        function expurgate(th,id) {
            if (confirm("Are you sure you want to delete this user?")){
                $.ajax({
                    url:"${pageContext.request.contextPath}/stu/toDelete/"+id,
                    type:"POST",
                    data:{_method:"DELETE"},
                    dataType:"json",
                    success:function(data){
                        if (data > 0){
                            $(th).parent().parent().remove();
                            alert("Delete successfully!")
                        }else {
                            alert("Delete failed!")
                        }
                    }
                });
            }
        }
    </script>
    

ajax attribute resolution:

url: the address to send the request.
type: request method, which can be POST or GET, and the default is GET.
Data: if the data sent to the server is not in string format, it will be automatically converted to string format. The writing method is generally data:{_method: "DELETE"}.
dataType: the type of data expected from the server.
success: request the callback function for the Function type parameter after the request is successful.

Complete the above operations to achieve the deletion function of local refresh.

  1. Modify user

    Controller layer

    @Controller
    @RequestMapping("/stu")
    public class StudentController {
        @Resource
     public StudentDao studentDao;
        
        //Query according to the modified user id, and then jump to the modified page to give the default value
        @GetMapping(value = "/findByStuId")
     public String findByStuId(Integer stuId, Model model){
            //Query by id
            Student stu = studentDao.selectById(stuId);
            model.addAttribute("student",stu);
            return "amend";
        }
    
        //Modify user information
        @PutMapping(value = "/toUpdate")
        public String toUpdate(Student student){
            Integer row = studentDao.updateById(student);
            if (row > 0){
                System.err.println("Modification succeeded!");
                //Use redirection to return to the main page after modification
                return "redirect:Main";
            }else {
                System.err.println("Modification failed!");
                return "error";
            }
        }
        
        //Jump to main page
        @GetMapping("/Main")
        public String Main(HttpSession session){
            //Query all data, reload data after data modification
            List<Student> list = studentService.findByAll();
            session.setAttribute("StudentList",list);
            return "main";
        }
    }
    

    Modify information page

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <form action="${pageContext.request.contextPath}/stu/toUpdate?stuId=${student.stuId}" method="post">
        <input hidden value="put" name="_method">
        <table border="1px">
            <tr>
                <th style="font-size: 20px;" colspan="2">Modify user</th>
            </tr>
            <tr>
                <td>User name</td>
                <td><input type="text" name="stuName" value="${student.stuName}" required /></td>
            </tr>
            <tr>
                <td>Password</td>
                <td><input type="text" name="stuPassword" value="${student.stuPassword}" required /></td>
            </tr>
            <tr>
                <td colspan="2">
                    <input type="submit" value="Preservation" />
                    <input type="button" value="Return" onclick="history.go(-1);" />
                </td>
            </tr>
        </table>
    </form>
    

Modify the function after completion.

Support hot deployment

Hot deployment: when using idea to develop projects such as web, you need to restart the project to take effect every time you modify the Controller, JSP, etc , so it provides a component to implement the function that can be completed without restarting the project (simply speaking, the code is written without restarting the project, but can be refreshed directly in the browser)!

Quick start

  1. Import dependency

    <!-- Add to spring-boot-devtools Component dependency -->
    <dependency>
    	<groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <optional>true</optional>
    </dependency>
        
    <!-- stay plugin Configure another property in fork,And configured to true -->
    <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <configuration>
        	<fork>true</fork>
        </configuration>
    </plugin>
    
  2. Configure IDEA

2.1: Select File - > Settings - > compiler command, and then check Build project automatically.

2.2: use the shortcut key Ctrl + Shift + A, enter Registry in the input box, double-click the first Registry, and check the check box of compile.automake.allow.when.app.running in the open interface.

2.3: configure Update classes and resources in the Edit Configurations option.


Interceptors and filters

In a Web project, the controller can handle specific business requests, and the processing of public functions can be realized through filters or interceptors using the idea of AOP. Both filters and interceptors are specific implementations of aspect oriented programming.

The difference between the two:

  1. Filter is dependent on the Servlet container and is part of the Servlet specification, while interceptor is independent and can be used under any circumstances.
  2. Filter is executed by Servlet container callback, while interceptor is usually executed by dynamic agent.
  3. Filter's life cycle is managed by Servlet container, while interceptor can be managed by IoC container, so it can obtain other Bean instances by injection and other ways, so it will be more convenient to use.

Custom filter

  1. Filter, also known as filter, can intercept requests from all users at the front end. Web developers use filter technology to intercept all web resources managed by web server, such as JSP, Servlet, controller, static picture file or static HTML file, so as to achieve some special functions. For example, some advanced functions such as URL level access control, filtering sensitive words, excluding characters threatened by XSS, and recording request logs are implemented.

  2. Spring Boot has built-in filters, such as OrderedCharacterEncodingFilter for processing encoding and HiddenHttpMethodFilter for request conversion, which can also be customized according to our needs.

  3. There are two ways to implement user-defined Filter. The first is to use @ WebFilter, and the second is to use FilterRegistrationBean. After practice, it is found that the priority order of user-defined Filter cannot take effect (it can only be inverted according to the alphabetical order of the Filter class name, and the priority is higher than the Filter configured by FilterRegistrationBean Therefore, the second scheme is recommended.

Implementation steps of custom filter:

  1. Implement the Filter interface and override the doFilter() method.

  2. Add @ Configuration annotation to add custom Filter to the Filter chain.

Example

Implement the Filter interface and override the doFilter() method

//Custom filter
public class AuthorizationFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //Convert to http protocol type
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        
        //Determine whether there is a value in the Session
        if (request.getSession().getAttribute("student") == null){
            response.setContentType("text/html;charset=UTF-8");
            PrintWriter out = response.getWriter();
            //When prompted, jump back to the login page and ask the user to log in
            out.print("<script>alert('Please log in first!');location.href='"+request.getContextPath()+"/login.jsp';</script>");
        }else {
            //Pass to the next filter and return the current request if there is no next
            filterChain.doFilter(request,response);
        }
    }
}

Add @ Configuration annotation to indicate that it is a Configuration class, and then add the custom Filter to the Filter chain

//Custom filter
@Configuration
public class FilterConfig {
    @Bean
    public FilterRegistrationBean filterRegistrationBean(){
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(new AuthorizationFilter());
        registrationBean.setName("AuthorizationFilter");
        //If the user does not log in and directly enters the main page, it will be blocked, and then jump to the specified page
        registrationBean.addUrlPatterns("/stu/Main");
        registrationBean.setOrder(5);
        return registrationBean;
    }
}

jsp (index.jsp) page

The function of this filter is that if the user wants to enter the main page without login, the filter will be triggered to return to the login page

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Select Page</title>
</head>
<body>
    <a href="login.jsp">Sign in</a>
    <a href="${pageContext.request.contextPath}/stu/Main">Main page</a>
</body>
</html>

Controller layer

@Controller
@RequestMapping("/stu")
public class StudentController {
    @GetMapping("/Main")
    public String Main(HttpSession session){
        List<Student> list = studentService.findByAll();
        session.setAttribute("StudentList",list);
        return "main";
    }
}

After completing the above operations, directly visit the index.jsp page in the browser, and then when the user has not logged in but directly click the hyperlink of the main page, the filter will be triggered, and then jump to the specified page!

custom interceptor

Implementation steps of custom Interceptor:

  1. Implement the HandlerInterceptor interface and rewrite three methods;
  2. Implement the WebMvcConfigurer interface, rewrite the addInterceptors method, and register the interceptor.

Example

Implement the HandlerInterceptor interface, which includes three methods: preHandle is executed before the request is executed, postHandler is executed after the request is executed, but it will be executed only when the preHandle method returns true, afterCompletion is executed after the view rendering is completed, and preHandle is also required to return True, which is usually used to clean up resources and other work.

//custom interceptor 
public class AuthorizationInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //Determine whether there is a value in the session
        if (request.getSession().getAttribute("student") == null){
            //Set character encoding
            response.setContentType("text/html;charset=UTF-8");
            
            //Jump to login page when entering error path
            PrintWriter out = response.getWriter();
            out.print("<script>alert('Please log in first!');window.location.href='login.jsp';</script>");
            return false;
        }
        return true;
    }
}

In addition to implementing the above interface, we need to configure and register it:

//custom interceptor 
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new AuthorizationInterceptor())
                .addPathPatterns("/**")     //Indicates blocking all paths
                .excludePathPatterns("/stu/login","/stu/toLogin"); //Indicates the path of release. Other paths can be used through the path of release
    }
}

Implement the WebMvcConfigurer interface; rewrite the addInterceptors method to configure the interceptor. There are two main configuration items: the first is to specify the interceptor, and the second is to specify the interceptor URL and the exclusion URL.

The custom interceptor has been developed successfully. The comparison filter shows that the interceptor is simpler and more convenient to configure exclusion path rules, and it is more flexible because it is managed by IOC container.

Note: the above is just a simple interceptor writing, when the program runs, entering the wrong address in the browser address bar will directly jump to the specified path page, but if you enter other paths through the path released by the interceptor, if you enter the wrong path again, it will cause 404 error!!

Packaging deployment

  1. Spring Boot uses embedded containers, so its deployment mode is very simple and flexible. On the one hand, you can package the Spring Boot project as an independent Jar or War package to run, or you can separately package it as a War package and deploy it to the Tomcat container to run. If it involves the deployment of large-scale models, Jinkins is one of the best choices.

  2. The development of embedded container technology has laid a solid foundation for Spring Boot deployment. The embedded container not only plays a huge role in the deployment phase, but also brings great convenience in the development and debugging phase. Compared with the tedious configuration of Tomcat when developing Web projects in the past, we will have a deeper feeling when using Spring Boot embedded container. To develop a Web project with Spring Boot, you don't need to care about the environment of the container, just concentrate on writing business code.

  3. Embedded containers bring more changes to deployment. Now Maven and Gradle have become indispensable building tools for our daily development. Using these tools, it's easy to package the project into Jar or War packages. Only one command is needed on the server to start the project.

Multi environment configuration

In our development process, we are bound to face multiple environment problems, such as development environment, test environment, production environment, and different database connection pools and other configuration information in different environments. If they are all written in a configuration file, you need to manually modify the corresponding environment parameters to start in different environments, which is prone to errors. Spring Boot supports the use of multiple configuration files. You only need to specify the corresponding configuration file at startup.

First, add the following configuration in pom.xml file:

<profiles>
    <profile>
        <id>dev</id>
        <properties>
        	<env>dev</env>
        </properties>
        <activation>
        	<activeByDefault>true</activeByDefault>
        </activation>
    </profile>

    <profile>
        <id>test</id>
        <properties>
        	<env>test</env>
        </properties>
    </profile>

    <profile>
        <id>pro</id>
        <properties>
        	<env>pro</env>
        </properties>
    </profile>
</profiles>

Then add the following configuration to the pom.xml file's compile tag:

<resources>
    <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
        <excludes>
            <exclude>application-dev.properties</exclude>
            <exclude>application-pro.properties</exclude>
            <exclude>application-test.properties</exclude>
        </excludes>
    </resource>
    <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
        <includes>
        	<include>application-${env}.properties</include>
        </includes>
    </resource>
</resources>

In Spring Boot, the multi environment configuration file name needs to meet the format of application-{profile}.properties, where {profile} corresponds to the environment ID.

Create the following three files in the resources directory:

  1. application-dev.properties: used by development environment ({profile}=dev)
  2. application-test.properties: the test environment uses {profile}=test)
  3. application-prod.properties: used by production environment ({profile}=prod)

Different configuration files correspond to different environments, and different configurations are enabled through parameter settings during startup. During the development process, the application.properties file is set through the spring.profiles.active property, and its value corresponds to the {profile} value.

# In application.properties The configuration environment used in the file can be used to apply the configuration in the corresponding environment
spring.profiles.active=dev

Resolution: there will be multiple environments in a project, all of which need to use multi environment configuration for testing, development and other purposes. Different configurations can be set in different environments, such as database, project root directory, port number, etc.

Server configuration

Common configuration:

# Project contextPath, generally not configured
server.servlet.context-path=/crm
    
# Error page, specifying the URL to jump when an error occurs
server.error.path=/error
    
# Service port
server.port=8090
    
# Maximum session timeout(Minute),Default is 30
server.session-timeout=60

If Tomcat is used, you can also set it as follows:

# tomcat Max threads, default is 200
server.tomcat.max-threads=600
    
# URI encoding of tomcat
server.tomcat.uri-encoding=UTF-8
    
# The temporary folder where Tomcat logs, dumps and other files are stored. By default, it is the tmp folder of the system
server.tomcat.basedir=/tmp/log
    
# Open the Access log of Tomcat and set the log format
server.tomcat.access-log-enabled=true

# The accesslog directory is basedir by default/logs
server.tomcat.accesslog.directory=basedir/logs

# Log file directory
logging.path=/tmp/log

# Log file name, spring by default.log
logging.file=crm.log

Pack Project

The maven project is used for demonstration. There are two packaging methods: jar package and war package (the default is jar package)

Maven plug-ins using IDEA can be packaged automatically:

[failed to save the image in the external link. The source station may have anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-gzh64cjr-1583660559966) (C: \ users \ YMQ \ appdata \ roaming \ typora \ typora user images \ 1583658529906. PNG))

You can also click install to package in maven's local warehouse. After printing the dual success on the console, it means that the package has been completed.

If you want to make a war package, you can set it in the pom file.

After packaging, the jar package will be generated to the target directory. The name is generally in the form of "project name + version number. Jar".

If you want to run the jar package, you can start it in cmd
Use Win+R and enter cmd to open the page, and then run as follows:

//Jump to the disk where the jar package is stored
C:\Users>e:

//Jump to the corresponding project folder
E:\>cd E:\springWeb

//Enter the command java -jar target/demo-0.0.1-SNAPSHOT.jar to start running
E:\springWeb>java -jar target/demo-0.0.1-SNAPSHOT.jar

Press Ctrl+C twice or close the cmd page to exit the program.

Published 5 original articles, won praise 0, visited 66
Private letter follow

Tags: Spring JSP Tomcat JSON

Posted on Sun, 08 Mar 2020 06:46:54 -0400 by sharal