Using springboot to do a computer mall project, the next day

Keywords: Java Spring Boot intellij-idea

User login

1 user login persistence layer

Learning video address [actual combat full version of SpringBoot project] actual combat of SpringBoot+MyBatis+MySQL computer mall project_ Beep beep beep_ bilibili

1.1 planning SQL statements to be executed

The SQL statement to be executed by the user login function is to query the user data according to the user name, and then judge whether the password is correct. The SQL statement is roughly:

SELECT * FROM t_user WHERE username=?

Note: the background development corresponding to the above SQL statements has been completed and does not need to be developed again.

1.2 interface and abstract method

Note: no further development is required.

1.3 configuring SQL mapping

Note: no further development is required.

2 user login business layer

2.1 planning exceptions

1. If the user name does not exist, the login fails, throws a com.cy.store.service.ex.UserNotFoundException exception, and generates five constructor methods of the child class from the parent class.

package com.cy.store.service.ex;
​
/** Exception where user data does not exist */
public class UserNotFoundException extends ServiceException {
    // Override Methods...
}

2. If the value of the isDelete field of the user is 1, it means that the current user data is marked as "deleted". The login failure operation is required, and a UserNotFoundException is thrown.

3. If the password is wrong, the login fails and a com.cy.store.service.ex.PasswordNotMatchException exception is thrown.

package com.cy.store.service.ex;
​
/** Exception of password verification failure */
public class PasswordNotMatchException extends ServiceException {
    // Override Methods...
}

4. Create the above UserNotFoundException and PasswordNotMatchException exception classes, which should inherit from the ServiceException class.

2.2 interfaces and abstract methods

Add the abstract method of login function in IUserService interface.

/**
 * User login
 * @param username user name
 * @param password password
 * @return User data for successful login
 */
User login(String username, String password);

After successful login, you need to obtain the user's id to facilitate subsequent identification of the user's identity, and also need to obtain the user's user name, avatar and other data for display in the software interface. You need to use the type that can encapsulate the data for id, user name and avatar as the return value type of the login method.

2.3 implementing abstract methods

1. Add login(String username, String password) method in UserServiceImpl class and analyze business logic.

@Override
public User login(String username, String password) {
    // Call the findByUsername() method of userMapper to query user data according to the parameter username
    
    // Judge whether the query result is null
    // Yes: a UserNotFoundException exception is thrown
    
    // Judge whether isDelete in the query result is 1
    // Yes: a UserNotFoundException exception is thrown
    
    // Get salt value from query results
    // Call the getMd5Password() method to encrypt the parameter password and salt
    // Judge whether the password in the query result is inconsistent with the password encrypted above
    // Yes: a PasswordNotMatchException exception is thrown
    
    // Create a new User object
    // Encapsulate the uid, username and avatar in the query results into a new user object
    // Returns a new user object
    
    return null;
}

2. Specific implementation of the code in the login (string username, string password) method.

@Override
public User login(String username, String password) {
    // Call the findByUsername() method of userMapper to query user data according to the parameter username
    User result = userMapper.findByUsername(username);
    // Judge whether the query result is null
    if (result == null) {
        // Yes: a UserNotFoundException exception is thrown
        throw new UserNotFoundException("Error that user data does not exist");
    }
​
    // Judge whether isDelete in the query result is 1
    if (result.getIsDelete() == 1) {
        // Yes: a UserNotFoundException exception is thrown
        throw new UserNotFoundException("Error that user data does not exist");
    }
​
    // Get salt value from query results
    String salt = result.getSalt();
    // Call the getMd5Password() method to encrypt the parameter password and salt
    String md5Password = getMd5Password(password, salt);
    // Judge whether the password in the query result is inconsistent with the password encrypted above
    if (!result.getPassword().equals(md5Password)) {
        // Yes: a PasswordNotMatchException exception is thrown
        throw new PasswordNotMatchException("Password verification failed error");
    }
​
    // Create a new User object
    User user = new User();
    // Encapsulate the uid, username and avatar in the query results into a new user object
    user.setUid(result.getUid());
    user.setUsername(result.getUsername());
    user.setAvatar(result.getAvatar());
    // Returns a new user object
    return user;
}

3. After completion, write and complete the unit test in UserServiceTests.

