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