1 ResponseBody 和 RequestBody
1.1 简介
- @ResponseBody 把后台 pojo 转换 json 对象,返回到页面;
- @RequestBody 接受前台 json 数据,把 json 数据自动封装 javaBean
1.2 使用
案例:请求和相应都是 json 数据
第一步:导入 json 的 jar
第二步:
添加个json转换器
配置文件
第三步:写个 jsp 页面,提交 json 请求参数
第四步:后台处理
注意学生类一定要提供无参的构造方法
案例:只有响应 json 数据
第一步:表单
第二步:后台处理
2 SpringMVC 多视图
多视图是一个方法可以返回json/xml等格式的数据
第一步:导入 xml 格式支持的 jar 包
第二步:配置支持多视图
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<!-- 配置支持媒体类型 -->
<property name="contentNegotiationManager">
<bean class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="mediaTypes">
<map>
<entry key="json" value="application/json"></entry>
<entry key="xml" value="application/xml"></entry>
</map>
</property>
</bean>
</property>
<!-- 指定默认视图 -->
<property name="defaultViews">
<!-- 支持多个视图 -->
<list>
<!-- 对josn格式视图支持 -->
<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"/>
<!-- xml格式视图支持 -->
<bean class="org.springframework.web.servlet.view.xml.MarshallingView">
<constructor-arg>
<bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound">
<list>
<value>com.gyf.backoffice.domain.Student</value>
</list>
</property>
</bean>
</constructor-arg>
</bean>
</list>
</property>
</bean>
第三步:控制器提供一个接口
注意学生对象需要声明一个注解
第四步:测试
3 eclipse 安装 spring 提示插件
3.1 在应用市场搜索 spring tools
点击Eclipse的Help 下的 Eclipse Marketplace搜索spring tools,然后红色不用勾选,点下一步安装插件
3.2 依次点开菜单‘XML -> XMLFiles -> Editor -> Content Assist’配置
如下图:
3.3 使用下面两种文件打开配置文件
在xml中使用. + /就会有类提示
4 SSM 整合
Spring + SpringMVC + Mybatis整合
4.1 导入jar包
- Spring+ SpringMVC + MyBatis + Mybatis-spring整合包
- AOP联盟+织入 + c3p0 数据库连接池 + MySQL连接驱动 + jstl
4.2 创建一个 SpringMVC 文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
<!-- 1.配置注解扫描位置 -->
<context:component-scan base-package="com.gyf.backoffice.web.controller" />
<!-- 2.配置注解处理映射-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
<!--3.配置适配器-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
</bean>
<!-- 4.配置springmvc视图解析器 视图解析器解析的视频路径为:前缀 + 后缀 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
4.3 在 web.xml 添加 springmvc 配置
这次我们更改默认的springmvc配置文件路径
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 3.0的springmvc 默认加载WEB-INF下的dispatcher-servlet.xml文件 3.2的springmvc 加载DispatcherServlet-servlet.xml文件 -->
<init-param>
<!-- 修改黑底springmvc加载的配置文件路径 -->
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
4.4 先配置一个 Controller 跑出一个页面
4.5 通过MyBatis的逆向工程生成JavaBean/Mapper
把生成的文件导入当到项目,步骤不记得可以参数MyBatis的博客
4.6 修改 ItemsMapper.java 和 ItemsMapper.xml
4.7 定义 Service 层 接口并实现
4.8 配置 SqlMappingConfig.xml、mybatis
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 别名配置 -->
<typeAliases>
<!-- 批量配置别名:指定批量定义别名的类包,别名为类名(首字母大小写都可) -->
<package name="com.gyf.backoffice.domain"/>
</typeAliases>
<mappers>
<!-- 批量加载映射文件 -->
<package name="com.gyf.backoffice.mapper"/>
</mappers>
</configuration>
4.9 创建 spring 的 applicationContext.xml
配置数据源和mybaties的session工厂
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
</beans>
4.10 配置 c3p0 数据源和 mybatis 的会话工厂
<!-- 1.加载db配置文件 -->
<context:property-placeholder location="classpath:db.properties"/>
<!-- 2.配置c3p0数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="maxPoolSize" value="30"/>
<property name="minPoolSize" value="2"/>
</bean>
<!-- 3.让spring管理sqlsessionFactory -->
<bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!-- 指定配置文件位置 -->
<property name="configLocation" value="classpath:SqlMapConfig.xml"/>
</bean>
<!-- 4.配置mapper扫描器.批量扫描创建代理对象 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.gyf.backoffice.mapper"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactoryBean"/>
</bean>
db文件内容
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=123456
4.11 Web.xml 配置 spring 容器
<!-- spring的配置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
4.12 添加 bean 的注解装配
<!-- 配置扫描注解 -->
<context:component-scan base-package="com.gyf.backoffice"/>
4.13 ItemsService
4.14 ItemsController
4.15 事务配置
Spring中Propagation类的事务属性详解:
- REQUIRED:支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
- SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。
- MANDATORY:支持当前事务,如果当前没有事务,就抛出异常。
- REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。
- NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
- NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
- NESTED:支持当前事务,如果当前事务存在,则执行一个嵌套事务,如果当前没有事务,就新建一个事务
<!-- 6.事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 6.通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 传播行为 -->
<tx:method name="save*" propagation="REQUIRED"/>
<tx:method name="insert*" propagation="REQUIRED"/>
<tx:method name="delete*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="find*" propagation="SUPPORTS" read-only="true"/>
<tx:method name="get*" propagation="SUPPORTS" read-only="true"/>
</tx:attributes>
</tx:advice>
<!-- 7. 切面 -->
<aop:config>
<aop:advisor advice-ref="txAdvice"
pointcut="execution(* com.gyf.backoffice.service.*.*(..))"/>
</aop:config>
<!-- 5.配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 6.开启事务注解-->
<tx:annotation-driven></tx:annotation-driven>
4.16 添加一个保存方法测试事务
- service
- controller
5 增删改查任务
5.1 显示商品数据
- Controller.java
- Views/items/list.jsp
5.2 删除商品
- Service
- Controller
5.3 显示编辑商品页面
- Controller
- Edit.jsp
5.4 更新商品
需要在页面中隐藏一个input标签存id
乱码,在web.xml配置
<!-- 配置编码过滤器 -->
<filter>
<filter-name>EncodingFilter</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>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
- controller
- Service:需要改下逻辑
6 文件上传
6.1 导包
6.2 Springmvc.xml配置支持文件上传
6.3 html/js
6.4 后台
@Controller
@RequestMapping("upload")
public class UploadController {
@RequestMapping("itemsPic")
public void itemsPic(HttpServletRequest request,String fileName, PrintWriter writer) throws Exception{
MultipartHttpServletRequest mulRequest = (MultipartHttpServletRequest) request;
//通过字段名获取文件数据
MultipartFile file1 = mulRequest.getFile(fileName);
System.out.println(fileName + ":上传文件大小 " + file1.getSize());
//格式化文件名
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
String saveName = sdf.format(new Date());
Random rd = new Random();
for(int i=0;i<3;i++){
saveName += rd.nextInt(10);//添加三个随机数
}
//文件后缀名
String suffix = file1.getOriginalFilename().split("\\.")[1];
String saveFileName = saveName + "." + suffix;
//文件保存目录
String dir = request.getServletContext().getRealPath("/upload");
File dirFile = new File(dir);
if(dirFile.exists() == false)dirFile.mkdirs();
//文件保存路径
String relativePath = "/upload/" + saveFileName;
String totalPath = request.getServletContext().getRealPath(relativePath);
System.out.println(totalPath);
File newFile = new File(totalPath);
//保存
FileCopyUtils.copy(file1.getInputStream(), new FileOutputStream(newFile));
Thread.sleep(2000);
//file1.transferTo(newFile);
//返回一个相对路径 相对路径和全路径
String serverIp = "http://127.0.0.1:8080" + request.getServletContext().getContextPath();
String respJson = "{\"imgUrl\":\"" + serverIp + relativePath+"\"}";
writer.write(respJson);
}
}
7 Oscache 页面缓存
7.1 页面缓存测试
7.1.1 导包
7.1.2 测试
创建一个index.jsp页面,使用时间来测试
7.1.3 知识点
缓存数据结构:map,key存储浏览器访问url,如果访问2个url不一致,缓存肯定变化。
缓存的作用域
缓存默认存储在application域当中,可更改缓存数据。
这样,不同浏览器访问时,缓存时间是不一样的,如果是application,不同浏览器访问同一个路径时,时间是一样的
缓存刷新时间
固定存储的 Key
缓存持久化
创建oscache.properties这个配置文件必须在classpath下面:
内容
cache.memory=false
cache.persistence.class=com.opensymphony.oscache.plugins.diskpersistence.DiskPersistenceListener
cache.path=C:\\test
访问路径后会在test的application中创建缓存文件
8 Oscache 整合 ssm 项目
约定:商品页面访问量特别大,给商品页面缓存。Items路径下所有请求都缓存。
在 web.xml 中配置页面缓存
<!-- 配置页面缓存 -->
<filter>
<filter-name>oscache</filter-name>
<filter-class>com.opensymphony.oscache.web.filter.CacheFilter</filter-class>
<init-param>
<param-name>time</param-name>
<param-value>3600</param-value>
</init-param>
<init-param>
<param-name>scope</param-name>
<param-value>application</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>oscache</filter-name>
<url-pattern>/items/*</url-pattern>
</filter-mapping>
第一次访问Items下面的页面,控制器方法会执行,第一次就走缓存页面
如图,把持久化缓存加到项目中,缓存的数据是一个页面
cache.persistence.class=com.opensymphony.oscache.plugins.diskpersistence.DiskPersistenceListener
cache.path=C:\\test
9 SpringMVC 整合 freemarker
9.1 简介:freemark
FreeMarker是一款模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页、电子邮件、配置文件、源代码等)的通用工具。
- https://freemarker.apache.org/
- http://freemarker.foofun.cn
- 模型引擎框架还有:https://www.thymeleaf.org/
9.2 导包
9.3 SpringMVC 配置 freemark
<!-- 配置freemarker -->
<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="/WEB-INF/views" />
<property name="defaultEncoding" value="UTF-8"></property>
</bean>
<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<property name="contentType" value="text/html;charset=utf-8"/>
<property name="suffix" value=".ftl" />
</bean>
9.4 写一个 hello.ftl 模板
9.5 ItemsController
9.6 测试结果
数据就通过模板引擎生成了
9.7 list.jsp 改成 list.ftl
掌握freemark的两个表达工:
赋值
<#assign/>
遍历
<#list xxList as xx>
${item.createtime?string(“yyyy-MM-dd HH:mm:ss zzzz”)}
10 SpringMVC 的拦截器
Spring Web MVC 的处理器拦截器类似于Servlet 开发中的过滤器Filter,用于对处理器进行预处理和后处理。
10.1 登录拦截器
public class LoginInterceptor implements HandlerInterceptor{
//controller执行后且视图返回后调用此方法
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
System.out.println("返回视图前 后处理");
}
//controller执行后但未返回视图前调用此方法
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {
System.out.println("未返回视图前 后处理....");
}
// controller执行前调用此方法
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object obj) throws Exception {
// TODO Auto-generated method stub
System.out.println("预处理....");
//如果是登录页面则放行
if(request.getRequestURI().indexOf("login.do")>=0){
return true;
}
HttpSession session = request.getSession();
//如果用户已登录也放行
if(session.getAttribute("user")!=null){
return true;
}
//用户没有登录挑战到登录页面
request.getRequestDispatcher("/WEB-INF/views/login.jsp").forward(request, response);
return false;
}
}
10.2 登录控制器
10.3 登录界面
10.4 登录拦截器配置
总结拦截注意点:
- 拦截所有的请求,使用
/**
,有两个**
- 如果拦截的路径在项目不存在,直接报错