SpringBoot+Vue commodity management system mode introduction and project transformation

Article catalog

md format documents can be obtained by clicking the small card below

0 review Vue

MVVM: front end design pattern. It implements bidirectional data binding. What is its relationship with MVC? MVC does not implement bidirectional data binding

2 two way data binding: when the model data changes, the page view layer changes automatically; When the page data changes, the model layer data will also receive the changes

3 life cycle hook function: created: new vue() is completed. It is usually used to obtain data before two-way data binding, followed by two-way binding

Note: review the 8 hook functions of vue

4 instruction:

  • Interpolation expression {}
  • v-text,v-html
  • v-model: bind input, radio, CheckBox, textarea and select of form elements
  • v-on: event modifier is short for @, including @ click @mouseover @mouseout @keydown @keyup
  • js bubbling event: prevent bubbling. stop
  • prevent the occurrence of the default event of js. prevent
  • v-if
  • v-for
  • v-bind: bound attributes, short for:
  • Computing attributes: essentially methods, but we can call them as attributes
  • axios: send ajax
  • Component: parent-child component value transfer

1 Vue review-

Objective: 1 review the basic usage of Vue

2. Take this exercise as the starting point to explain the development method of front and rear end separation

1.1 case requirements

Query, add, modify and delete commodities

Front end (browser side): vue

Back end (server side): spring boot+spring mvc+mybatis

1.2 database design and table structure

CREATE TABLE `t_goods` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `image` varchar(255) DEFAULT NULL,
  `price` double(20,0) DEFAULT NULL,
  PRIMARY KEY (`id`)
) 

Import data:

INSERT INTO `t_goods` VALUES ('1', 'Huawei G9 Youth white Mobile Unicom Telecom 4 G Mobile dual card dual standby', 'https://img12.360buyimg.com/n1/jfs/t17050/106/1124838205/250590/7e63050a/5abb6be2N853106d9.jpg', '84900');
INSERT INTO `t_goods` VALUES ('2', 'Huawei G9 Youth golden Mobile Unicom Telecom 4 G Mobile dual card dual standby', 'https://img12.360buyimg.com/n1/jfs/t17050/106/1124838205/250590/7e63050a/5abb6be2N853106d9.jpg', '84900');
INSERT INTO `t_goods` VALUES ('3', 'Samsung Galaxy C5(SM-C5000)4GB+32GB Maple leaf gold Mobile Unicom Telecom 4 G Mobile dual card dual standby', 'https://img12.360buyimg.com/n1/jfs/t17050/106/1124838205/250590/7e63050a/5abb6be2N853106d9.jpg', '119900');
INSERT INTO `t_goods` VALUES ('4', 'Samsung Galaxy C5(SM-C5000)4GB+32GB Rose powder China Mobile Unicom Telecom 4 G Mobile dual card dual standby', 'https://img12.360buyimg.com/n1/jfs/t17050/106/1124838205/250590/7e63050a/5abb6be2N853106d9.jpg', '119900');
INSERT INTO `t_goods` VALUES ('5', 'Samsung Galaxy C5(SM-C5000)4GB+32GB Soot Mobile Unicom Telecom 4 G Mobile dual card dual standby', 'https://img12.360buyimg.com/n1/jfs/t17050/106/1124838205/250590/7e63050a/5abb6be2N853106d9.jpg', '119900');
INSERT INTO `t_goods` VALUES ('6', 'Samsung Galaxy C5(SM-C5000)4GB+32GB Jiaojieyin Mobile Unicom Telecom 4 G Mobile dual card dual standby', 'https://img12.360buyimg.com/n1/jfs/t17050/106/1124838205/250590/7e63050a/5abb6be2N853106d9.jpg', '119900');
INSERT INTO `t_goods` VALUES ('7', 'Huawei G9 Plus 32GB Moonlight silver Mobile Unicom 4 G Mobile dual card dual standby', 'https://img12.360buyimg.com/n1/jfs/t17050/106/1124838205/250590/7e63050a/5abb6be2N853106d9.jpg', '119900');
INSERT INTO `t_goods` VALUES ('8', 'Huawei maimang 5 all Netcom 4 GB+64GB Champagne gold Mobile Unicom Telecom 4 G Mobile dual card dual standby', 'https://img12.360buyimg.com/n1/jfs/t17050/106/1124838205/250590/7e63050a/5abb6be2N853106d9.jpg', '139900');
INSERT INTO `t_goods` VALUES ('9', 'Nubia( nubia)Z11 Lily gold 4 GB+64GB China Netcom Mobile Unicom Telecom 4 G Mobile dual card dual standby', 'https://img12.360buyimg.com/n1/jfs/t17050/106/1124838205/250590/7e63050a/5abb6be2N853106d9.jpg', '159900');
INSERT INTO `t_goods` VALUES ('10', 'Huawei HUAWEI nova 4GB+64GB Champagne gold (white) mobile Unicom Telecom 4 G Mobile dual card dual standby', 'https://img12.360buyimg.com/n1/jfs/t17050/106/1124838205/250590/7e63050a/5abb6be2N853106d9.jpg', '139900');

