This is the fourth day of my participation in the August More text Challenge. For details, see: August More Text Challenge

preface

The project encountered such a usage scenario, the login information of the user is saved by token. In the place where the login information is needed, the user Id needs to be obtained every time, but the user information needs to be obtained in the request method every time, so the code is repeated, redundant and low. Therefore, the attribute @ModelAttribute is thought of

Usage scenarios

Without @ModelAttribute you need to get the user information separately every time you request it

  String token = request.getAttribute("token").toString();
   User LoginUser = tokenService.decodeToken(token);
Copy the code

The code repeats have to be written separately each time,

So I came up with the idea to optimize the code and write a public method in the controller that needs user information, just fetching it directly every time

private User gerUserInfo(HttpServletRequest request){
        String token = request.getAttribute("token").toString();
        User LoginUser = tokenService.decodeToken(token);
        return LoginUser;
    }
Copy the code

Does this simplify the code a little bit, but it doesn’t make a big difference, or do I have to call this method in every request Controller that needs the user information, and repeat it if multiple controllers need to get the user information

Also think about inheritance, write a public controller called BaseController, inherit BaseController every time in the controller that needs user information and then call it

@RestController
public class BaseController {
    @Autowired
    private TokenService tokenService;
   

   private User gerUserInfo(HttpServletRequest request){
        String token = request.getAttribute("token").toString();
        User LoginUser = tokenService.decodeToken(token);
        returnLoginUser; }}Copy the code

This seems to be much simpler and more convenient than the previous two methods. We can directly inherit the call in the controller that needs to use user information, but it does not solve our problem. We still need to write repeated code to obtain user information in each controller separately. Not really!!

In fact, SpringBoot provides @ModelAttribute, which is an attribute that can be retrieved through parameter injection

Let’s adjust the above slightly as follows:

@RestController
public class BaseController {
    @Autowired
    private TokenService tokenService;
 

    @ModelAttribute
    public void userInfo(ModelMap modelMap, HttpServletRequest request) {
        String token = request.getAttribute("token").toString();
        User LoginUser = tokenService.decodeToken(token);
    
        modelMap.addAttribute("LoginUser", LoginUser);
        modelMap.addAttribute("userId", LoginUser.getUserId()); }}Copy the code

Then do the parameter mapping in the controller that needs to use the user information

@apioperation (value = "User is about to expire coupon info ",tags =" Coupon interface ")
    @GetMapping("/expiredCoupon")
    public List<Coupon> userExpiredCoupon(@ModelAttribute("userId") @ApiParam(hidden = true) String userId){
        return couponService.getUserExpiredCoupon(userId);
    }
Copy the code
@GetMapping("/info")
    @apiOperation (" Get user information ")
    public User getUseInfo(@ModelAttribute("LoginUser") User user) {
        return user;
    }
Copy the code

So the user information is injected directly into the Controller through the parameter, and we can use it directly in the request

@ModelAttributeBreak down

  1. The method annotated by @ModelAttribute executes the annotation above the method before each method of the controller executes, storing the object returned by the method in the Model, and the method is called before any other mapping method of the controller executes

  2. @ModelAttribute annotates the parameters of a method and gets the parameter @ModelAttribute(“LoginUser”) from the model. User The User parameter is derived from the Model attribute in the BaseControlleruserInfo() method

Refer to the summary of the @ModelAttribute annotation for more details