整合过程参照传智播客的mybatis+springmvc,感谢传智!
案例下载:http://download.csdn.net/detail/changerzhuo_319/9730857
终于还是把spring, springmvc, mybatis整合起来了,记录下整合出的问题。使用的mybatis的mapper开发, 所以在service层控制事务
1.整合spring和mybatis时, 在测试中使用实现类UserServiceImpl接收从容器中获取的bean,报类型转换异常。如果使用UserService接口来接收就是正常的, 后来发现是因为使用aop整合事务造成的,查资料比较靠谱的说法是, 使用aop获取的bean是jdk的代理对象(如果类实现了接口,spring会使用jdk代理, 否则使用cglib代理)的接口类型, 所以不能使用接口的实现类接收。 如果不实用aop整合事务, 而是使用事务的注解方式,则使用接口或者实现类都是可以接收从容器中获取的bean。
private UserServiceImpl userServiceImpl;
@Before
public void Init() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
userServiceImpl = (UserServiceImpl) context.getBean("userServiceImpl");
}
2. 在获取mapper对象时,有一个疑问,首先我没有给mapper加注解将其纳入到spring容器中,然后也没有在xml中配置mapper,但是却可以从容器中获取到mapper对象,
后来看资料是因为使用了MapperScannerConfigurer进行mapper扫描,该扫描会将mapper接口纳入spring容器中,id为bean的name为首字母小写类名
private UserMapper userMapper = null;
@Before
public void Init() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
userMapper = (UserMapper) context.getBean("userMapper");
}
<!-- mybatis的mapper.xml文件扫描加载, 同时将mapper接口纳入spring容器中,bean的name为首字母小写接口名 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 指定扫描的包名 如果扫描多个包,每个包中间使用半角逗号分隔 -->
<property name="basePackage" value="com.changez.sm.mapper"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
3. ssm整合完成后,项目启动时报错不能加载sqlMapperConfig.xml文件, 当时对于configLocation的值直接写的是sqlMapConfig.xml, 再前面加上classpath就可以了, 正确的配置如下:
<!-- mybatis操作数据库的sqlSessinFactory的装配 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 加载mybatis的配置文件 -->
<property name="configLocation" value="classpath:sqlMapConfig.xml" />
<!-- 数据源 -->
<property name="dataSource" ref="dataSource" />
</bean>
4. 解决post中文乱码, 在web.xml文件中添加一下内容:
<!-- post中文乱码 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
5.静态资源过滤,使用tomcat的默认行为,或者使用springmvc的释放配置:
<!-- 方式一:在web.xml文件中添加释放静态资源配置, 可以不使用springmvc释放资源 -->
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.js</url-pattern>
<url-pattern>*.css</url-pattern>
<url-pattern>*.html</url-pattern>
<url-pattern>*.png</url-pattern>
<url-pattern>*.jpg</url-pattern>
</servlet-mapping>
<!-- 方式二:在applicationContext.xml中使用springmvc的静态资源释放配置,为了方便管理可以讲所有的静态资源统一放到一个文件中 -->
<mvc:resources location="/sources/" mapping="/sources/**"/>
6. 在controller中重定向或转发到其他页面、controller中。重定向、转发时,controller中的返回值不会拼接视图解析器配置的前缀和后缀。
跳转目标结果,如果以根目录("/")开始则跳转目标地址为:只使用自己配置的; 如果不是以根目录开始,则跳转目标地址为:类名上配置的请求路径+自己写的请求路径
public String login(User user) {
user = userService.login(user);
//--->跳转到页面
// 重定向到页面(不能重定向到web-inf下面,且不会携带参数),
// 如果不以“/”开头,默认为当前controller类上的@RequestMapping("")的值+重定向的值
// 访问的是webContent下的redirectSuccess.jsp页面
// return user != null ? "redirect:/redirectSuccess.jsp" : "redirect:/redirectFail.jsp";
// 访问的是webContent下的user/test下的redirectSuccess.jsp页面
// return user != null ? "redirect:redirectSuccess.jsp" : "redirect:redirectFail.jsp";
// 转发到页面, 携带参数, 浏览器地址栏不变化
// return user != null ? "forward:/forwardSuccess.jsp" : "forward:/forwardFail.jsp";
// 转发到web-inf下的页面
// return user != null ? "forward:/WEB-INF/jsp/web_forwardSuccess.jsp" : "forward:/WEB-INF/jsp/web_forwardFail.jsp";
//--->跳转到controller
// 跳转当前controller中的其他方法
// return "forward:redirectFunc";
//跳转到其他controller中的方法
return "forward:/user/test/redirectFunc";
}
7.使用@ResponseBody注解的问题
@ResponseBody注解我知道的主要作用是将返回结果格式化为json格式的数据。 最开始我是要跳转页面的, 不小心加了@ResponseBody注解, 页面始终没有跳转到预期的地方, 去掉该注解就可以了。测试后发现该注解会只会将返回结果格式化为json格式数据,并把json数据返回到当前执行方法的完整访问mapping路径上(类名上的mapping+方法上的mapping)。