1.3 server side

1.3.1 create SprignBoot project

Process strategy.

1.3.2 import jar package

pom.xml

    <properties>
        <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
        <java.version>1.8java.version>
        <mybatis.starter.version>1.3.2mybatis.starter.version>
        <mapper.starter.version>2.0.2mapper.starter.version>
        <mysql.version>5.1.32mysql.version>
        <pageHelper.starter.version>1.2.5pageHelper.starter.version>
        <durid.starter.version>1.1.10durid.starter.version>
        <lombok.version>1.18.16lombok.version>
    properties>
    <dependencies>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>

        dependency>

        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>

        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-jdbcartifactId>
        dependency>
        
        <dependency>
            <groupId>org.mybatis.spring.bootgroupId>
            <artifactId>mybatis-spring-boot-starterartifactId>
            <version>${mybatis.starter.version}version>
        dependency>
        
        <dependency>
            <groupId>tk.mybatisgroupId>
            <artifactId>mapper-spring-boot-starterartifactId>
            <version>${mapper.starter.version}version>
        dependency>
        
        <dependency>
            <groupId>com.github.pagehelpergroupId>
            <artifactId>pagehelper-spring-boot-starterartifactId>
            <version>${pageHelper.starter.version}version>
        dependency>
        
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <version>${mysql.version}version>
        dependency>
        
        <dependency>
            <groupId>com.alibabagroupId>
            <artifactId>druid-spring-boot-starterartifactId>
            <version>${durid.starter.version}version>
        dependency>
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <version>${lombok.version}version>
        dependency>
    dependencies>

1.3.3 configuration file (application.properties)

application.properties file

#Tomcat
server.port=8090
#DB configuration
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/vue01?useUnicode=true&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=123456
#druid
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.druid.initial-size=1
spring.datasource.druid.min-idle=1
spring.datasource.druid.max-active=20
spring.datasource.druid.test-on-borrow=true
spring.datasource.druid.stat-view-servlet.allow=true

1.3.4 create springboot boot class

@SpringBootApplication
public class UserManagementApplication {

    public static void main(String[] args) {
        SpringApplication.run(UserManagementApplication.class, args);
    }
}

1.3.5 creating entities

Create the package com.czxy.pojo and create the class User.java

@Table(name="t_goods")
public class Goods {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Integer id;
    private String name;
    private String image;
    private Double price;
}    

1.3.6 creating Dao

Create package com.czxy.dao and interface GoodsMapper.java

@org.apache.ibatis.annotations.Mapper
public interface GoodsMapper extends Mapper<Goods> {

}

1.3.7 create Service

Create package com.czxy.service and interface GoodsService.java

@Service
@Transactional
public class GoodsService {

    @Autowired
    private GoodsMapper goodsMapper;

}    

1.3.8 create Controller

Create the package com.czxy.controller and create the class GoodsController.java

@RestController
@RequestMapping("/goods")
public class GoodsController {
    @Autowired
    private GoodsService goodsService;
}

1.4 front end

Copy the page to static under resources

1.4.1 Goods.html

We put all the vue content into the page

<script src="js/vue-2.6.10.js"></script>
<script src="js/axios-0.18.0.js"></script>

