Complex functions should be disassembled into relatively simple functions, which is easy to develop
web projects can split functionality on request
Click the registration button to jump to the registration page, which is a request;
Submit the registration information to the server, and the server will send an activation email, which is a request;
Click the link in the activation email, and the server will change the user's status to activated. This is a request
Each request is developed according to the data access layer, business layer and view layer
Some requests do not have a complete three-tier
1 visit the registration page
Now the links of the home page and the registration button are static links. First change them into dynamic links
The web pages in templates cannot be accessed directly, but can only be accessed by Controller
Since the Controller method has been written on the home page, you can click it now. The registration has not been written yet. Click it
Now write the registered Controller method
1.1 Controller
To develop the registration function, use a Controller again
//Visit the registration page @RequestMapping(path = "/register",method = RequestMethod.GET) public String getRegister(){ return "/site/register"; }
Note: the path in the second line is the URL of the registration page, which should be consistent with the URL in the engine template
The URL in the fourth line is the pathname of the dynamic page in the returned templates
1.2 dynamic page
Change the site/register.html under templates to a dynamic page
1.2.1 processing static resources from beginning to end
1.2.2 handling the head
The head in the head
index.html
register.html
2 submit registration data
2.1 data access layer
Provides methods for inserting users and modifying user status
2.2 business layer
1. Return various error messages
2. Registered user
3. Send activation email
coding...
[SpringBoot learning] 01. Send email to SpringBoot
[SpringBoot learning] 02. Encrypt the password with MD5
//Register user and send activation email public Map<String,Object> register(User user){ //The error information is encapsulated by map Map<String, Object> map = new HashMap<>(); //Null value judgment if(user==null){ throw new IllegalArgumentException("User cannot be empty!"); } if(StringUtils.isBlank(user.getUsername())){ map.put("usernameMsg","User name cannot be empty!"); return map; } if(StringUtils.isBlank(user.getPassword())){ map.put("passwordMsg","Password cannot be empty!"); return map; } if(StringUtils.isBlank(user.getEmail())){ map.put("emailMsg","Mailbox cannot be empty!"); return map; } //Verify user name User u = userMapper.selectByName(user.getUsername()); if(u!=null){ map.put("usernameMsg","The user name already exists!"); return map; } //Verify mailbox u=userMapper.selectByEmail(user.getEmail()); if(u!=null){ map.put("emailMsg","This mailbox has been registered!"); return map; } //Registered user user.setSalt(CommunityUtil.generateUUID().substring(0,5)); user.setPassword(CommunityUtil.md5(user.getPassword()+user.getSalt())); user.setType(0); user.setStatus(0); user.setActivationCode(CommunityUtil.generateUUID()); user.setHeaderUrl(String.format("http://images.nowcoder.com/head/%dt.png", new Random().nextInt(1000))); user.setCreateTime(new Date()); userMapper.insertUser(user); //Send activation email Context context = new Context(); context.setVariable("email",user.getEmail()); // http://localhost:8080/community/activation/id/code String url = domain + contextPath + "/activation/" + user.getId() + "/" + user.getActivationCode(); context.setVariable("url", url); String content = templateEngine.process("/mail/activation", context); mailClient.sendMail(user.getEmail(), "Activate account", content); return map; }
2.3 modify email to dynamic template
2.4 viewing layer
//Receive registration data and send activation email @RequestMapping(path = "/register",method = RequestMethod.POST) public String register(User user, Model model){ Map<String,Object> map = userService.register(user); //no problem if(map.isEmpty()||map==null){ model.addAttribute("Msg","Registration is successful. We have sent an activation email to your email. Please go to activate as soon as possible!"); model.addAttribute("target","/index"); return "site/operate-result"; } //something the matter else{ model.addAttribute("usernameMsg",map.get("usernameMsg")); model.addAttribute("passwordMsg",map.get("passwordMsg")); model.addAttribute("emailMsg",map.get("emailMsg")); return "site/register"; } }
2.5 dynamic formwork
The pages returned by the view layer should be changed to static templates
2.5.1 site/operate-result.html
2.5.2 site/register.html
action: when submitting a form, the destination of sending form data is / register, which will be processed by the Controller method whose address is mapped to / register
method="post" th:action="@{/register}"
The front end passes the value to the back end
The question that puzzles me for a long time: how can the data submitted by the front end in form be encapsulated into classes and passed to the back end?
My guess is:
After the request is submitted, the DispatcherServlet is passed to the corresponding Controller method. The input parameters of this method include User. Then match the attributes of User class from the data submitted by the form, encapsulate the data into User class, and then pass it to the Controller method
This needs to see the source code to confirm
It is certain that the name value on the front end is consistent with the input parameter of the Controller method, and the dispatcher servlet will assign it to the value of the corresponding input parameter
The back end passes the value to the front end
1. html page
2. Pass JSON string
3 activate registered account
After clicking the activation link, the server will change the user's status from 0 to 1
3.1 data access layer
It provides the function of modifying status according to user id
3.2 business layer
Provide the method to activate the user: if the incoming activation code is consistent with the activation code in the database, the activation is successful
Put the state constant in the interface and use the class of the state constant to inherit the interface
//Activate user public int activation(int userId,String code){ User user = userMapper.selectById(userId); if(user.getStatus()==1) return ACTIVATION_REPEAT; else{ if(user.getActivationCode().equals(code)){ userMapper.updateStatus(userId, 1); return ACTIVATION_SUCCESS; } else return ACTIVATION_FAIL; } }
3.3 viewing layer
//Activate user // http://localhost:8080/community/activation/id/code @RequestMapping(path = "/activation/{userId}/{activationCode}",method = RequestMethod.GET) public String activation(Model model,@PathVariable("userId")int userId,@PathVariable("activationCode")String code){ int result = userService.activation(userId, code); if(result==ACTIVATION_REPEAT){ model.addAttribute("Msg","Invalid operation. You have activated this account and do not need to reactivate it."); model.addAttribute("target", "/index"); }else if(result==ACTIVATION_SUCCESS){ model.addAttribute("Msg","Activation succeeded,Your account can be used normally!"); model.addAttribute("target", "/login"); }else{ model.addAttribute("Msg","Activation failed,The activation code you provided is incorrect!"); model.addAttribute("target", "/index"); } return "/site/operate-result"; }
3.4 dynamic pages involved in the view layer
4 test
Well, why can't you request server data asynchronously.....
talk later
Some bugs have been changed. Another bug is how to asynchronously display whether the account has been registered or not?
Oh, the teacher didn't realize asynchronous display originally. I'll think about how to display it