Spring background management system project exercise 03 - product list, Nginx, project local release

1 product list

1.1 preparation



2. Product list display

2.1 front end request

2.2 ItemController

/*Business requirements: display of commodity list
    Request path: / item / getitemlist? query=&pageNum=1&pageSize=10
    Request type: get
    Request parameters: receive using pageResult object
    Return value: SysResult(pageResult)
    * */
    //@PathVariable restful get parameters dynamically
    @GetMapping("/getItemList")
    public SysResult getItemList(PageResult pageResult){//3 parameters
        pageResult=itemService.getItemList(pageResult);//3+2

        return SysResult.success(pageResult);
    }

2.3 ItemServiceImpl

	/*
    * sql:select * from item limit Start position, display number
    *
    * */
    @Override
    public PageResult getItemList(PageResult pageResult) {
        //1. Build fuzzy query
        boolean flag= StringUtils.hasLength(pageResult.getQuery());//Dynamic sql, splicing condition only when it is true
        QueryWrapper<Item> queryWrapper = new QueryWrapper<>();
        queryWrapper.like(flag,"title", pageResult.getQuery());
        //2. Define paging objects
                                        //Number of pages
        IPage page=new Page(pageResult.getPageNum(), pageResult.getPageSize());

        //The page parameter consists of the original number of pages / entries, and the total number of records and the paging results are added through business calls
        page=itemMapper.selectPage(page,queryWrapper);
        long total=page.getTotal();//Get total
        List<Item> rows=page.getRecords();//Get paging results
        return pageResult.setTotal(total).setRows(rows);
    }

2.4 editing paging configuration class

@Configuration //Identity configuration class
public class MybatisPlusConfig {
    //Give the custom object to the container management and tell MP that the database currently used is mysql/maridb
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
    
}


3. New commodity business interface

3.1 description of commodity information

Note: the basic information of item and the detailed information of ItemDesc can be wrapped by object
For example: {item: data information of item, itemdesc: data information of itemdesc}

3.1 modifying table field types

3.2 business interface analysis

Request path: http://localhost:8091/item/saveItem
 Request type: post
 Front end transfer parameter analysis
	{
		item: {
			images: "/2021/05/20/da0c1d4781c1499399f090da8b60f359.jpg,/2021/05/20/2ac1c34776a7465887eb019655354c3c.jpg"
			itemCatId: 560
			num: "100"
			price: 718800
			sellPoint: "[Huawei official direct supply,Zhigao 12 interest free 0 down payment,[original] send Huawei original wireless charger+Sports Bluetooth headset+Bluetooth Speaker +Three in one multifunctional data line+Toughened film, etc!"
			title: "Huawei P40 Pro 5G Mobile phone [12 interest free optional gifts] all Netcom smart phone"
		},
		itemDesc: {
				itemDesc: "<ul><li>Brand:&nbsp;<a href=https://list.jd.com/list.html".......      "
		},
		itemParam: {
			dynamicArray: [
							{paramId: 1, paramVals: "Bright black,Glaze white"}, 
							{paramId: 2, paramVals: "8GB+128GB,8GB+256GB"}
						   ],
			staticArray: [
				 	{"paramId": 3,"paramVals": "Huawei Mate 40 Pro"},
				    {"paramId": 4,"paramVals": "0.575kg"}.....
			 		]
		}
	}

Request parameters: received using ItemVO object

Parameter nameParameter typeParameter descriptionremarks
itemItemCommodity basic information object encapsulationCannot be null
itemDescItemDescProduct detailsCannot be null

3.3 front end request


3.4 encapsulating ItemVO objects

Encapsulate Item and ItemDesc into an ItemVO object

@Data
@Accessors(chain = true)
public class ItemVO implements Serializable {
    private Item item;
    private ItemDesc itemDesc;
}

3.5 ItemController

