该成功案例是ssm框架下的学生成绩管理系统的一小部分,登录身份判断模块。
大致流程:页面请求----controller层接受请求----controller层调用service层----service层调用dao层----dao层实现----返回结果跳转页面。
一、页面请求 主要问题是怎么让这个请求连接到具体的方法。
首先在登录页面,输入账号密码后点击登录,页面发送了如下请求。请求风格restful。
二、controller层接受请求 主要问题是怎么让这个请求连接到具体的方法。
通过这个请求可以得知,如果想要响应这个请求,需要 “/login” 和 “/getAuthority” 这两个映射。
//controller层代码
@Controller
@RequestMapping("/login")
public class LoginController {
@Autowired
@Qualifier("teacherServiceImpl")
private TeacherService teacherService;
@RequestMapping("/getAuthority")
public String getLoginId(Model model, @RequestParam String id, @RequestParam String password){
System.out.println(id+" "+password);
String trueId = Id.idBefore(id);
String au = id.substring(0,1);
if(au.equals("1")){//学生
}else if(au.equals("2")){//教师
Teacher teacher = teacherService.login(trueId,password);
if(teacher!=null){
return "forward:/teacher/test";
}
}else if(au.equals("3")){//admin
}
return "";
}
在controller层,通过注解 @RequestMapping("/login")和@RequestMapping("/getAuthority")可以获得两个映射。而要想使这两个注解生效,需要
1.启动注解驱动 ,2.使注解能被扫描到。
在spring配置文件中写上<mvc:annotation-driven/>
来启动注解;
在spring配置文件中写上<context:component-scan base-package="com.controller"/>
来扫描com.controller包下的所有写了@Controller的类,所以还需要在类名上边写上@Controller注解。
则现阶段部分流程是:
1.启动注解;
2.添加包扫描配置,3.给需要的类(LoginController)添加@Controller,将类标注为spring中的bean;
4.给上一条的类添加@RequestMapping("/login"),获得总的映射;
5.给类中的方法添加注解@RequestMapping("/getAuthority"),获得第二个映射。
至此页面发送的请求就可以被正确接收到了;
三、controller层调用service层
我们在LoginController类中只能调用service层的类。于是就看到我们需要teacherService这个对象。
LoginController类中相关teacherService的语句一共有如下。
...
@Autowired
@Qualifier("teacherServiceImpl")
private TeacherService teacherService;
...
...
...
Teacher teacher = teacherService.login(trueId,password);
...
代码中teacherService对象并不是手写new出来的,而是跟@Autowired 和@Qualifier(“teacherServiceImpl”)这两个注解有关(这两个注解和@Resource(name=“teacherServiceImpl”)可以互换)。
这两个注解用于bean的装配(即bean的依赖注入)。
想要装配bean,得先有bean。所以,我们需要通过下面代码来(显式的)配置TeacherServiceImpl类的bean(也可以通过注解,给类加上@Service,在配置文件写上注解驱动和包扫描)。
<bean id="teacherServiceImpl" class="com.service.TeacherServiceImpl">
<property name="teacherMapper" ref="teacherMapper"/>
</bean>
那么有了bean,有了它的依赖注入,我们就可以使用teacherService对象的方法了。
四、service层调用dao层
这一步主角是service,我们来看看service层的代码。
public class TeacherServiceImpl implements TeacherService{
@Autowired
private TeacherMapper teacherMapper;
@Override
public Teacher login(String id, String pas) {
return teacherMapper.login(id,pas);
}
}
按照三层架构的规则,service层调用dao层对象teacherMapper(因为用了mybatis所以dao层起名都带mapper)。那么就又涉及依赖注入的问题了。
teacherMapper是这个类的私有属性,通过@Autowired添加依赖,依赖关系的另一方自然要在配置文件中配置(也可使用注解)
<bean id="teacherServiceImpl" class="com.service.TeacherServiceImpl">
</bean>
五、dao层实现
调用teacherMapper的login方法后,就要到mybatis的部分。
要连数据库,数据源配置必不可少。在spring配置文件中写如下代码(用spring代替mybatis配置数据源)。
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" >
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost/shixun?characterEncoding=utf8&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true&useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>
mybatis需要sqlSession获取mapper, 而SqlSession需要SqlSessionFactory来获取。
所以需要先在spring配置文件中先配置SqlSessionFactory的bean。
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!-- 绑定mybatis文件。-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:com/dao/*.xml"/>
</bean>
接着就可以获取mybatis的映射器mapper。本代码使用MapperScannerConfigurer类。该类可以自动扫描包下的类,spring通过包中的接口自动生成映射器,就不用了我们在手写mapper的bean了。
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<property name="basePackage" value="com.dao"/>
</bean>
6、返回结果跳转页面
获取到映射器 ,就可以正确获得dao层,service层的返回值了。这时再来看controller层的代码。当返回结果不为null时,则controller层方法通过return的字符串来寻找跳转页面的位置或者请求转发的位置。
@Controller
@RequestMapping("/login")
public class LoginController {
@Autowired
@Qualifier("teacherServiceImpl")
private TeacherService teacherService;
@RequestMapping("/getAuthority")
public String getLoginId(Model model, @RequestParam String id, @RequestParam String password){
System.out.println(id+" "+password);
String trueId = Id.idBefore(id);
String au = id.substring(0,1);
if(au.equals("1")){//学生
}else if(au.equals("2")){//教师
Teacher teacher = teacherService.login(trueId,password);
if(teacher!=null){
return "forward:/teacher/test";
}
}else if(au.equals("3")){//admin
}
return "";
}
这时在spring中配置视图解析器,写上前缀和后缀,这样我们controller层就只用写页面的名字就可以了。如果要转发到另一个controller,在return后写 “forward:/******”.
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="suffix" value=".jsp"/>
<property name="prefix" value="/jsp/"/>
</bean>
本文是博主学习ssm框架第一次整合的学习记录,主要目的是通过分析成功运行的代码来理解spring中的各种配置。如有错误欢迎指正,互相进步。