Niuke community project (development and registration function)

When the project is complex, you need to change your thinking and disassemble the problem. The function is mainly divided into three aspects: the first is to visit the registration page, the second is to submit registration data, and the third is to activate the registration account. Or according to the three-tier logic. Further refinement is:

  1. Visit the registration page,
    Click the link in the top area to open the registration page.
  2. Submit registration data
    Submit data through a form.
    The server verifies whether the account already exists and whether the mailbox has been registered.
    The server sends an activation email.
  3. Activate registered account
    Click the link in the email to access the activation service of the server.

Visit the registration page

Create a new LoginController under the controller package, return to the registration page, click registration in the index on the home page, and the default jump is the register page.

package com.newcoder.community.controller;

import com.newcoder.community.entity.User;
import com.newcoder.community.service.UserService;
import com.newcoder.community.util.CommunityConstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import java.util.Map;

@Controller
public class LoginController implements CommunityConstant {
    @Autowired
    private UserService userService;

    @RequestMapping(path = "/register",method = RequestMethod.GET)
    public String getResisterPage(){
        return "/site/register";
    }
    @RequestMapping(path = "/login",method = RequestMethod.GET)
    public String getLoginPage(){
        return "/site/login";
    }

    @RequestMapping(path = "/register",method = RequestMethod.POST)
    public String register(Model model ,User user){
        Map<String,Object> map = userService.register(user);
        if (map == null || map.isEmpty()){
//            Successfully transferred the home page,
            model.addAttribute("msg","Registration is successful. We have sent an activation email to your email. Please activate as soon as possible");
            model.addAttribute("target","/index");
            return "/site/operate-result";



        }else {
            model.addAttribute("usernameMsg",map.get("usernameMsg"));
            model.addAttribute("passwordMsg",map.get("passwordMsg"));
            model.addAttribute("emailMsg",map.get("emailMsg"));
            return "/site/register";


        }
    }
    @RequestMapping(path = "/activation/{userId}/{code}",method = RequestMethod.GET)
    public String activation(Model model, @PathVariable("userId") int userId, @PathVariable("code") String code){
        int result = userService.activation(userId, code);
        if (result == ACTIVATION_SUCCESS){
            model.addAttribute("msg","Activation succeeded. Your account can be used normally");
            model.addAttribute("target","/login");
        } else if (result == ACTIVATION_REPEAT){
            model.addAttribute("msg","Invalid operation. The account has been activated");
            model.addAttribute("target","/index");
        }else {
            model.addAttribute("msg","Activation failed. The activation code you provided is incorrect");
            model.addAttribute("target","/index");

        }
        return "/site/operate-result";
    }
}

Registration page

Encapsulate a tool class

The first is to generate a random string, using UUID. For simplicity, remove the short horizontal line in the generated string.
The second is MD5 encryption, which encrypts the password. The MD5 value calculated by the same password is the same, so it is not safe enough. We salt the password, that is, splice a random string behind the user's password before MD5 calculation.

package com.newcoder.community.util;

import org.apache.commons.lang3.StringUtils;
import org.springframework.util.DigestUtils;

import java.util.UUID;

public class CommunityUtil {
//    Generate random string
//    Provide the random name of the uploaded
    public static String generateUUid(){
        return UUID.randomUUID().toString().replace("-","");
    }
//    encryption algorithm 
//    Encryption is just encryption. It can't decrypt a random string
    public static String md5(String key){
        if (StringUtils.isBlank(key)){
            return null;
        }
        return DigestUtils.md5DigestAsHex(key.getBytes());
    }
}

Registration service

Configure a project address localhost:80/community/index in properties

community.path.domain = http://localhost:80
  1. First, the project path and domain name are introduced with annotations
  2. Write the registration method, return the value, and return the corresponding message with map.
  3. First, make a null judgment on the user object passed in
  4. Then verify whether the account and email have been registered.
    Then complete the value of the user object, generate salt, and then encrypt the password. The registered users are ordinary users. The type is set to 0 and the status is set to inactive 0. The avatar is regenerated into a random string of activation code. The default avatar of niuke.com can be used. The avatar 0-1000 can be inserted into the object after being generated by the registration time. Use the template engine to generate html mail and send it.

userService

package com.newcoder.community.service;

import com.newcoder.community.dao.UserMapper;
import com.newcoder.community.entity.User;
import com.newcoder.community.service.imp.MailClient;
import com.newcoder.community.util.CommunityConstant;
import com.newcoder.community.util.CommunityUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

@Service
public class UserService implements CommunityConstant {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private MailClient mailClient;
    @Autowired
    private TemplateEngine templateEngine;
    @Value("${community.path.domain}")
    private  String domain;
    @Value("${server.servlet.context-path}")
    private String contextPath;


//    Generate activation code

    public User findUserById(int id){
        return userMapper.selectById(id);
    }
    public Map<String,Object> register(User user){
        Map<String,Object> map = new HashMap<>();
//        Null value processing
        if (user == null){
            throw new IllegalArgumentException("Parameter is not empty");
        }
        if (StringUtils.isBlank(user.getUsername())){
            map.put("usernameMsg","Account number 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;
        }
//        Judge account number
        User u = userMapper.selectByName(user.getUsername());
        if (u!=null){
            map.put("usernameMsg","The account already exists");
            return map;
        }
//        Verify mailbox
         u = userMapper.selectByEmail(user.getEmail());
        if (u!=null){
            map.put("emailMsg","The mailbox already exists");
            return map;
        }
//Start registration. The so-called registration is to put users in the library and generate random strings
        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());
//        Random image
        user.setHeaderUrl(String.format("http://images.nowcoder.com/head/%dt.png",new Random().nextInt(1000)));
        user.setCreateTime(new Date());
        userMapper.insertUser(user);

//        Need to send html file
        Context context = new Context();
        context.setVariable("email",user.getEmail());
//        url path
        String url = domain+contextPath+"/activation/"+user.getId()+"/"+user.getActivationCode();
        context.setVariable("url",url);
//
        String content = templateEngine.process("/mail/activation",context);
        mailClient.senMail(user.getEmail(),"Activate account",content);
//        The active state is
        return  map;

    }
    public int activation(int userId,String code){
//        First, check the user and judge after the activation code
        User user = userMapper.selectById(userId);
        if (user.getStatus() == 1){
//            Indicates that the activation is repeated
            return ACTIVATION_REPEAT;
        }else if(user.getActivationCode().equals(code)){
//            Said no problem
            userMapper.updateStatus(userId,1);
            return ACTIVATION_SUCCESS;
        }
        else {
            return ACTIVATION_FAILURE;
        }
    }
}

Then write the control method in LoginController. First, call the register method of the service to return the map message. If the map is empty, the page of successful registration is returned
Finally, restart the startup class and register successfully!

Keywords: Java Spring RESTful

Added by anonymouse on Sun, 03 Oct 2021 22:57:20 +0300