/*Commodity addition
    Request path: / item/saveItem
    Request type: post
    Parameter information: itemVO object
    * */
    @PostMapping("/saveItem")
    public SysResult saveItem(@RequestBody ItemVO itemVO){//Item+ItemDesc

        itemService.saveItem(itemVO);
        return SysResult.success();
    }

3.6 ItemServiceImpl

 /**
     * Requirement: Complete 2 parts of warehousing operations
     * Step 1: complete the Item warehousing operation
     * Step 2: complete the ItemDesc receipt operation item id=ItemDesc. id
     * mybatis Knowledge explanation
     *  <insert id="xxxx" useGeneratedKeys="true"
     *             keyColumn="id"
     *             keyProperty="id">
     *         Add sql
     *  </insert>
     *  MP Knowledge explanation:
     *      MP Operate data in an object-based manner. If the data warehousing operation is realized,
     *      The data will be bound to the object and echoed dynamically
     *  Difficult knowledge: how to realize data echo!!!!!!
     * @param itemVO
     */
    @Override
    @Transactional
    public void saveItem(ItemVO itemVO) {
        //1. Step 1 implements Item object warehousing
        Item item = itemVO.getItem().setStatus(true);
        //At the beginning, the id is null. During the warehousing operation, the id will be automatically assigned in the database
        //After assignment, the ID in the object is still null
        itemMapper.insert(item);
        //2. Step 2 implements ItemDesc object warehousing
        ItemDesc itemDesc = itemVO.getItemDesc();
        itemDesc.setId(item.getId());
        itemDescMapper.insert(itemDesc);
    }

4 product deletion and status update

4.1 deletion of goods

4.1.1 ItemController

/*
    Request path: / item/deleteItemById
    Request type: delete
    Request parameter: id
    */
    @DeleteMapping("/deleteItemById")
    public SysResult deleteItemById(Integer id){
        itemService.deleteItemById(id);
        return SysResult.success();
    }

4.1.2 ItemService

Item and item_ Descs should be deleted together

		@Override
    @Transactional
    public void deleteItemById(Integer id) {
        itemMapper.deleteById(id);
        itemDescMapper.deleteById(id);
    }

4.2 commodity status update

4.2.1 ItemController

		/*
    /item/updateItemStatus
     */
    @PutMapping("/updateItemStatus")
    public SysResult updateItemStatus(@RequestBody Item item){
        itemService.updateItemStatus(item);
        return SysResult.success();
    }

4.2.2 ItemService

		@Override
    @Transactional
    public void updateItemStatus(Item item) {
        itemMapper.updateById(item);
    }

5 file upload operation

5.1 file upload business description

Note: when the user selects multiple pictures, they are transmitted one by one

5.2 interface information

Request path: http://localhost:8091/file/upload
Request type: post
Request parameters:

Parameter nameParameter descriptionremarks
fileParameter name of file uploadfile carries binary information

ImageVO object description

Parameter nameParameter typeParameter descriptionremarks
virtualPathStringvirtualPathFor example, 2021/11/11/a.jpg does not need to write the disk address
urlPathStringurlPathhttp://image.jt.com/2021/11/11/a.jpg Domain name address needs to be specified
fileNameStringFile name after file uploadUUID.type

5.3 ImageVO object encapsulation

@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class ImageVO implements Serializable {
    private String virtualPath; //Virtual path dynamic path
    private String urlPath;     //Picture network address
    private String fileName;    //Picture name
}

