SpringMVC中如何实现Controller和Service层的正确交互

How to implemenet correct interaction between Controller and Service layer in Spring MVC

我使用 Spring MVC、Spring 安全和 Hibernate 设计了网络应用程序。 我有与服务层交互的控制器:

@Controller
@RequestMapping(value="/")
public class InitController {

    @Autowired
    private UserService userService;


    @Autowired
    private StudentService studentService;

    @InitBinder
    public void initBinder(WebDataBinder dataBinder){
        dataBinder.registerCustomEditor(String.class, "studentGroup", new StudentNameEditor());
    }

    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public ModelAndView getLoginForm(){
        return new ModelAndView("login");
    }

    @RequestMapping(value = "/registration.html",method = RequestMethod.GET)
    public ModelAndView getRegistrationForm(){
        return new ModelAndView("registration");
    }

    @RequestMapping(value = "/students.html",method = RequestMethod.GET)
    public ModelAndView getGroupForm(){
        return new ModelAndView("searchStudents");
    }


    @RequestMapping(value = "/getStudents.html",method = RequestMethod.POST)
    public ModelAndView getStudents(@Valid @ModelAttribute("student") Student student,
                                BindingResult result){
        if(result.hasErrors()){
            return new ModelAndView("searchStudents");
        }else{
            return studentService.getStudentOfGroup(student);
        }

    }

    @RequestMapping(value = "/registrationConfirm.html",method = RequestMethod.POST)
    public ModelAndView registration(@Valid @ModelAttribute("user") User user,
                                BindingResult result){
        if(result.hasErrors()){
            return new ModelAndView("registration");
        }else{
            User savedUser = userService.registerUser(user);
            if(Objects.isNull(savedUser)){
                ModelAndView modelAndView = new ModelAndView("login");
                modelAndView.addObject("resultRegistration", 
                                        "Success registration!");
                return modelAndView;
            }else{
                ModelAndView modelAndView = new ModelAndView("registration");
                modelAndView.addObject("resultRegistration", 
                                        "User with the same login or password is registered in system already");
                return modelAndView;
            }
        }
    }
}

服务层与DAO层交互:

@Transactional(propagation = Propagation.REQUIRES_NEW )
@Service("userService")
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDAO userDao;

    @Transactional(propagation = Propagation.REQUIRES_NEW )
    @Override
    public User registerUser(User user) {
        User userWithTheSameLogin = userDao.getUserByLogin(user.getUserLogin());
        if(!Objects.isNull(userWithTheSameLogin)){
            //if user with the same login registered already
            return userWithTheSameLogin;
        }else{
            User userWithTheSamePassword = userDao.getUserByEmail(user.getUserEmail());
            if(!Objects.isNull(userWithTheSamePassword)){
                //if user with the same email registered already
                return userWithTheSamePassword;
            }
            else{
                //if user's credentials are unique
                userDao.saveUser(user);
                return null;
            }
        }

    }
}

我是Service层的return用户,存在email或login时,保存成功时为null。

我认为简单的 returning 值 - 这是不好的,它不符合逻辑,也不明确。 请告诉我通知控制器有关保存用户结果的最佳方式。它是抛出异常并在控制器中捕获它们还是从服务层 returning 状态代码?请举例说明。我将不胜感激

我的建议是返回一个布尔值,其中 registerUser 如果用户可以注册则为真,否则为假:

@Transactional(propagation = Propagation.REQUIRES_NEW )
@Override
public boolean registerUser(User user) {
    User userWithTheSameLogin = userDao.getUserByLogin(user.getUserLogin());
    if(!Objects.isNull(userWithTheSameLogin)){
        //if user with the same login registered already
        return false;
    }
    User userWithTheSamePassword = userDao.getUserByEmail(user.getUserEmail());
    if(!Objects.isNull(userWithTheSamePassword)){
        //if user with the same email registered already
        return false;
    }
    //if user's credentials are unique
    userDao.saveUser(user);
    return true;
}

在您的控制器中,您将拥有:

@RequestMapping(value = "/registrationConfirm.html",method = RequestMethod.POST)
public ModelAndView registration(@Valid @ModelAttribute("user") User user,
                            BindingResult result){
    if(result.hasErrors()){
        return new ModelAndView("registration");
    }
    if(userService.registerUser(user)){
        ModelAndView modelAndView = new ModelAndView("login");
        modelAndView.addObject("resultRegistration", "Success registration!");
        return modelAndView;
    }
    //If the other cases didn't hold true, it means the registration failed
    ModelAndView modelAndView = new ModelAndView("registration");
    modelAndView.addObject("resultRegistration", 
        "User with the same login or password is registered in system already");
    return modelAndView;
}

这感觉更具可读性并且摆脱了空检查。希望这对你也有感觉 "better"。