@Test
public void login() {
    try {
        String username = "lower";
        String password = "123456";
        User user = iUserService.login(username, password);
        System.out.println("Login succeeded!" + user);
    } catch (ServiceException e) {
        System.out.println("Login failed!" + e.getClass().getSimpleName());
        System.out.println(e.getMessage());
    }

Note: do not try to log in with wrong data, such as the data of new users through persistence layer test in the early stage, and delete these data from the table.

3 user login controller

3.1 handling exceptions

When processing the user login function, UserNotFoundException and PasswordNotMatchException exceptions are thrown in the business layer, and both exceptions have not been handled. You should add these two branches to the exception handling method of BaseController class for processing.

@ExceptionHandler(ServiceException.class)
public JsonResult<Void> handleException(Throwable e) {
    JsonResult<Void> result = new JsonResult<Void>(e);
    if (e instanceof UsernameDuplicateException) {
        result.setState(4000);
    } else if (e instanceof UserNotFoundException) {
        result.setState(4001);
    } else if (e instanceof PasswordNotMatchException) {
        result.setState(4002);
    } else if (e instanceof InsertException) {
        result.setState(5000);
    }
    return result;
}

3.2 design request

Design the request submitted by the user and design the response method:

Request path: / users/login
 Request parameters: String username, String password
 Request type: POST
 Response result: jsonresult < user >

3.3 processing requests

1. Add login(String username, String password) method to handle login request in UserController class.

@RequestMapping("login")
public JsonResult<User> login(String username, String password) {
    // Call the method of the business object to perform login and obtain the return value
    
    // Encapsulate the above return value and status code OK into the response result and return
    
    return null;
}

2. Specific implementation of login(String username, String password) method code for processing login request.

@RequestMapping("login")
public JsonResult<User> login(String username, String password) {
    // Call the method of the business object to perform login and obtain the return value
    User data = userService.login(username, password);
    // Encapsulate the above return value and status code OK into the response result and return
    return new JsonResult<User>(OK, data);
}

4. After completion, start the project and visit http://localhost:8080/users/login?username=Tom&password=1234 Request login.

4 user login front page

1. At the end of the body tag in the login.html page, add a script tag to write JavaScript programs.

<script type="text/javascript">
    $("#btn-login").click(function() {
    $.ajax({
        url: "/users/login",
        type: "POST",
        data: $("#form-login").serialize(),
        dataType: "json",
        success: function(json) {
            if (json.state == 200) {
                alert("Login succeeded!");
                location.href = "index.html";
            } else {
                alert("Login failed!" + json.message);
            }
        }
    });
});
</script>

2. After completion, start the project and open the browser for access http://localhost:8080/web/login.html Page and log in.

Interceptor

In Spring MVC, intercepting requests is implemented through the processor interceptor HandlerInterceptor, which intercepts the address of the request. To define an interceptor in Spring MVC, you need to implement the HandlerInterceptor interface.

1 HandlerInterceptor

1.1 preHandle() method

This method will be called before the request is processed. Interceptors in spring MVC are chain calls. Multiple interceptors can exist simultaneously in an application or a request. Each Interceptor call will be executed in sequence according to its declaration order, and the first execution is the preHandle() method in the Interceptor. Therefore, some pre initialization operations or preprocessing of the current request can be carried out in this method, and some judgments can be made in this method to determine whether the request should continue. The return value of this method is Boolean. When false is returned, it means that the request ends and subsequent interceptors and controllers will not execute again; When the return value is true, it will continue to call the preHandle method of the next Interceptor. If it is already the last Interceptor, it will call the Controller method of the current request.

1.2 postHandle() method

This method will be executed after the current request is processed, that is, after the Controller method is called, but it will be called before the dispatcher servlet performs view return rendering, so we can operate on the ModelAndView object processed by the Controller in this method. The postHandle method is called in the opposite direction to the preHandle, that is, the postHandle method of the Interceptor declared first will be executed later. If the return value of the preHandle() method of the current Interceptor is false, this method will not be called.

1.3 afterCompletion() method

This method will be executed after the end of the entire current request, that is, after the dispatcher servlet renders the corresponding view. The main function of this method is to clean up resources. If the return value of the preHandle() method of the current Interceptor is false, this method will not be called.

2 WebMvcConfigurer

In the SpringBoot project, if you want to customize some interceptors, viewresolvers and messageconverters, how to implement them? In SpringBoot version 1.5, the methods in the WebMvcConfigurerAdapter class are rewritten to add custom interceptors, view parsers, message converters, etc. After SpringBoot version 2.0, this class is marked @ Deprecated. Therefore, we can only implement the WebMvcConfigurer interface.

One of the core methods in the WebMvcConfigurer interface is the addinterceptors (interceptor Registry) method, which means adding interceptors. It is mainly used to intercept user login status, log, etc.

  • addInterceptor: you need an interceptor instance that implements the HandlerInterceptor interface

  • addPathPatterns: used to set the filter path rules of the interceptor; addPathPatterns("/ * *") intercepts all requests

  • excludePathPatterns: used to set filtering rules that do not need to be intercepted

public interface WebMvcConfigurer {
    // ...
    default void addInterceptors(InterceptorRegistry registry) {
    }
}

3. Add interceptor function to the project

1. Analysis: many operations in the project can only be performed after logging in. It is unrealistic to write code to check whether there is login information in the Session before each request is processed. Therefore, interceptors should be used to solve this problem.

2. Create interceptor class com.cy.store.interceptor.LoginInterceptor and implement org.springframework.web.servlet.HandlerInterceptor interface.

package com.cy.store.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
​
/** Define processor interceptors */
public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (request.getSession().getAttribute("uid") == null) {
            response.sendRedirect("/web/login.html");
            return false;
        }
        return true;
    }
}