5.4 introduction to file upload

		@RestController
		@CrossOrigin
		@RequestMapping("/file")
		public class FileController {
    /**
     * URL: /file/upload
     * Type: post
     * Parameter: file = byte information
     * Return value: SysResult(ImageVO)
     * Knowledge points:
     *   SpringMVC MultipartFile is developed for and IO operations
     *   The bottom implementation is a conventional IO stream, which simplifies the user's operation process There is no need to close the flow manually
     *   SpringMVC The maximum 1M is supported by default
     * Steps:
     *      1.Get file name
     *      2.Prepare file path
     *      3.Prepare full path for file upload
     *      4.Realize file upload operation
     */
    @PostMapping("/upload")
    public SysResult upload(MultipartFile file) throws IOException {
        //1. Get the file name a.jpg
        String fileName = file.getOriginalFilename();
        //2. Prepare file directory
        String dir = "D:/project3/images";
        File dirFile = new File(dir);
        if(!dirFile.exists()){//Determine whether the directory exists
            dirFile.mkdirs(); //Create multi-level directory
        }
        String path = dir + "/" + fileName;
        //Realize file upload
        file.transferTo(new File(path));
        return SysResult.success();
    }
}

5.5 file upload complete code

5.5. 1 edit FileController

@PostMapping("/upload")
    public SysResult fileUpload(MultipartFile file){

        ImageVO imageVO=fileService.upload(file);
        if (imageVO==null){
            return SysResult.fail();
        }
        return SysResult.success(imageVO);
    }

5.5. 2 Edit FileService

Idea: 1. Check whether the file is a picture
2. Prevent files from being malicious programs
3. Sub directory storage is divided according to maintenance time
4. Prevent file name duplication UUID

5.5. 2.1 verification (steps 1 and 2)

@Override
    public ImageVO upload(MultipartFile file) {
        //1.
        //Get all picture names to lowercase
        String filename = file.getOriginalFilename().toLowerCase();
        if (!filename.matches("^.+\\.(jpg|png|gif)$")) {//In java, \ \ stands for \; Single is not recognized\
            return null;
        }
        //2. Judge whether it is a picture by checking the width and height
        try {
            BufferedImage bufferedImage = ImageIO.read(file.getInputStream());
            int width = bufferedImage.getWidth();
            int height = bufferedImage.getHeight();
            if (width == 0 || height == 0) {
                return null;
            }
        } catch (IOException e) {
            //In general, in order not to affect the code structure, check exceptions are converted into runtime exceptions
            e.printStackTrace();
            throw new RuntimeException(e);//
        }

        return null;
    }

5.5.2.2

@Override
    public ImageVO upload(MultipartFile file) {
        //1.
        //Get all picture names to lowercase
        String fileName = file.getOriginalFilename().toLowerCase();
        if (!fileName.matches("^.+\\.(jpg|png|gif)$")) {//In java, \ \ stands for \; Single is not recognized\
            return null;
        }
        //2. Judge whether it is a picture by checking the width and height
        try {

            BufferedImage bufferedImage = ImageIO.read(file.getInputStream());
            int width = bufferedImage.getWidth();
            int height = bufferedImage.getHeight();
            if (width == 0 || height == 0) {
                return null;
            }
            //3 sub directory storage
            String datePath = new SimpleDateFormat("/yyyy/MM/dd/").format(new Date());
            String fileDir = rootDir + datePath;
            File dirFile = new File(fileDir);//
            if (!dirFile.exists()) {
                dirFile.mkdirs();
            }

            //4. Dynamically generate UUID
            String UUID = java.util.UUID.randomUUID().toString();
            int index = fileName.lastIndexOf(".");
            String fileType = fileName.substring(index);
            fileName = UUID + fileType;

            //5. Realize file upload
            String path = fileDir + "/" + fileName;
            file.transferTo(new File(path));

            //6. Prepare the data return of imageVO
            String virtualPath = datePath + fileName;
            //String urlPath="https://img14.360buyimg.com/n0/jfs/t1/162878/20/21270/387542/61b8da25Ed63246d6/baffb7e01f3edefb.jpg";
            String urlPath = rootURL + virtualPath;
            //String urlPath = rootDir + virtualPath;
            System.out.println(urlPath);

            ImageVO imageVO = new ImageVO(virtualPath, urlPath, fileName);
            return imageVO;

        } catch (IOException e) {
            //In general, in order not to affect the code structure, check exceptions are converted into runtime exceptions
            e.printStackTrace();
            throw new RuntimeException(e);//
        }

    }