1.4.2 query all

Idea: query all commodity data at the back end

        Front end display all

1.4.2.1 GoodsService

public List<Goods> findAllGoods(){
    return goodsMapper.selectAll();
}

1.4.2.2 GoodsController

@GetMapping
public ResponseEntity<List<Goods>> findAll(){
    List<Goods> list = goodsService.findAllGoods();
    return new ResponseEntity<>(list,HttpStatus.OK);
}

1.4.2.3 Goods.html page

Step 1: import vue library files

    <script src="axios-0.23.0.js"></script>
    <script src="vue-2.6.14.js"></script>

Step 2: page template, including all contents into a parent container

<div id="app">
div>

Step 3: write vue code

var vm = new Vue({
    el:"#app",
    data:{
        goods:[]
    },
    created(){
        //Send ajax request
        axios.get("/goods").then(res => {
            console.log(res)
            this.goods = res.data
        })
    }
})

Step 4: write Goods.html

<div id="app">
    <table border="1" cellspacing="0" cellpadding="0" width="800" height="400">
        <tr>
            <th>number th>
            <th>Commodity name th>
            <th>Product picture th>
            <th>commodity price th>
        tr>
        <tr v-for="(goods,index) in goods">
            <td>{{goods.id}}td>
            <td>{{goods.name}}td>
            <td><img  src="{{goods.image}}"/>td>
            <td>{{goods.price}}td>
        tr>
    table>

div>

Test results:

1.4.2.3 optimization 1: the problem of not displaying pictures

Modification:

<td><img  :src="goods.image"/>td>

The effects are as follows:

1.4.2.3 optimization 2: the picture is too big

effect:

2 introduction of front and rear end separation development mode

2.1 front and rear end separation

Front end separation is a very popular development mode at present, which makes the division of labor of the project more clear:

  • Back end: responsible for processing and storing data
  • Front end: responsible for displaying data

Front end and back-end developers exchange data through the interface.

Benefits:

  1. A set of back-end interfaces provide data for all front ends (PC end, APP end, desktop end, etc.)
  2. The front-end and back-end codes are independent of each other

Disadvantages:

  1. When the interface changes, it is very troublesome –
  2. Joint commissioning of front and rear end personnel is required – the time for joint commissioning and development (development + test + joint commissioning) accounts for 15% - 60% of the project

2.2 JavaScript framework

With the development of the front-end, many functions previously completed by the server are now transferred to the front-end, which leads to thousands of lines of code written by the front-end JavaScript Code, use them to manage all kinds of HTML and CSS Documents, but lack of formal organization form:

In order to better organize the front-end code, developers are increasingly using JavaScript frameworks. The most popular front-end frameworks are:

  1. Google's Angularjs
  2. Facebook's React
  3. Vue in Youyu Creek

3. Transformation of commodity management

3.1 specific implementation of front and rear end separation development

3.1.1 installation of visual studio code development tool

Data location:

Double click to install successfully

3.1.2 configuration of visual studio code development tool

3.1.2.1 setting Chinese environment

  • Set Chinese environment

After installation, the vscode is all in English, and the vscode environment needs to be adjusted to the Chinese version.

  • The adjustment steps are as follows:
    • Step 1: shortcut key ctrl+shift+p Select Configure Display Language
    • Step 2: choose to install "other languages"
    • Step 3: after setting, save the file, restart vscode, and Chinese will be displayed

      Well, now that vscode has become a Chinese mode, you can enter the development process.

3.1.2.2 installing the vehicle plug-in

  • Functional expression Total: by comprehensive comparison, it is the best Vue plug-in used in VSCode at present Points:
    • Syntax error checking, including CSS/SCSS/LESS/Javascript/TypeScript
    • Syntax highlighting, including HTML / Jade / Pug CSS / sass / SCSS / less / style JS / TS
    • emmet support
    • Automatic code completion (still in its infancy), including HTML/CSS/SCSS/LESS/JavaScript/TypeScript
    • ...
  • The installation steps are as follows:

3.2 put the product development page into vs

Copy the address and open it directly in the browser:

3.3. Cross domain issues

3.3.1. What is cross domain (back)

Cross domain refers to cross domain access. The following situations are cross domain:

Cross domain reason description

Example

1. Different domain names

www.jd.com and www.taobao.com

2. The domain name is the same, but the port is different

www.jd.com:8080 and www.jd.com:8081

localhost:8080 and localhost:8090

3. Different secondary domain names / subdomains

item.jd.com and miaosha.jd.com

4 different protocols

http://jd.com And https://jd.com

5 domain name and ip address

http://jd.com And 192.168.23.12

If???? The domain name and port are the same, but the request path is different????, Not cross domain, such as:

www.jd.com/item

www.jd.com/goods

And we just came from file:///E:/vueworkspace1019/Chapter01/Goods.html Go visit http://localhost:8090/ , this belongs to different domain names and cross domains.

3.3.2. Why are there cross domain problems?

1. The same origin policy of the browser causes cross domain problems

2 cross domain problems do not necessarily exist.

a: a. cross domain does not cause problems:

b. Cross domain causes problems

Because the cross domain problem is a security restriction of the browser for ajax requests: the ajax request initiated by a page can only be the path with the same domain name as the current page, which can effectively prevent cross site attacks.

Therefore: cross domain issues are a limitation of ajax. Effectively prevent cross site attacks through cross domain restrictions

But this has brought inconvenience to our development, and in the actual production environment, there must be many servers interacting with each other, and the addresses and ports may be different. What should we do?

3.3.3. Solutions to cross domain problems

At present, there are three common cross domain solutions:

  • Jsonp The earliest solution is based on the principle that script tags (unrestricted) can be implemented across domains. Limitations:
    • Service support required (Getting)
    • Only GET requests can be initiated
  • nginx reverse proxy The idea is: use nginx reverse proxy to turn cross domain into non cross domain, and support various request modes
  • CORS Standardized cross domain request solution, safe and reliable. It is the standard of w3c organization Advantages:
    • Control whether cross domain is allowed on the server, and you can customize the rules
    • Various request methods are supported: get, post, put and delete
    • IP address of the computer with restricted access

    Disadvantages:

    • Additional requests will be generated (primary / secondary requests may be made)

We adopt cross domain scheme of cors.

3.4. Cross domain CORS solution

3.4.1. What is cors

CORS is a W3C standard, whose full name is "cross origin resource sharing".

It allows browsers to send messages to cross source servers XMLHttpRequest Request, which overcomes the problem that AJAX can only Homology Restrictions on use.

CORS requires both browser and server support. At present, all browsers support this function, and IE browser cannot be lower than IE10.

  • Browser side: At present, all browsers support this function (not below IE10). The whole CORS communication process is completed automatically by the browser without user participation.
  • Server: Generally, the function is completed through the filter.

3.4.2. The principle of CORS is a little complex (understand)

The browser will divide ajax requests into two categories, and their processing schemes are slightly different: simple requests and special requests.

Simple request

As long as the following two conditions are met at the same time, it is a simple request

(1) The request method is one of the following three methods:

  • HEAD
  • GET
  • POST

(2) The HTTP header information does not exceed the following five fields:

  • Accept
  • Accept-Language
  • Content-Language
  • Last-Event-ID
  • Content type: limited to three values: application/x-www-form-urlencoded, multipart / form data, and text/plain

When the browser finds that the discovered ajax request is a simple request, it will carry a field in the request header: Origin

Origin will indicate which domain the current request belongs to (protocol + domain name + port). The service will decide whether to allow it to cross domains based on this value.

If the server allows cross domain, the following information needs to be carried in the returned response header:

Access-Control-Allow-Origin: http://localhost:8094
Access-Control-Allow-Credentials: true
Content-Type: text/html; charset=utf-8
  • Access control allow origin: an acceptable domain, which is a specific domain name or *, representing any domain name
  • Access control allow credentials: whether cookies are allowed to be carried. By default, cors will not carry cookies unless this value is true

be careful:

If a cross domain request wants to operate cookie s, three conditions must be met:

  • The response header of the service needs to carry access control allow credentials and be true.
  • The browser needs to specify withCredentials as true to initiate ajax
  • The access control allow origin in the response header must not be *, it must be the specified domain name

Special request