3. Create the configuration class of LoginInterceptorConfigurer interceptor and implement the org.springframework.web.servlet.config.annotation.WebMvcConfigurer interface. The configuration class needs to be decorated with @ configuration annotation.

package com.cy.store.config;
import com.cy.store.interceptor.LoginInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.ArrayList;
import java.util.List;
​
/** Register processor interceptor */
@Configuration
public class LoginInterceptorConfigurer implements WebMvcConfigurer {
    /** Interceptor configuration */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // Create interceptor object
        HandlerInterceptor interceptor = new LoginInterceptor();
​
        // White list
        List<String> patterns = new ArrayList<String>();
        patterns.add("/bootstrap3/**");
        patterns.add("/css/**");
        patterns.add("/images/**");
        patterns.add("/js/**");
        patterns.add("/web/register.html");
        patterns.add("/web/login.html");
        patterns.add("/web/index.html");
        patterns.add("/web/product.html");
        patterns.add("/users/reg");
        patterns.add("/users/login");
        patterns.add("/districts/**");
        patterns.add("/products/**");
​
        // Add interceptors through the registration tool
        registry.addInterceptor(interceptor).addPathPatterns("/**").excludePathPatterns(patterns);
    }
}

conversation

1. Rebuild the login() method, and store the uid and username into the HttpSession object after successful login.

@RequestMapping("login")
public JsonResult<User> login(String username, String password, HttpSession session) {
    // Call the method of the business object to perform login and obtain the return value
    User data = userService.login(username, password);
​
    //After successful login, save uid and username into HttpSession
    session.setAttribute("uid", data.getUid());
    session.setAttribute("username", data.getUsername());
    // System.out.println ("uid=" + getUidFromSession(session));
    // System.out.println ("username=" + getUsernameFromSession(session));
​
    // Encapsulate the above return value and status code OK into the response result and return
    return new JsonResult<User>(OK, data);
}

2. Add a method to get uid and username from HttpSession object in the parent class BaseController, so as to quickly get the values of these two attributes in the future.

 

/**
 * Get uid from HttpSession object
 * @param session HttpSession object
 * @return id of the currently logged in user
 */
protected final Integer getUidFromSession(HttpSession session) {
    return Integer.valueOf(session.getAttribute("uid").toString());
}

/**
 * Get user name from HttpSession object
 * @param session HttpSession object
 * @return Currently logged in user name
 */
protected final String getUsernameFromSession(HttpSession session) {
    return session.getAttribute("username").toString();
}

 

Change Password

1 user - modify password - persistence layer

1.1 planning SQL statements to be executed

The SQL statements that users need to execute when modifying passwords are roughly as follows:

UPDATE t_user SET password=?, modified_user=?, modified_time=? WHERE uid=?

Before changing the password, you should also check whether the user data exists, whether the user data is marked as "deleted", and whether the original password is correct. These checks can be assisted by querying the user data:

SELECT * FROM t_user WHERE uid=?

1.2 interface and abstract method

Add the updatePasswordByUid(Integer uid,String password,String modifiedUser,Date modifiedTime) abstract method in the UserMapper interface.

When using annotation to simplify xml configuration, the @ Param annotation is used to name the parameters. After the parameters are named, the parameter values can be obtained according to the name, and the parameters can be correctly passed into sql statements@ The parameter name in the Param("parameter name") annotation needs to be consistent with the parameter name of #{parameter name} in the sql statement.

/**
 * Update user's password based on uid
 * @param uid User id
 * @param password New password
 * @param modifiedUser Last modified executor
 * @param modifiedTime Last modification time
 * @return Number of rows affected
 */
Integer updatePasswordByUid(
        @Param("uid") Integer uid, 
        @Param("password") String password, 
        @Param("modifiedUser") String modifiedUser, 
        @Param("modifiedTime") Date modifiedTime);
​
/**
 * Query user data according to user id
 * @param uid User id
 * @return Matching user data. If there is no matching user data, null is returned
 */
User findByUid(Integer uid);

1.3 configuring SQL mapping

1. Configure the mapping of updatePasswordByUid() and findByUid() abstract methods in UserMapper.xml.

<!-- according to uid Update user's password:
     Integer updatePasswordByUid(
        @Param("uid") Integer uid, 
        @Param("password") String password, 
        @Param("modifiedUser") String modifiedUser, 
        @Param("modifiedTime") Date modifiedTime) -->
<update id="updatePasswordByUid">
    UPDATE
        t_user 
    SET
        password = #{password},
        modified_user = #{modifiedUser},
        modified_time = #{modifiedTime} 
    WHERE
        uid = #{uid}
</update>
​
<!-- According to user id Query user data: User findByUid(Integer uid) -->
<select id="findByUid" resultMap="UserEntityMap">
    SELECT
        *
    FROM
        t_user
    WHERE
        uid = #{uid}
</select>

2. Write and execute unit tests in UserMapperTests.

@Test
public void updatePasswordByUid() {
    Integer uid = 7;
    String password = "123456";
    String modifiedUser = "Super administrator";
    Date modifiedTime = new Date();
    Integer rows = userMapper.updatePasswordByUid(uid, password, modifiedUser, modifiedTime);
    System.out.println("rows=" + rows);
}
​
@Test
public void findByUid() {
    Integer uid = 7;
    User result = userMapper.findByUid(uid);
    System.out.println(result);
}

2 user - modify password - business layer

2.1 planning exceptions

1. Before modifying the password, the user needs to check whether the user data exists and whether it is marked as "deleted". If the check fails, a UserNotFoundException exception should be thrown.

2. When the user modifies the password, the modification may fail due to the error of the original password, and a PasswordNotMatchException exception shall be thrown.

3. When changing the password, if the number of affected rows returned is different from the expected value, an UpdateException exception should be thrown.

4. Create com.cy.store.service.ex.UpdateException exception class, which inherits from ServiceException class.

/** Exception in updating data */
public class UpdateException extends ServiceException {
    // Override Methods...
}

2.2 interfaces and abstract methods

Add the changePassword(Integer uid, String username, String oldPassword, String newPassword) abstract method in IUserService.

/**
 * Change Password
 * @param uid Currently logged in user id
 * @param username user name
 * @param oldPassword Original password
 * @param newPassword New password
 */
public void changePassword(Integer uid, String username, String oldPassword, String newPassword);

2.3 implementing abstract methods

1. Implement the changePassword() abstract method in the UserServiceImpl class.

public void changePassword(Integer uid, String username, String oldPassword, String newPassword) {
    // Call the findByUid() method of userMapper to query user data according to the parameter uid
    // Check whether the query result is null
    // Yes: a UserNotFoundException exception is thrown
​
    // Check whether isDelete in the query result is 1
    // Yes: a UserNotFoundException exception is thrown
​
    // Extract salt value from query results
    // The parameter oldPassword is encrypted with the salt value to obtain oldMd5Password
    // Judge whether the password in the query result is inconsistent with oldMd5Password
    // Yes: a PasswordNotMatchException exception is thrown
​
    // The parameter newPassword is encrypted with the salt value to obtain newMd5Password
    // Create current time object
    // Call updatePasswordByUid() of userMapper to update the password and get the return value
    // Judge whether the number of affected rows returned above is not 1
    // Yes: UpdateException exception thrown
}