6. File deletion service interface

6.2 FileController

/*
    Request path: / file/deleteFile
    Request type: delete
    Request parameter: virtualPath
    Return value: SysResult
     */
    @DeleteMapping("/deleteFile")
    public SysResult deleteFile(String virtualPath){
        fileService.deleteFile(virtualPath);
        return SysResult.success();
    }

6.3 FileService

/*
    The full path of the file is required to delete the file
     */

    @Override
    public void deleteFile(String virtualPath) {
        String localPath=rootDir+virtualPath;
        File file = new File(localPath);
        if (file.exists()) {//Delete if file exists
            file.delete();
        }
    }

7 reverse proxy

7.1 business requirements

Requirement Description: after uploading the picture, the user will access the picture according to the network address, but the searched picture must exist in the disk
URL address: http://image.jt.com/2021/12/16/f9981c76-e6a7-49fa-88d9-3be0851dbf50.jpg
Disk address: D: / project3 / images / 2021 / 12 / 16 / f9981c76-e6a7-49fa-88d9-3be0851dbf50 jpg

Technical difficulties:
1. When the user accesses the URL network address, it should search according to the disk address!
How do I convert a network address to a disk address?

7.2 introduction to reverse proxy

The reverse proxy server is located between the user and the target server, but for the user, the reverse proxy server is equivalent to the target server, that is, the user can obtain the resources of the target server by directly accessing the reverse proxy server. At the same time, users do not need to know the address of the target server, nor do they need to make any settings on the client. Reverse proxy server can usually be used as Web acceleration, that is, using reverse proxy as the front-end machine of Web server to reduce the load of network and server and improve access efficiency.

7.2. 1. Knowledge foreshadowing

If the website tells the user the real address directly This makes the whole server unsafe Therefore, we need to use agent technology to avoid this problem

7.2. 2 reverse proxy features

The reverse proxy server is between the user and the target server
 The user obtains resources from the reverse proxy server, The user thinks that the reverse proxy server is the target server.
Users don't know who the real server is, Protects real server information. Also known as "Server side agent"

7.2 introduction to forward agent

7.2. 1 Introduction to forward agent

Forward proxy means a server located between the client and the original server. In order to obtain content from the original server, the client sends a request to the proxy and specifies the target (original server), and then the proxy forwards the request to the original server and returns the obtained content to the client. Only clients can use forward proxy.

7.2. 2. Characteristics of forward agent

The forward proxy server is between the client and the original server
The user accesses the forward proxy server and specifies the target server address
The server does not know who accessed it. It is assumed that it is accessing the proxy server Protects user information Also known as client agent


.

7.3 nginx

7.3. 1. Introduction to nginx

Nginx (engine x) is a high-performance HTTP and reverse proxy web server. It also provides IMAP/POP3/SMTP services. Nginx is rambler, the second most visited Russian by Igor sesoyev Ru site (Russian: Рамблер) Developed, the first public version 0.1 0 was published on October 4, 2004.
It publishes its source code in the form of BSD like license, which is famous for its stability, rich feature set, simple configuration file and low consumption of system resources. June 1, 2011, nginx 1.0 4 release.
Nginx is a lightweight Web server / reverse proxy server and e-mail (IMAP/POP3) proxy server, issued under BSD-like protocol. Its characteristics are less memory and concurrent capability. In fact, nginx's concurrent capability is better in the same type of Web server. Chinese mainland users use nginx website: Baidu, Jingdong, Sina, NetEase, Tencent, Taobao, etc.

7.3.2 Nginx features

nginx Is an open source free lightweight reverse proxy server/web The server.
nginx Strong concurrency theoretical value: 5 Ten thousand times/Second actual value: 3 Ten thousand times/second
tomcat: 150-220 —>1000 individual/200 seconds of memory M
nginx Occupy less memory than 2 M

7.3.3 Nginx Download

URL address: http://nginx.org/en/download.html

