Java learning day57_MVC

Keywords: Java mvc

MVC

JSON

JSON is a data format. To put it bluntly, it is the object (data structure) in js

student name, age, province

{name: "jingtian", age:26,province: "henan"} - the object in js

How to write json data? How to understand?

Just remember the following conclusions

If you see that {} represents an object

If you see [], it represents an array or collection

xml used to be a format for data interaction. What data format is used to exchange data between mobile client and server?

xml. Compared with key=value data, the biggest advantage of XML is that it can represent the relationship between data. Can show a hierarchical relationship.

xml is gradually abandoned by people. The main reason is that the transmission efficiency is not particularly high (xml has very strict labels)

Later, it was replaced by json.

At present, xml is mainly used in the configuration files of some frameworks and software.

var country = {name:"China",province:[{name:"Heilongjiang", cities:["Harbin","Daqing"]},
                {name:"Guangdong", cities:["Guangzhou","Shenzhen"]},
                {name:"Taiwan", cities:["Taipei","Kaohsiung"]},
                {name:"newly build", cities:["Urumqi","Kashgar"]}]}

var country ={
"name": "China",
"province": [{"name": "Heilongjiang", "cities": ["Harbin", "Daqing]},
{"name": "Guangdong", "cities": ["Guangzhou", "Shenzhen", "Zhuhai"]},
{"name": "Taiwan", "cities": ["Taipei", "Kaohsiung"]},
{"name": "Xinjiang", "cities": ["Urumqi"]}
]
}

What is the difference between the two?

The first method refers to the js object (json); the second method can be considered as the js object string (json string)

It can be understood that the former is equivalent to a java object, and the latter is equivalent to calling the toString method

In the process of data transmission at the front and back ends, we usually transmit in the form of json string.

For example, on the login page, the previously submitted parameters are submitted in the form of key=value

In fact, you can also submit in the form of json string

{"username":"admin","password":"admin"}


Using json

The java language can also use json related data.

1. Convert java objects into json strings

The front and back ends interact. The back end queries the database and obtains relevant data, such as commodity information data, which needs to be returned to the front end. java objects need to be converted into json strings and handed over to the front end for further processing

public class MainTest {

    public static void main(String[] args) {
        //Convert java objects to json strings
        //  {"name":"admin", "province":"hubei"}
        Student student = new Student();
        student.setName("Zhang San");
        student.setProvince("Hubei province");
        // bejson.com can verify whether the format of json is correct
        String jsonStr = "{\"name\":\"" + student.getName() + "\",\"province\":\"" + student.getProvince() + "\"}";
        System.out.println(jsonStr);
    }
}

It's troublesome. And many of them are repetitive mechanical operations. If we need to deal with list s, map s, etc., it's more cumbersome

You can use some class libraries and third-party jar packages.

google-gson

alibaba-fastjson

SpringMVC----jackson

2. Convert json string to java object

The front-end and back-end interact. The front-end page submits request parameters, such as login. The back-end needs to receive the request parameters and save them to the database.

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;

public class JSONTest {

    @Test
    public void testObjectToJson(){
        Student student = new Student();
        student.setName("Zhang San");
        student.setAge(25);

        Gson gson = new Gson();
        String s = gson.toJson(student);
        System.out.println(s);
    }

    @Test
    public void testObjectToJson2(){
        Student student = new Student();
        student.setName("Zhang San");
        student.setAge(25);

        Student student2 = new Student();
        student2.setName("Li Si");
        student2.setAge(26);

        List<Student> students = new ArrayList<>();
        students.add(student);
        students.add(student2);

        Gson gson = new Gson();
        String s = gson.toJson(students);
        System.out.println(s);
    }

    @Test
    public void testJsonToObject(){
        String jsonStr = "{\"name\":\"Zhang San\",\"age\":25}";
        Gson gson = new Gson();
        //reflex
        Student student = gson.fromJson(jsonStr, Student.class);
        System.out.println(student);
    }

    @Test
    public void testJsonToObject2(){
        String str = "[{\"name\":\"Zhang San\",\"age\":25},{\"name\":\"Li Si\",\"age\":26}]";
        Gson gson = new Gson();
        // List<Student>
        //You can parse the json string first
        JsonElement jsonElement = new JsonParser().parse(str);
        //Judge which method to choose next according to the outermost bracket
        //If [] getAsJsonArray; if {} getAsJsonObject
        JsonArray jsonArray = jsonElement.getAsJsonArray();
        for (JsonElement element : jsonArray) {
            //element is actually the encapsulation of {"name": "Zhang San" and "age":25}
            Student student = gson.fromJson(element, Student.class);
            System.out.println(student);
        }
    }
}

case

Write a case and introduce MVC through the case

Register the login system.

There is a form on the registration page. The form submits data to the server and needs to save the data

There is also a form on the login page. The form submits the request parameters. By comparing with the data stored in the server, it can judge whether the user name and password entered by the user are correct

Requirements:

First, store the data in a json file (don't think about whether there is a performance problem stored in a json file. This is not the point. We just want to use two storage methods to experience how to design to minimize code changes when changing requirements. In fact, it won't be stored in a json file) Subsequently, the requirements are changed to use database storage


New Maven EE project

The Maven project is created as before. The operations that need to be done are mainly after the new project is created.


1. You need to create a webapp directory under src\main

2. Next, you need to set the webapp directory to facet web


Pay attention to the path

3. Set artifacts

Just setting this line of code is enough.

<dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>

As for the coordinates of servlet s, remember to set provided, which means that a jar package is required during compilation, but not during runtime. Why? Because the runtime is provided by the container and tomcat provides the jar package.

Integrate Maven EE project, create a new configuration file and place it in the resources directory. How to get the path of the file?

Execute the package instruction. By observing the compiled path of the file, it is found that

Under the classes directory.

This directory is actually the classpath of the current application. You can use the classloader to obtain the absolute path of the file.

First, the class file in the application is located on the hard disk, and the runtime must be located in memory. This process is completed by the loader

Since the class loader can load your class file into memory, do you know the location of your class file on the hard disk?

Sure. Now that we know the path, we can use an API provided by the classloader to get the absolute path of the file in the classpath directory.

package com.cskaoyan.register;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;

@WebServlet("/user/*")
public class UserServlet extends javax.servlet.http.HttpServlet {
    protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
        String requestURI = request.getRequestURI();
        String action = requestURI.replace(request.getContextPath() + "/user/", "");
        if("register".equals(action)){
            register(request, response);
        }
    }

    /**
     * Logic of registration
     * Take out the user name and password and verify them first
     * Persist the user name and password (first judge whether the user name is occupied)
     * @param request
     * @param response
     */
    private void register(HttpServletRequest request, HttpServletResponse response) throws IOException {
        User user = new User();
        Map<String, String[]> params = request.getParameterMap();
        try {
            BeanUtils.populate(user, params);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        //Check the parameters
        //Judge whether the user name and password are empty, etc
        if(!user.valid()){
            //In this case, the prompt is vague, and the return value of the valid method specifies a rule
            //200 OK 404 is empty 500 passwords are inconsistent twice
            response.getWriter().println("Illegal parameter");
            return;
        }
        //The specific business logic of registration first uses json files to store data, and then changes to databases
        //If the configuration file is placed in WEB-INF, how to handle it? How to get the path of the file servletContext.getRealPath();
        //If it is placed in the resources directory, how can I get it?
        //You can use the class loader to get
        ClassLoader classLoader = UserServlet.class.getClassLoader();
        //This method can be used to obtain the resource information of a file in the classpath directory
        //In EE Projects, classpath refers to the WEB-INF/classes directory
        URL resource = classLoader.getResource("users.json");
        String path = resource.getPath();
        //This method of obtaining the stream is actually equivalent to the domain, and the above method is encapsulated
        //classLoader.getResourceAsStream()
        File file = new File(path);
        //Read the contents of the users.json file to form a string
        BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
        //Content is the content of the file
        String content = bufferedReader.readLine();
        Gson gson = new Gson();
        List<User> userList = new ArrayList<>();
        if(!StringUtils.isEmpty(content)){
            //If it is not empty, it means someone has registered before; if it is empty, it means no one has registered before
            JsonElement jsonElement = new JsonParser().parse(content);
            JsonArray jsonArray = jsonElement.getAsJsonArray();
            //You need to determine whether the current user name has been registered
            for (JsonElement element : jsonArray) {
                User u = gson.fromJson(element, User.class);
                if(user.getUsername().equals(u.getUsername())){
                    response.getWriter().println("The current user name has been registered");
                    return;
                }
                userList.add(u);
            }
        }
        //It indicates that the registration is successful, and then it is written back to the file
        userList.add(user);
        //How to write a string to a file
        FileWriter fileWriter = new FileWriter(file);
        fileWriter.write(gson.toJson(userList));
        fileWriter.flush();
        fileWriter.close();
        response.getWriter().println("login was successful");

    }

    protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {

    }
}

Code change

If I need to use json file to store data instead of database in the future, what should I change?

//The specific business logic of registration first uses json files to store data, and then changes to databases
//If the configuration file is placed in WEB-INF, how to handle it? How to get the path of the file servletContext.getRealPath();
//If it is placed in the resources directory, how can I get it?
//You can use the class loader to get
ClassLoader classLoader = UserServlet.class.getClassLoader();
//This method can be used to obtain the resource information of a file in the classpath directory
//In EE Projects, classpath refers to the WEB-INF/classes directory
URL resource = classLoader.getResource("users.json");
String path = resource.getPath();
//This method of obtaining the stream is actually equivalent to the domain, and the above method is encapsulated
//classLoader.getResourceAsStream()
File file = new File(path);
//Read the contents of the users.json file to form a string
BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
//Content is the content of the file
String content = bufferedReader.readLine();
Gson gson = new Gson();
List<User> userList = new ArrayList<>();
if(!StringUtils.isEmpty(content)){
    //If it is not empty, it means someone has registered before; If it is blank, it means that no one has registered before
    JsonElement jsonElement = new JsonParser().parse(content);
    JsonArray jsonArray = jsonElement.getAsJsonArray();
    //You need to determine whether the current user name has been registered
    for (JsonElement element : jsonArray) {
        User u = gson.fromJson(element, User.class);
        if(user.getUsername().equals(u.getUsername())){
            response.getWriter().println("The current user name has been registered");
            return;
        }
        userList.add(u);
    }
}
//It indicates that the registration is successful, and then it is written back to the file
userList.add(user);
//How to write a string to a file
FileWriter fileWriter = new FileWriter(file);
fileWriter.write(gson.toJson(userList));
fileWriter.flush();
fileWriter.close();

This part of the code needs to be changed, but there is also a line of code that does not need to be changed

        response.getWriter().println("The current user name has been registered");
        return;

The code displayed in this part does not need to be changed

The code that needs to be changed is tightly wrapped with the code that does not need to be changed. How to change the code that needs to be changed without affecting other code that does not need to be changed. The two are closely coupled.

Question:

The code blocks that need to be changed are tightly coupled with the code that does not need to be changed. When the code is changed, it is not easy to maintain.

How to handle code that needs to change

notes


MVC design pattern

The whole application will be divided into three parts according to MVC design pattern: model, view and controller

Model: encapsulates the data model (which can be understood as the object we use, i.e. user) and related operations on user, including registration, login, etc.

View: a display of a data model. Display of user. Personal home page

Controller: use the controller to decouple the model and view. The request is first distributed to the controller. The controller returns a result by calling one or more methods of the model, and then calls the view according to the result. In this way, the model and view are decoupled.

Model part:

ClassLoader classLoader = UserServlet.class.getClassLoader();
//This method can be used to obtain the resource information of a file in the classpath directory
//In EE Projects, classpath refers to the WEB-INF/classes directory
URL resource = classLoader.getResource("users.json");
String path = resource.getPath();
//This method of obtaining the stream is actually equivalent to the domain, and the above method is encapsulated
//classLoader.getResourceAsStream()
File file = new File(path);
//Read the contents of the users.json file to form a string
BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
//Content is the content of the file
String content = bufferedReader.readLine();
Gson gson = new Gson();
List<User> userList = new ArrayList<>();
if(!StringUtils.isEmpty(content)){
    //If it is not empty, it means someone has registered before; If it is blank, it means that no one has registered before
    JsonElement jsonElement = new JsonParser().parse(content);
    JsonArray jsonArray = jsonElement.getAsJsonArray();
    //You need to determine whether the current user name has been registered
    for (JsonElement element : jsonArray) {
        User u = gson.fromJson(element, User.class);
        if(user.getUsername().equals(u.getUsername())){
          
        }
        userList.add(u);
    }
}
//It indicates that the registration is successful, and then it is written back to the file
userList.add(user);
//How to write a string to a file
FileWriter fileWriter = new FileWriter(file);
fileWriter.write(gson.toJson(userList));
fileWriter.flush();
fileWriter.close();

View section (page):

response.getWriter().println("The current user name has been registered");
return;




response.getWriter().println("login was successful");

In fact, the main responsibility of MVC is to decouple the model from the view

for (JsonElement element : jsonArray) {
        User u = gson.fromJson(element, User.class);
        if(user.getUsername().equals(u.getUsername())){
            response.getWriter().println("The current user name has been registered");
            return;
        }
        userList.add(u);
    }
}

It is this place that has problems and needs to be decoupled.

controller: the part of the servlet in addition to these two parts. Generally speaking, you can think of servlets as controllers

package com.cskaoyan.register.mvc;

import com.cskaoyan.register.User;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@WebServlet("/user_bak/*")
public class UserServlet extends javax.servlet.http.HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws javax.servlet.ServletException, IOException {
        String requestURI = request.getRequestURI();
        String action = requestURI.replace(request.getContextPath() + "/user/", "");
        if("register".equals(action)){
            register(request, response);
        }
    }

    /**
     * Logic of registration
     * Take out the user name and password and verify them first
     * Persist the user name and password (first judge whether the user name is occupied)
     * @param request
     * @param response
     */
    private void register(HttpServletRequest request, HttpServletResponse response) throws IOException {
        User user = new User();
        Map<String, String[]> params = request.getParameterMap();
        try {
            BeanUtils.populate(user, params);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        //Check the parameters
        //Judge whether the user name and password are empty, etc
        if(!user.valid()){
            //In this case, the prompt is vague, and the return value of the valid method specifies a rule
            //200 OK 404 is empty 500 passwords are inconsistent twice
            response.getWriter().println("Illegal parameter");
            return;
        }
        //The specific business logic of registration first uses json files to store data, and then changes to databases
        //If the configuration file is placed in WEB-INF, how to handle it? How to get the path of the file servletContext.getRealPath();
        //If it is placed in the resources directory, how can I get it?
        //You can use the class loader to get
        //If the database needs to be changed by json in the future, what changes need to be made
//        boolean result = UserJsonModel.register(user);
        boolean result = UserSqlModel.register(user);

        if(!result){
            response.getWriter().println("The current user name has been registered");
            return;
        }
        response.getWriter().println("login was successful");

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws javax.servlet.ServletException, IOException {

    }
}

package com.cskaoyan.register.mvc;

import com.cskaoyan.register.User;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import org.apache.commons.lang3.StringUtils;

import java.io.*;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

public class UserJsonModel {

    public static boolean register(User user) throws IOException {
        ClassLoader classLoader = UserJsonModel.class.getClassLoader();
        //This method can be used to obtain the resource information of a file in the classpath directory
        //In EE Projects, classpath refers to the WEB-INF/classes directory
        URL resource = classLoader.getResource("users.json");
        String path = resource.getPath();
        //This method of obtaining the stream is actually equivalent to the domain, and the above method is encapsulated
        //classLoader.getResourceAsStream()
        File file = new File(path);
        //Read the contents of the users.json file to form a string
        BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
        //Content is the content of the file
        String content = bufferedReader.readLine();
        Gson gson = new Gson();
        List<User> userList = new ArrayList<>();
        if(!StringUtils.isEmpty(content)){
            //If it is not empty, it means someone has registered before; If it is blank, it means that no one has registered before
            JsonElement jsonElement = new JsonParser().parse(content);
            JsonArray jsonArray = jsonElement.getAsJsonArray();
            //You need to determine whether the current user name has been registered
            for (JsonElement element : jsonArray) {
                User u = gson.fromJson(element, User.class);
                if(user.getUsername().equals(u.getUsername())){
                    return false;
                }
                userList.add(u);
            }
        }
        //It indicates that the registration is successful, and then it is written back to the file
        userList.add(user);
        //How to write a string to a file
        FileWriter fileWriter = new FileWriter(file);
        fileWriter.write(gson.toJson(userList));
        fileWriter.flush();
        fileWriter.close();
        return true;
    }
}

At this point, our code has complied with the MVC design pattern. Is the code perfect enough?


Further improved into interface

For the convenience of future expansion, if the change is small enough, I should meet the following characteristics:

1. The method names of different models should be called register (the method names should be the same)

2. The parameter types in the method are the same

3. The return values of methods are of the same type (both boolean and int)

Only if these three conditions are met, the future code changes will be the smallest. Just change one class name.

What are the characteristics of the above three points? Interface

Further leads to the three-tier architecture.

The three-tier architecture is not MVC. In fact, it further decouples the code based on the MVC design pattern, and then forms a three-tier architecture.

Problems with MVC at this time:

1. The above three points are not constrained

2. When the logic of registration, login and query needs to be changed, the UserJsonModel needs to be changed to UserSqlModel. In fact, there are many changes.

Note: when introducing the three-tier architecture, we rename the code about data model operation in the previous model. For example, the previous UserJsonModel is changed to UserJsonDao, and the concept of dao is introduced. Data Access Object. A place dedicated to dealing with data.

Therefore, next, we need to design an interface called UserDao, which has two different implementation classes UserJsonDao and UserSqlDao

package com.cskaoyan.register.level3;

import com.cskaoyan.register.User;

public interface UserDao {
    
    boolean register(User user);
}
package com.cskaoyan.register.level3;

import com.cskaoyan.register.User;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import org.apache.commons.lang3.StringUtils;

import java.io.*;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

public class UserJsonDao implements UserDao{

    public boolean register(User user) {
        ClassLoader classLoader = UserJsonDao.class.getClassLoader();
        //This method can be used to obtain the resource information of a file in the classpath directory
        //In EE Projects, classpath refers to the WEB-INF/classes directory
        URL resource = classLoader.getResource("users.json");
        String path = resource.getPath();
        //This method of obtaining the stream is actually equivalent to the domain, and the above method is encapsulated
        //classLoader.getResourceAsStream()
        File file = new File(path);
        //Read the contents of the users.json file to form a string
        BufferedReader bufferedReader = null;
        try {
            bufferedReader = new BufferedReader(new FileReader(file));
            //Content is the content of the file
            String content = bufferedReader.readLine();
            Gson gson = new Gson();
            List<User> userList = new ArrayList<>();
            if(!StringUtils.isEmpty(content)){
                //If it is not empty, it means someone has registered before; If it is blank, it means that no one has registered before
                JsonElement jsonElement = new JsonParser().parse(content);
                JsonArray jsonArray = jsonElement.getAsJsonArray();
                //You need to determine whether the current user name has been registered
                for (JsonElement element : jsonArray) {
                    User u = gson.fromJson(element, User.class);
                    if(user.getUsername().equals(u.getUsername())){
                        return false;
                    }
                    userList.add(u);
                }
            }
            //It indicates that the registration is successful, and then it is written back to the file
            userList.add(user);
            //How to write a string to a file
            FileWriter fileWriter = new FileWriter(file);
            fileWriter.write(gson.toJson(userList));
            fileWriter.flush();
            fileWriter.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return true;
    }
}
package com.cskaoyan.register.level3;

import com.cskaoyan.register.User;

public class UserSqlDao implements UserDao{
    public  boolean register(User user) {
        return false;
    }
}

At this time, in the servlet, it is written as follows:

package com.cskaoyan.register.level3;

import com.cskaoyan.register.User;
import org.apache.commons.beanutils.BeanUtils;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;

@WebServlet("/user/*")
public class UserServlet extends javax.servlet.http.HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws javax.servlet.ServletException, IOException {
        String requestURI = request.getRequestURI();
        String action = requestURI.replace(request.getContextPath() + "/user/", "");
        if("register".equals(action)){
            register(request, response);
        }
    }

    /**
     * Logic of registration
     * Take out the user name and password and verify them first
     * Persist the user name and password (first judge whether the user name is occupied)
     * @param request
     * @param response
     */
    private void register(HttpServletRequest request, HttpServletResponse response) throws IOException {
        User user = new User();
        Map<String, String[]> params = request.getParameterMap();
        try {
            BeanUtils.populate(user, params);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        //Check the parameters
        //Judge whether the user name and password are empty, etc
        if(!user.valid()){
            //In this case, the prompt is vague, and the return value of the valid method specifies a rule
            //200 OK 404 is empty 500 passwords are inconsistent twice
            response.getWriter().println("Illegal parameter");
            return;
        }
        //The specific business logic of registration first uses json files to store data, and then changes to databases
        //If the configuration file is placed in WEB-INF, how to handle it? How to get the path of the file servletContext.getRealPath();
        //If it is placed in the resources directory, how can I get it?
        //You can use the class loader to get
        //If the database needs to be changed by json in the future, what changes need to be made
        //This line of code can be further written as a member variable
        UserDao userDao = new UserJsonDao();
        boolean result = userDao.register(user);
        boolean result = UserJsonModel.register(user);
//        boolean result = UserSqlDao.register(user);

        if(!result){
            response.getWriter().println("The current user name has been registered");
            return;
        }
        response.getWriter().println("login was successful");

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws javax.servlet.ServletException, IOException {

    }
}
    UserDao userDao = new UserJsonDao();
    boolean result = userDao.register(user);

As for the first line of code, you can further write it as a member variable. Why?

In the current servlet, we process logics such as registration and login, so we can turn userDao into a member variable at this time. Then, when processing logics such as login and query, changes will occur synchronously, and the changes will be further reduced.

package com.cskaoyan.register.level3;

import com.cskaoyan.register.User;
import org.apache.commons.beanutils.BeanUtils;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;

@WebServlet("/user/*")
public class UserServlet extends javax.servlet.http.HttpServlet {

    UserDao userDao = new UserJsonDao();

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws javax.servlet.ServletException, IOException {
        String requestURI = request.getRequestURI();
        String action = requestURI.replace(request.getContextPath() + "/user/", "");
        if("register".equals(action)){
            register(request, response);
        }else if("login".equals(action)){
            login(request, response);
        }
    }

    private void login(HttpServletRequest request, HttpServletResponse response) {
        //userDao.login();
    }

    /**
     * Logic of registration
     * Take out the user name and password and verify them first
     * Persist the user name and password (first judge whether the user name is occupied)
     * @param request
     * @param response
     */
    private void register(HttpServletRequest request, HttpServletResponse response) throws IOException {
        User user = new User();
        Map<String, String[]> params = request.getParameterMap();
        try {
            BeanUtils.populate(user, params);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        //Check the parameters
        //Judge whether the user name and password are empty, etc
        if(!user.valid()){
            //In this case, the prompt is vague, and the return value of the valid method specifies a rule
            //200 OK 404 is empty 500 passwords are inconsistent twice
            response.getWriter().println("Illegal parameter");
            return;
        }
        //The specific business logic of registration first uses json files to store data, and then changes to databases
        //If the configuration file is placed in WEB-INF, how to handle it? How to get the path of the file servletContext.getRealPath();
        //If it is placed in the resources directory, how can I get it?
        //You can use the class loader to get
        //If the database needs to be changed by json in the future, what changes need to be made
        //This line of code can be further written as a member variable
        boolean result = userDao.register(user);
        boolean result = UserJsonModel.register(user);
//        boolean result = UserSqlDao.register(user);

        if(!result){
            response.getWriter().println("The current user name has been registered");
            return;
        }
        response.getWriter().println("login was successful");

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws javax.servlet.ServletException, IOException {

    }
}

In the future, do you need to change the code inside the register method when changing the requirements again?

No, just change the direction of the member variable userDao.

At this time, the three-tier architecture has taken shape, with two layers.

One is the display layer controller

Business layer service (why do you need a service? At this time, it is found that the code has been well designed and the basic requirements can be well implemented. Why do you need a service?)

Suppose that if the business scenario is somewhat complex at this time, for example, do another experiment to evaluate the difference in operation performance between the two methods.

Operation 1:

dao.method1();

dao.method2();

Operation 2:

dao.method1();

dao.method3();

dao.method4();

We need to evaluate the performance difference between the two operation modes. How can we change the operation mode without modifying the code as much as possible?

After introducing a service layer in the middle, you only need to extend the code instead of modifying the existing code logic to make changes again in the future

//Do a test to evaluate the performance of both operations
    //You find that you are in a state of repeatedly modifying the code to adapt to changes in requirements
    private void operation(){       
        //Mode 1:
//        userDao.method1();
//        userDao.method2();
        //Mode 2:
        userDao.method1();
        userDao.method3();
        userDao.method4();
    }

This place can be further optimized

package com.cskaoyan.register.level3;

import com.cskaoyan.register.User;

public interface UserService {
    
    boolean register(User user);
    
    void operation();
}
package com.cskaoyan.register.level3;

import com.cskaoyan.register.User;

public class UserServiceImpl implements UserService {

    UserDao userDao = new UserJsonDao();

    @Override
    public boolean register(User user) {
        return userDao.register(user);
    }

    @Override
    public void operation() {
        userDao.method1();
        userDao.method2();
    }
}
package com.cskaoyan.register.level3;

import com.cskaoyan.register.User;

public class UserServiceImpl2 implements UserService {

    UserDao userDao = new UserJsonDao();

    @Override
    public boolean register(User user) {
        return userDao.register(user);
    }

    @Override
    public void operation() {
        userDao.method1();
        userDao.method3();
        userDao.method4();
    }
}
package com.cskaoyan.register.level3;

import com.cskaoyan.register.User;
import org.apache.commons.beanutils.BeanUtils;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;

@WebServlet("/user/*")
public class UserServlet extends javax.servlet.http.HttpServlet {

    //UserDao userDao = new UserJsonDao();

    UserService userService = new UserServiceImpl();

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws javax.servlet.ServletException, IOException {
        String requestURI = request.getRequestURI();
        String action = requestURI.replace(request.getContextPath() + "/user/", "");
        if("register".equals(action)){
            register(request, response);
        }else if("login".equals(action)){
            login(request, response);
        }
    }

    private void login(HttpServletRequest request, HttpServletResponse response) {
        //userDao.login();
    }

    /**
     * Logic of registration
     * Take out the user name and password and verify them first
     * Persist the user name and password (first judge whether the user name is occupied)
     * @param request
     * @param response
     */
    private void register(HttpServletRequest request, HttpServletResponse response) throws IOException {
        User user = new User();
        Map<String, String[]> params = request.getParameterMap();
        try {
            BeanUtils.populate(user, params);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        //Check the parameters
        //Judge whether the user name and password are empty, etc
        if(!user.valid()){
            //In this case, the prompt is vague, and the return value of the valid method specifies a rule
            //200 OK 404 is empty 500 passwords are inconsistent twice
            response.getWriter().println("Illegal parameter");
            return;
        }
        //The specific business logic of registration first uses json files to store data, and then changes to databases
        //If the configuration file is placed in WEB-INF, how to handle it? How to get the path of the file servletContext.getRealPath();
        //If it is placed in the resources directory, how can I get it?
        //You can use the class loader to get
        //If the database needs to be changed by json in the future, what changes need to be made
        //This line of code can be further written as a member variable
        boolean result = userService.register(user);
        boolean result = UserJsonModel.register(user);
//        boolean result = UserSqlDao.register(user);

        if(!result){
            response.getWriter().println("The current user name has been registered");
            return;
        }
        response.getWriter().println("login was successful");

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws javax.servlet.ServletException, IOException {

    }

    //Do a test to evaluate the performance of both operations
    //You find that you are in a state of repeatedly modifying the code to adapt to changes in requirements
    private void operation(){
        //Mode 1:
//        userDao.method1();
//        userDao.method2();
        //Mode 2:
//        userDao.method1();
//        userDao.method3();
//        userDao.method4();
        userService.operation();
    }
}

controller refers to service, and service refers to dao

Display layer

Business layer

Data layer

Generally speaking, it can also be regarded as

controller

service

dao

A project should have at least three layers.

One is the data layer dao

The code of service and dao is actually to further decouple the previous model, that is, the code of the operation part of the data model.

After the introduction of the three-tier architecture, the execution entry of the whole program is still the service method located in the servlet

Posted by Sooz719 on Sat, 02 Oct 2021 15:11:13 -0700