2. Specific code of changepassword() method.

The equals and contentEquals methods in String can be used to compare whether the contents of String objects are the same.

@Override
public void changePassword(Integer uid, String username, String oldPassword, String newPassword) {
    // Call the findByUid() method of userMapper to query user data according to the parameter uid
    User result = userMapper.findByUid(uid);
    // Check whether the query result is null
    if (result == null) {
        // Yes: a UserNotFoundException exception is thrown
        throw new UserNotFoundException("User data does not exist");
    }
    
    // Check whether isDelete in the query result is 1
    if (result.getIsDelete().equals(1)) {
        // Yes: a UserNotFoundException exception is thrown
        throw new UserNotFoundException("User data does not exist");
    }
    
    // Extract salt value from query results
    String salt = result.getSalt();
    // The parameter oldPassword is encrypted with the salt value to obtain oldMd5Password
    String oldMd5Password = getMd5Password(oldPassword, salt);
    // Judge whether the password in the query result is inconsistent with oldMd5Password
    if (!result.getPassword().contentEquals(oldMd5Password)) {
        // Yes: a PasswordNotMatchException exception is thrown
        throw new PasswordNotMatchException("Original password error");
    }
    
    // The parameter newPassword is encrypted with the salt value to obtain newMd5Password
    String newMd5Password = getMd5Password(newPassword, salt);
    // Create current time object
    Date now = new Date();
    // Call updatePasswordByUid() of userMapper to update the password and get the return value
    Integer rows = userMapper.updatePasswordByUid(uid, newMd5Password, username, now);
    // Judge whether the number of affected rows returned above is not 1
    if (rows != 1) {
        // Yes: an UpdateException exception is thrown
        throw new UpdateException("An unknown error occurred while updating user data. Please contact your system administrator");
    }
}

3. Write and execute unit tests in UserServiceTests.

@Test
public void changePassword() {
    try {
        Integer uid = 5;
        String username = "lower";
        String oldPassword = "123456";
        String newPassword = "888888";
        userService.changePassword(uid, username, oldPassword, newPassword);
        System.out.println("Password modified successfully!");
    } catch (ServiceException e) {
        System.out.println("Password modification failed!" + e.getClass().getSimpleName());
        System.out.println(e.getMessage());
    }
}

3 user - modify password - controller

3.1 handling exceptions

A new UpdateException exception is thrown in the user's password modification business, which needs to be handled in the BaseController class.

@ExceptionHandler(ServiceException.class)
public JsonResult<Void> handleException(Throwable e) {
    JsonResult<Void> result = new JsonResult<Void>(e);
    if (e instanceof UsernameDuplicateException) {
        result.setState(4000);
    } else if (e instanceof UserNotFoundException) {
        result.setState(4001);
    } else if (e instanceof PasswordNotMatchException) {
        result.setState(4002);
    } else if (e instanceof InsertException) {
        result.setState(5000);
    } else if (e instanceof UpdateException) {
        result.setState(5001);
    }
    return result;
}

3.2 design request

Design the request submitted by the user and the way of response.

Request path: / users/change_password
 Request parameters: String oldPassword, String newPassword, HttpSession session
 Request type: POST
 Response result: jsonresult < void >

3.3 processing requests

1. Add the ChangePassword (string oldpassword, string newpassword, httpsession) method to process the request in the UserController class.

@RequestMapping("change_password")
public JsonResult<Void> changePassword(String oldPassword, String newPassword, HttpSession session) {
    // Call session.getAttribute("") to get uid and username
    // Call the business object to modify the password
    // Return success
    
    return null;
}

2. The code that implements the password modification method in the UserController controller.

@RequestMapping("change_password")
public JsonResult<Void> changePassword(String oldPassword, String newPassword, HttpSession session) {
    // Call session.getAttribute("") to get uid and username
    Integer uid = getUidFromSession(session);
    String username = getUsernameFromSession(session);
    // Call the business object to modify the password
    iUserService.changePassword(uid, username, oldPassword, newPassword);
    // Return success
    return new JsonResult<Void>(OK);
}

