SSM整合
一、跨域访问
概述
根据浏览器的同源策略,不同服务器之间是不能访问的,否则服务器不安全
只有加了相互信任的域才能狗进行访问。
应用
被访问的目标资源需要加入访问我的链接的信任域;例如,A访问B;在B处设置A可以访问我
@CrossOrigin("http://localhost:8080") //允许此域发请求访问
public class UserController {
//...
}
Ajax访问时,需要进行配置:
$("#btn").click(function () {
$.ajax({
type: "POST",
url: "http://localhost:8081/hello1",
xhrFields: {
// 跨域携带cookie
withCredentials: true
}
});
})
注意事项
1.需要两个工程,一个设置8081; 另一个设置8080端口;都配置SpringMVC
2.两个工程测试springMVC目标handler成功
3.必须处理静态资源的访问:<mvc:default-servlet-handler />
二、SSM整合
DAO的SSM
先进行DAO测试,先结合DAO与mybatis进行处理。
Spring核心库的配置:
<!-- 加载配置文件 -->
<context:property-placeholder location="classpath:db.properties"></context:property-placeholder>
<!-- 产生数据源的bean,将加载的数据库驱动注入 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!-- sqlSessionFactory工厂bean的产生;里面配置了数据源,注册mapper,别名,分页插件-->
<bean class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="mapperLocations">
<list>
<value>classpath:mapper/*.xml</value>
</list>
</property>
<property name="typeAliasesPackage" value="com.qf.entity"></property>
<!-- spring容器配置 类似于ref属性引入bean对象 -->
<property name="plugins">
<bean class="com.github.pagehelper.PageInterceptor"></bean>
</property>
</bean>
<!-- 通过扫描器方式创建接口目录中的bean -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 产生dao的bean对象,id为接口首字母小写 -->
<property name="basePackage" value="com.qf.dao"></property>
</bean>
<!-- 注解扫描 -->
<context:component-scan base-package="com.qf"></context:component-scan>
使用spring单元测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:bean/bean-*.xml")
public class SpringTest { //产生当前类的bean
@Resource
private UserDao userDao;
@Test
public void daoTest(){
List<User> list = userDao.selectUsers();
System.out.println(list);
}
}
SSM测试
完成springMVC配置:
配置web.xml:
<servlet>
<servlet-name>mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param><!-- 初始化springMVC的配置 -->
<param-name>contextConfigLocation</param-name>
<param-value>classpath:mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>mvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 通过监听器用于加载spring的工厂 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 加载spring容器 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:bean/bean-*.xml</param-value>
</context-param>
mvc.xml的配置:
<!-- 扫描控制层注解 -->
<context:component-scan base-package="com.qf.controller"></context:component-scan>
<!-- 开启springMVC的注解驱动 -->
<mvc:annotation-driven></mvc:annotation-driven>
<!-- 静态访问处理 -->
<mvc:default-servlet-handler/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
</bean>
控制层测试:
@Controller
@RequestMapping("/user")
public class UserController {
@Resource
private UserService userService;
@RequestMapping("/users")
public String users(HttpServletRequest request){
System.out.println("展示数据...");
List<User> list = userService.selectUsers();
request.setAttribute("list",list);
return "show";
}
}
事务配置
分离spring容器用于配置事务。bean-tx.xml
<!-- 事务管理器bean -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 事务的增强,管理事务管理器 -->
<tx:advice id="tx" transaction-manager="txManager">
<tx:attributes>
<tx:method name="select*" propagation="SUPPORTS"/>
<tx:method name="add*" rollback-for="Exception" />
<tx:method name="delete*" rollback-for="Exception" />
<tx:method name="update*" rollback-for="Exception" />
</tx:attributes>
</tx:advice>
<!-- 切点与增强绑定,形成切面 -->
<aop:config>
<aop:pointcut id="po" expression="execution(* com.qf.service.*.*(..))"/>
<aop:advisor advice-ref="tx" pointcut-ref="po"></aop:advisor>
</aop:config>
三、功能与优化
细节
- 扫描冲突问题
mvc容器与spring容器的注解扫描有重合的地方,容易出现接口污染;所以需要调整成如下情况:
mvc容器只负责com.qf.controller的扫描,其它的不扫
spring容器负责扫描com.qf中除了controller以为的其它注解
<context:component-scan base-package="com.qf">
<!-- spring容器中, 除了controller包,其它的都扫描 -->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
容器调用
DispatcherServlet 启动springMVC容器,负责产生控制层的组件
ContextLoaderListener启动spring容器,负责产生除控制层以外的组件
父子关系
springMVC是spring的子容器,所以springMVC是spring的扩展与延申
分页
导入分页插件,及配置分页插件bean,在业务层封装分页实体
@Override
public PageInfo<User> selectPage(String pageNum, String pageSize) {
int pnum = 1;
int psize = 4;
if(pageNum!=null){
pnum = Integer.parseInt(pageNum);
}
if(pageSize!=null){
psize = Integer.parseInt(pageSize);
}
PageHelper.startPage(pnum,psize); //分页设置
List<User> list = userDao.selectUsers();
return new PageInfo<>(list); //返回封装的Page实体
}
控制层获取分页参数
@RequestMapping("/pages")
public String pages(HttpServletRequest request){
System.out.println("展示分页...");
String pageNum = request.getParameter("pageNum");
String pageSize = request.getParameter("pageSize");
PageInfo<User> pageInfo = userService.selectPage(pageNum,pageSize);
System.out.println("分页:"+pageInfo);
request.setAttribute("p",pageInfo);
return "show";
}
前端显示分页数据
<table border="1">
<tr>
<td>ID号</td>
<td>姓名</td>
<td>密码</td>
<td>性别</td>
<td>操作</td>
</tr>
<c:forEach items="${p.list}" var="u">
<tr>
<td>${u.id}</td>
<td>${u.name}</td>
<td>${u.password}</td>
<td>${u.sex}</td>
<td><a href="#">删除</a> |
<a href="#">修改</a>
</td>
</tr>
</c:forEach>
</table>
<a href="/user/pages?pageNum=1&pageSize=4">首页</a>
<c:if test="${p.hasPreviousPage}">
<a href="/user/pages?pageNum=${p.pageNum-1}&pageSize=4">上一页</a>
</c:if>
<c:if test="${p.hasNextPage}">
<a href="/user/pages?pageNum=${p.pageNum+1}&pageSize=4">下一页</a>
</c:if>
<a href="/user/pages?pageNum=${p.pages}&pageSize=4">尾页</a>
共${p.pageNum}/${p.pages}页
删除
DML的功能的事务操作,在SSM整合中,都通过AOP方式注入了,所以使用非常方便,只关注核心删除功能.
<a href="/user/delete/${u.id}">删除</a>
//控制层进行删除功能操作
@RequestMapping("/delete/{id}")
public String delete(@PathVariable Integer id){
int res = userService.deleteById(id); //根据id删除
System.out.println("删除:"+res);
return "redirect:/user/pages";
}
四、总结与作业
总结
1.跨域访问
如何跨域,怎么设置的,环境搭建过程
2.SSM整合(重点)
DAO的SSM、SSM整合测试,事务应用
3.功能的优化
优化细节、分页功能-分页插件、删除
作业
1.完成SSM修改功能