7.3. 4 installation and use of nginx

explain:
1.nginx startup will occupy port 80!!
2. The nginx startup path should not have Chinese / spaces / special characters. The underlying development language: C language

Access test:

7.3. 5. Description on the occupation of nginx 80 terminal

Check port number occupancy

7.3. 6 description of nginx startup items

Note: the startup of nginx will start 2 process items each time
Main process: mainly provides reverse proxy service Memory intensive
Daemon: prevent the main process from shutting down unexpectedly Small memory footprint

Task manager process

7.3.7 nginx command (proficient)

Note: the command of nginx needs to run nginx in the root directory The path where exe is located is the root directory
Command:

  1. Start nginx start nginx
  2. Restart nginx - s reload
  3. Close nginx - s stop

7.4 Nginx reverse proxy mechanism

	http {
		 #Each reverse proxy service is a server
		 server {
		 	#The default listening port number of nginx is 80
			listen       80;
			#nginx domain name to block
			server_name  localhost;
			
			#Block all requests
			location / {
				# root represents a directory for the agent 
            	root   html;
            	# Configure home page for default access
            	index  index.html index.htm;
        	}
		 }	
	}

7.5 image proxy implemented by nginx

URL address: http://image.jt.com/2021/12/16/f9981c76-e6a7-49fa-88d9-3be0851dbf50.jpg
Disk address: D: / project3 / images / 2021 / 12 / 16 / f9981c76-e6a7-49fa-88d9-3be0851dbf50 jpg
Agency mechanism:
Domain name: http://image.jt.com:80
The agent is:
D:/project3/images

Configure picture proxy:

#Configure picture proxy
	server {
		listen 80;
		server_name  image.jt.com;

		location / {
			root D:/project3/images;
		}
	}

After editing, restart nginx

7.7 modifying hosts file

File location: C:\Windows\System32\drivers\etc

7.7. 1 check whether it is read-only

If the file is read-only, the read-only option should be removed

7.7. 2 check authority

7.7. 3. Modify the hosts file

127.0.0.1       localhost
127.0.0.1		image.jt.com			#picture
127.0.0.1		manage.jt.com			#back-end
127.0.0.1		web.jt.com				#front end

8 project release preparation

8.1 project release

1. Check whether the table names in all SQL have case problems Check annotation check SQL
2. Check POM according to code cloud XML file content
3. Package the project with the install command
4. Front end project packaging

Check whether dist directory is generated

8.2 preparation for front-end release

1. Modify main JS path


2. Edit addItem Vue file

3. Compile the front-end project
If the above operations are modified, the program needs to be compiled. As shown in the figure

8.3 front end project release

8.3. 1. Business description

Copy the compiled dist directory to the root directory of nginx.

8.3. 2 front end project release

Requirements: users pass http://web.jt.com Visit dist / index html

#Configure front-end agent
	server {
		listen 80;
		server_name  web.jt.com;

		location / {
			root dist;
			index index.html;
		}
	}

Restart nginx

8.3. 3 front end code test

8.4 back end project release

8.4. 1 get port number dynamically

package com.jt.controller;
@RestController
@CrossOrigin
public class PortController {
    //Get port number dynamically
    @Value("${server.port}")
    private Integer port;

    @GetMapping("/getPort")
    public String getPort(){

        return "Current port number:"+port;
    }
}


8.4. 2 project release

Command: Java - jar 8091 jar

8.4. 3. Nginx completes back-end Publishing

#Configure backend agent
	server {
		listen 80;
		server_name  manage.jt.com;

		location / {
			#proxy_pass maps the requested address
			proxy_pass http://localhost:8091;
		}
	}

8.4. 4 back end project test

By: http://manage.jt.com/itemCat/findItemCatList/3 Test whether the back-end domain name is available



Keywords: Java Nginx Spring

Added by vasoftwaresolutions on Thu, 16 Dec 2021 15:47:48 +0200