3. Log in before accessing the project http://localhost:8080/users/change_password?oldPassword=xx&newPassword=xx Test.

4 user - modify password - front page

1. At the end of the body tag in the password.html page, add a script tag to write JavaScript programs.

<script type="text/javascript">
    $("#btn-change-password").click(function() {
        $.ajax({
            url: "/users/change_password",
            type: "POST",
            data: $("#form-change-password").serialize(),
            dataType: "json",
            success: function(json) {
                if (json.state == 200) {
                    alert("Modification succeeded!");
                } else {
                    alert("Modification failed!" + json.message);
                }
            }
        });
    });
</script>

2. Log in before accessing the project http://localhost:8080/web/password.html Page and change the password.

Problem: if the data cannot be transferred to the background normally, restart the system and IDEA development tool, and change the password after logging in.

3. Problem: when operating the front page, the user enters the password modification page and stays on the current page for a long time without any operation, which will cause the login information to expire. At this time, when you click the Modify button, you will still send a message to / users / change_ When password sends a request, it will be redirected to the login page by the interceptor. Because the whole process is handled asynchronously by the $. ajax() function, the redirection is also completed by the asynchronous task. Without any performance in the page, there will be the problem of "no response when the user clicks the button after the login information timeout".

Solution: you can supplement the configuration of the error attribute in $. ajax() on the password.html page. The value of the attribute is a callback function. This function will be called when the server does not respond to the status code normally, such as 302, 400, 404, 405, 500 and other status codes.

error: function (xhr) {
    alert("Your login information has expired, please login again! HTTP Response code:" + xhr.status);
    location.href = "login.html";
}

personal data

1 user profile persistence layer

1.1 planning SQL statements to be executed

1. The SQL statement to modify the user's personal data is roughly as follows:

UPDATE t_user SET phone=?, email=?, gender=?, modified_user=?, modified_time=? WHERE uid=?

2. Before modifying user data, when the user just opens the page of modifying data, the currently logged in user information should be displayed on the page. To display user data, you can:

SELECT * FROM t_user WHERE uid=?

explain:

1. The query function has been realized and does not need to be developed again;

2. Before modifying user data, you should also check whether the user data exists and whether it is marked as "deleted", which can also be realized through the above query.

1.2 interface and abstract method

Add the updateinfo byuid (user user) method in the UserMapper interface.

/**
 * Update user profile according to uid
 * @param user The object that encapsulates the user id and the new profile
 * @return Number of rows affected
 */
Integer updateInfoByUid(User user);

1.3 configuring SQL mapping

1. Configure the mapping of integer updateinfo byuid (user user) abstract method in UserMapper.xml.

<!-- according to uid Update user profile: Integer updateInfoByUid(User user) -->
<update id="updateInfoByUid">
    UPDATE
        t_user 
    SET
        <if test="phone != null">phone = #{phone},</if>
        <if test="email != null">email = #{email},</if>
        <if test="gender != null">gender = #{gender},</if>
        modified_user = #{modifiedUser},
        modified_time = #{modifiedTime}
    WHERE
        uid = #{uid}
</update>

2. Write and execute unit tests in UserMapperTests.

@Test
public void updateInfoByUid() {
    User user = new User();
    user.setUid(20);
    user.setPhone("17858802222");
    user.setEmail("admin@cy.com");
    user.setGender(1);
    user.setModifiedUser("system administrator");
    user.setModifiedTime(new Date());
    Integer rows = userMapper.updateInfoByUid(user);
    System.out.println("rows=" + rows);
}

2 user - Profile - business layer

2.1 planning exceptions

1. There are two functions for users to modify their personal data.

  • When the page is opened, the information of the currently logged in user is displayed;

  • The user's information is updated when the Modify button is clicked.

2. For the information of the currently logged in user displayed when opening the page, the page may not be displayed correctly because the user data does not exist and the user is marked as deleted. A UserNotFoundException exception is thrown.

3. For updating the user's information when clicking the Modify button, you still need to check whether the user data exists and whether the user is marked as "deleted" before modifying the data, then a UserNotFoundException exception may be thrown. In addition, UpdateException may be thrown during data modification.

2.2 interfaces and abstract methods

Add two abstract methods in IUserService interface, corresponding to the above two functions respectively.