If a simple request does not meet the conditions, it will be judged as a special request by the browser. For example, the request method is PUT.

Pre inspection request

Special requests will add an HTTP query request before formal communication, which is called "preflight".

The browser first asks the server whether the domain name of the current web page is in the server's license list, and what HTTP verbs and header information fields can be used. Only when you get a positive reply will the browser send a formal XMLHttpRequest request, otherwise an error will be reported.

A template for a "pre check" request:

OPTIONS /cors HTTP/1.1
Origin: http://localhost:8094
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header
Host: http://localhost:8094
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...

Compared with simple requests, there are two more headers besides Origin:

  • Access control request method: the next request method, such as PUT
  • Access control request headers: header information for additional use

Response to pre inspection request

The service receives a pre check request. If the license is cross domain, it will send a response:

HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:15:39 GMT
Server: Apache/2.0.61 (Unix)
Access-Control-Allow-Origin: http://localhost:8094
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: X-Custom-Header
Access-Control-Max-Age: 1728000
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Content-Length: 0
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: text/plain

In addition to access control allow origin and access control allow credentials, there are three additional headers:

  • Access control allow methods: allowed access methods
  • Access control allow headers: allowed headers
  • Access control Max age: the valid duration of this license, in seconds,????????????????? ajax requests before expiration do not need to be pre checked again????

If the browser receives the above response, it is considered that it can cross domain, and the subsequent processing is the same as that of a simple request.

3.4.3. The implementation is very simple

Although the principle is complex, as mentioned earlier:

  • The browser is automatically completed on the browser side, so we don't need to worry
  • The server can be implemented uniformly through interceptors, and there is no need to write cross domain decisions every time.

In fact, spring MVC has helped us write the cross domain filter of CORS: CorsFilter, which has implemented the decision logic just mentioned. We can just use it directly.

Write a configuration class in the config directory and register CorsFilter:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration
public class GlobalCorsConfig {
    @Bean
    public CorsFilter corsFilter() {
        //1. Add CORS configuration information
        CorsConfiguration config = new CorsConfiguration();
        //1) Do not write *, otherwise the cookie will not be used
        config.addAllowedOrigin("*");
        //2) Send Cookie information
        config.setAllowCredentials(true);
        //3) Allowed request mode
        config.addAllowedMethod("OPTIONS");
        config.addAllowedMethod("HEAD");
        config.addAllowedMethod("GET");
        config.addAllowedMethod("PUT");
        config.addAllowedMethod("POST");
        config.addAllowedMethod("DELETE");
        config.addAllowedMethod("PATCH");
        // 4) Allowed header information
        config.addAllowedHeader("*");

        //2. Add a mapping path and we will intercept all requests
        UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
        configSource.registerCorsConfiguration("/????", config);

        //3. Return to the new CorsFilter
        return new CorsFilter(configSource);
    }
}

Structure:

4.5.4. Restart test: still unable to access

Summary:

Benefits of 0 front-end and back-end separation development

  • The back-end pursues three high (high concurrency, high availability, high performance), security, storage, business and so on.
  • The front-end pursues: page performance, smooth speed, compatibility, user experience and so on.

Let the front and rear end focus more on their own business areas

1 what is cross domain

2 why is there a leap forward problem

3 cross domain solution: advantages and disadvantages of the solution (advantages and disadvantages of JSONP and cors)

4 nginx: reverse proxy server, which accesses the project through the domain name; Build static resource server

4 what is CORS

5. CORS solution: how to implement it?

6. After the front and back ends are separated, the html page is placed under vs, and the back-end java only provides interfaces. How can the html page under vs access the back-end interface?

A: you should put html static resources under the server, and nginx is the best static resource server

7 nginx build HTML static resource server

8 CORS principle summary (understanding):

  • Simple request
    • Only head, get and post requests are allowed
    • Header information shall not exceed 5 kinds of data
    • Only one request needs to be sent
  • Complex request
    • Send one or two requests
    • put, delete and other requests
    • The first request is a pre check request to determine whether the server will process the request. The second request is to send a real request to the server after passing the pre check

Posted on Mon, 06 Dec 2021 19:32:16 -0500 by scritpkid