/**
 * Get the information of the currently logged in user
 * @param uid id of the currently logged in user
 * @return Information of the currently logged in user
 */
User getByUid(Integer uid);
​
/**
 * Modify user data
 * @param uid id of the currently logged in user
 * @param username Currently logged in user name
 * @param user User's new data
 */
void changeInfo(Integer uid, String username, User user);

2.3 implementing abstract methods

1. Implement the above two abstract methods getByUid(Integer uid) and changeInfo(Integer uid, String username, User user) in the UserServiceImpl implementation class.

@Override
public User getByUid(Integer uid) {
    // Call the findByUid() method of userMapper to query user data according to the parameter uid
    // Judge whether the query result is null
    // Yes: a UserNotFoundException exception is thrown
​
    // Judge whether isDelete in the query result is 1
    // Yes: a UserNotFoundException exception is thrown
​
    // Create a new User object
    // Encapsulate the username/phone/email/gender in the above query results into a new User object
​
    // Returns a new User object
    return null;
}
​
@Override
public void changeInfo(Integer uid, String username, User user) {
    // Call the findByUid() method of userMapper to query user data according to the parameter uid
    // Judge whether the query result is null
    // Yes: a UserNotFoundException exception is thrown
​
    // Judge whether isDelete in the query result is 1
    // Yes: a UserNotFoundException exception is thrown
​
    // Complete data to parameter user: uid
    // Complete data in parameter user: modifiedUser(username)
    // Complete data in parameter user: modifiedTime(new Date())
    // Call the updateinfo byuid (user user) method of userMapper to perform the modification and obtain the return value
    // Judge whether the number of affected rows returned above is not 1
    // Yes: an UpdateException exception is thrown
    
}

2. Specific code implementation of getbyuid (integer uid) and changeInfo(Integer uid, String username, User user) methods.

@Override
public User getByUid(Integer uid) {
    // Call the findByUid() method of userMapper to query user data according to the parameter uid
    User result = userMapper.findByUid(uid);
    // Judge whether the query result is null
    if (result == null) {
        // Yes: a UserNotFoundException exception is thrown
        throw new UserNotFoundException("User data does not exist");
    }
 
    // Judge whether isDelete in the query result is 1
    if (result.getIsDelete().equals(1)) {
        // Yes: a UserNotFoundException exception is thrown
        throw new UserNotFoundException("User data does not exist");
    }
​
    // Create a new User object
    User user = new User();
    // Encapsulate the username/phone/email/gender in the above query results into a new User object
    user.setUsername(result.getUsername());
    user.setPhone(result.getPhone());
    user.setEmail(result.getEmail());
    user.setGender(result.getGender());
    
    // Returns a new User object
    return user;
}
​
@Override
public void changeInfo(Integer uid, String username, User user) {
    // Call the findByUid() method of userMapper to query user data according to the parameter uid
    User result = userMapper.findByUid(uid);
    // Judge whether the query result is null
    if (result == null) {
        // Yes: a UserNotFoundException exception is thrown
        throw new UserNotFoundException("User data does not exist");
    }
​
    // Judge whether isDelete in the query result is 1
    if (result.getIsDelete().equals(1)) {
        // Yes: a UserNotFoundException exception is thrown
        throw new UserNotFoundException("User data does not exist");
    }
​
    // Complete data to parameter user: uid
    user.setUid(uid);
    // Complete data in parameter user: modifiedUser(username)
    user.setModifiedUser(username);
    // Complete data in parameter user: modifiedTime(new Date())
    user.setModifiedTime(new Date());
    // Call the updateinfo byuid (user user) method of userMapper to perform the modification and obtain the return value
    Integer rows = userMapper.updateInfoByUid(user);
    // Judge whether the number of affected rows returned above is not 1
    if (rows != 1) {
        // Yes: an UpdateException exception is thrown
        throw new UpdateException("An unknown error occurred while updating user data. Please contact your system administrator");
    }
}

3. Unit test in UserServiceTests class.

@Test
public void getByUid() {
    try {
        Integer uid = 20;
        User user = iUserService.getByUid(uid);
        System.out.println(user);
    } catch (ServiceException e) {
        System.out.println(e.getClass().getSimpleName());
        System.out.println(e.getMessage());
    }
}
​
@Test
public void changeInfo() {
    try {
        Integer uid = 20;
        String username = "Data Administrator";
        User user = new User();
        user.setPhone("15512328888");
        user.setEmail("admin03@cy.cn");
        user.setGender(2);
        iUserService.changeInfo(uid, username, user);
        System.out.println("OK.");
    } catch (ServiceException e) {
        System.out.println(e.getClass().getSimpleName());
        System.out.println(e.getMessage());
    }
}

3 user profile controller

3.1 handling exceptions

Note: no further development is required.

3.2 design request

1. Design the user to submit the request to display the currently logged in user information, and design the response method.

Request path: / users/get_by_uid
 Request parameter: HttpSession session
 Request type: GET
 Response result: jsonresult < user >

2. The design user submits and executes the request to modify user information, and designs the response method.

Request path: / users/change_info
 Request parameters: user, httpsession, session
 Request type: POST
 Response result: jsonresult < void >

3.3 processing requests

1. Process the request to obtain user information

1. Add the getByUid() method for processing the request in the UserController class and import the org.springframework.web.bind.annotation.GetMapping package.

@GetMapping("get_by_uid")
public JsonResult<User> getByUid(HttpSession session) {
    // Get uid from HttpSession object
    // Call the business object to get data
    // Response success and data
    return null;
}

2. The specific code in getbyuid (httpsession) method is implemented as.

@GetMapping("get_by_uid")
public JsonResult<User> getByUid(HttpSession session) {
    // Get uid from HttpSession object
    Integer uid = getUidFromSession(session);
    // Call the business object to get data
    User data = userService.getByUid(uid);
    // Response success and data
    return new JsonResult<User>(OK, data);
}

3. Start the project after completion, open the browser, log in first, and then visit http://localhost:8080/users/get_by_uid Request testing.

2. Process the request to modify the user's personal information

1. Add the changeinfo (user user, httpsession) method to handle the request in the UserController class.

@RequestMapping("change_info")
public JsonResult<Void> changeInfo(User user, HttpSession session) {
    // Get uid and username from HttpSession object
    // Call the business object to modify user data
    // Response successful
    return null;
}

2. The specific code in the changeinfo (user, httpsession) method is implemented as.

@RequestMapping("change_info")
public JsonResult<Void> changeInfo(User user, HttpSession session) {
    // Get uid and username from HttpSession object
    Integer uid = getUidFromSession(session);
    String username = getUsernameFromSession(session);
    // Call the business object to modify user data
    userService.changeInfo(uid, username, user);
    // Response successful
    return new JsonResult<Void>(OK);
}

3. Start the project after completion, open the browser, log in first, and then visit http://localhost:8080/users/change_info?phone=17858800000&email=admin07@cy.com&gender=1 Test.

4 user profile front page

1. At the end of the body tag in the userdata.html page, add a script tag to write JavaScript programs.

<script type="text/javascript">
    $(document).ready(function() {
        $.ajax({
            url: "/users/get_by_uid",
            type: "GET",
            dataType: "json",
            success: function(json) {
                if (json.state == 200) {
                    console.log("username=" + json.data.username);
                    console.log("phone=" + json.data.phone);
                    console.log("email=" + json.data.email);
                    console.log("gender=" + json.data.gender);
​
                    $("#username").val(json.data.username);
                    $("#phone").val(json.data.phone);
                    $("#email").val(json.data.email);
​
                    let radio = json.data.gender == 0 ? $("#gender-female") : $("#gender-male");
                    radio.prop("checked", "checked");
                } else {
                    alert("Failed to get user information!" + json.message);
                }
            }
        });
    });
​
    $("#btn-change-info").click(function() {
        $.ajax({
            url: "/users/change_info",
            type: "POST",
            data: $("#form-change-info").serialize(),
            dataType: "json",
            success: function(json) {
                if (json.state == 200) {
                    alert("Modification succeeded!");
                    location.href = "login.html";
                } else {
                    alert("Modification failed!" + json.message);
                }
            },
            error: function(xhr) {
                alert("Your login information has expired, please login again! HTTP Response code:" + xhr.status);
                location.href = "login.html";
            }
        });
    });
</script>

2. Start the project after completion, open the browser, log in first, and then visit http://localhost:8080/web/userdata.html Page and test the modification of user's personal data.

Posted by el_quijote on Thu, 18 Nov 2021 06:57:11 -0800