Springmvc第二天
回顾第一天课程内容:
1.JAVAEE体系结构
2.什么是springmvc?
* mvc设计模式
* springmvc框架原理
3.springmvc第一个程序案例
* 不是视图解析器
* 使用视图解析器
4.根据程序分析springmvc执行流程(画图)
5.处理器映射器
* 默认视图解析器(BeanNameUrlHandlerMapping)
* 集中配置处理器映射器(SimpleHandlerMapping)
* 类名处理器映射器(ClassNameHandlerMapping)
6.处理器适配器
* 默认使用的处理器适配器(SimpleControllerHandlerAdapt)
* 请求处理器适配器(HttpControllerHandlerAdapt)
7.控制器
* 普通控制器(继承接口Controller,HttpRequestHandler)
* 命令控制器(CommandController)
例子:跳转到添加页面,进行页面跳转,参数提交post请求
* 参数控制器(parameterizabled)
复习商务知识?
分析:源码执行流程?
8.注解开发
* 注解开发第一个程序
创建工程,导入jar文件,配置处理器映射器,配置处理器适配器,视图解析器
使用注解开发:添加,返回到成功页面进行回显,点击修改回到添加页面,初步理解参数传递。
* springmvc 与 struts2的区别?
注解:
* requestMapping
几种写法:
requestMapping("/index")
requestMapping(value="/index")
requestMapping(value="/index",method=RequestMethod.GET)
requestMapping(value="/index",method=RequestMethod.POST)
@RequestMapping(value="/toIndex",method={RequestMethod.GET,RequestMethod.POST})
requestMapping:根路径+子路径
* 使用get请求乱码解决?
配置tomcat编码
* 使用post请求乱码
在web.xml里面配置编码过滤器
* @ModelAttribute 在方法定义上使用 @ModelAttribute 注解:Spring MVC 在调用目标处理方法前,会先逐个调用在方法级上标注了@ModelAttribute 的方法
* url模版映射
最近比较火restfull软件风格架构。url模版映射就可以实现这种架构
url模版映射需要@RequestMapping和@PathVariable集合使用
* requestParam
* springmvc方法接受参数类型
* 基本类型参数
int long float double String boolean等等
* pojo类型:包装类型,javabean类型
* 数组类型
* 集合类型:List Map
* 重定向:redirect
* 本类进行
* 重定向到另一个类
* 转发:forward
* 本地转发
* 转发到另一个类
今日课程内容:
l Springmvc对json数据格式支持
l Springmvc多视图(页面)
l Ssm整合
l 文件上传(跨服务器上传)
l Oscache(页面缓存)
l Freemarker
l 拦截器
S
pringmvc对
json格式
支持
需求
l 直接传递json格式的数据,返回json格式数据。
传递json:js
返回json:ajax
Springmvc本身对json格式数据支持?
不支持,依赖josn格式的持久
Json格式插件:struts-json,jsonlib,fastJson
Springmvc:
页面请求的json格式数据:
需要把json格式数据转换javaBean:直接使用:@requestBody
返回javaBean:@responseBody把返回的javaBean转换成json
l 直接传递普通文本数据,返回json数据。
导入jar
整合jackson
在处理器适配器进行整合。
作用:
@RequestBody注解用于读取http请求的内容(字符串),通过springmvc提供的HttpMessageConverter接口将读到的内容转换为json、xml等格式的数据并绑定到controller方法的参数上。
本例子应用:
@RequestBody注解实现接收http请求的json数据,将json数据转换为java对象
页面(请求json,响应json)
接受json格式参数方法
返回格式
页面(请求普通数据,返回json)
http请求头,请求体:key=value&key=value.
后端代码接受pojo,返回json
返回效果
<mvc:annotation-driven />
注解映射器和注解适配器可以使用<mvc:annotation-driven />代替。
<mvc:annotation-driven />默认注册了注解映射器和注解适配器等bean。
如下:
以下配置可用<mvc:annotation-driven />代替
S
pringmvc
多视图
分析:springmvc支持json,xml,pdf,excel等等。
Springmvc支持xml视图:
Springmvc.xml配置jsp视图:
在springmvc.xml添加json视图,xml视图
Springmvc
<!-- springmvc多视图支持 -->
<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>
<!-- 指定json视图 -->
<bean
class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"></bean>
<!-- 指定xml视图支持 -->
<bean class="org.springframework.web.servlet.view.xml.MarshallingView">
<constructor-arg>
<bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<!-- 把User对象转换成xml视图展示页面 -->
<property name="classesToBeBound">
<list>
<value>cn.itcast.domain.User</value>
</list>
</property>
</bean>
</constructor-arg>
</bean>
</list>
</property>
</bean>
javaBean支持xml视图
方法
约定请求
如果返回json视图:扩展名必须json
http://localhost:8080/springmvc0926_day02_01/rest/user/multiView.json
如果返回xml视图:扩展名必须是xml
http://localhost:8080/springmvc0926_day02_01/rest/user/multiView.xml
约定:在rest目录下的所有请求支持多视图。
访问效果
S
sm整合
创建一个web工程,并导入jar文件
分析:导入jar:spring(包含springmvc),mybatis,mybatis-spring,jstl,c3p0,mysql驱动。
项目环境准备:
配置web.xml入口文件:
l 前端控制器(DispatcherServlelt)
l 编码过滤器
l 加载spring配置文件
配置spring核心配置文件(beans.xml)
l 数据源
l 工厂
l 事务
Springmvc核心配置文件
l 扫描
l Mvc:annotation:driven
l 视图解析器
Web.xml(入口文件)
<filter>
<filter-name>characterEncoding</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>characterEncoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 加载spring配置文件
-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:beans.xml</param-value>
</context-param>
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 加载springmvc配置文件:处理器映射器,处理器适配器,视图解析器
springmvc默认加载配置文件:
命名规范:servlet-name-servlet.xml====springmvc-servlet.xml
路径规范:WEB-INF下面
-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
配置springmvc
<context:component-scan base-package="cn.itcast"></context:component-scan>
<!--mvc:annotation-driven:默认创建对象: RequestMappingHandlerMapping RequestMappingHandlerAdapter
还支持json格式数据和java对象转换。 -->
<mvc:annotation-driven />
<!-- 配置视图解析器 后台返回逻辑试图:hello 视图解析器功能:解析出真正的物理视图 前缀+逻辑视图+后缀=====/WEB-INF/jsps/hello.jsp -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsps/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
Spring的配置文件beans.xml
<!-- 第一步:加载数据源 -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="driverClass" value="${jdbc.driver}"></property>
<property name="user" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!-- 第二步:工厂,生产sqlSession -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:sqlMapConfig.xml"></property>
</bean>
<!-- ssm整合使用接口代理开发模式:
spring扫描接口包
接口开发规范:
* 接口的方法名必须和映射文件的Statement的Id一致
* namespace的名称必须是接口的全类路径名
* 接口和映射文件必须同名,且在同一个目录下。
-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="cn.itcast.dao"></property>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
</bean>
<!-- 第三步:事务 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="delete*" propagation="REQUIRED"/>
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!-- 切面 :aop-->
<aop:config>
<aop:advisor advice-ref="txAdvice" pointcut="execution(* cn.itcast.service.*.*(..))"/>
</aop:config>
创建测试类
业务
操作
环境准备
使用sqlGernarator自动生成:
JavaBean,接口,映射文件。
分析:dao层接口有,需要创建service:接口,实现类
创建service层
查询所有商品
Controller
需要调用Service方法:创建Service层对象
@resource,@AutoWire
Service
注解dao层对象,调用dao层方法。查询所有
Dao层
Dao层采用接口代理开发,只需要写接口,满足mybatis接口代理开发规范。
修改
分析:1.跳转到修改页面:根据Id进行查询需要修改的对象,回显修改对象的数据
2.然后才进行修改。
根据Id查询修改对象,跳转到修改页面
修改
删除
删除单个记录
批量删除
修改页面
提交表单:把多个商品Id传递后台进行批量删除。
后台代码
文件上传
需求
上传图片:
上传图片,图片立马回显,页面不刷新。使用ajax技术。
怎么立马回显:
<img src=”图片绝对路径”></img>
<input type=”file” name=”myfile” onchange=”ajax事件”>
l 把文件关联到form表单
l 触发事件
<input type=”hidden” name=”pic” value=”图片相对路径”>
图片服务器:
模拟一台图片服务器:
创建一个web项目,这个web项目就是图片服务器。这个项目和上传图片项目的端口不一样。
上传图片:两台服务器都必须同时启动。
跨服务器上传:
Springmvc依赖上传文件jar文件:
Commos-io,fileupload,jersey
文件上传解析器
在springmvc配置:
导入依赖jar包
Springmvc依赖上传文件jar文件:
Commos-io,fileupload,jersey
页面改写
<p><label></label>
<img id='imgSize1ImgSrc' src='${picPath }${item.pic }' height="100" width="100" />
<input type='file' id='imgSize1File' name='imgSize1File' class="file" onchange='submitImgSize1Upload()' /><span class="pos" id="imgSize1FileSpan">请上传图片的大小不超过3MB</span>
<input type='hidden' id='imgSize1' name='pic' value='' reg="^.+$" tip="亲!您忘记上传图片了。" />
</p>
Ajax
上传图片服务器代码
@RequestMapping("uploadPic")
publicvoid uploadPic(HttpServletRequest request,String fileName,PrintWriter out){
//把Request强转成多部件请求对象
MultipartHttpServletRequest mh = (MultipartHttpServletRequest) request;
//根据fileName获取文件对象
CommonsMultipartFile cm = (CommonsMultipartFile) mh.getFile(fileName);
//获取上传图片流
byte[] fbytes = cm.getBytes();
String newFileName="";
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
newFileName = sdf.format(new Date());
//随机数
Random r = new Random();
for(int i=0;i<3;i++){
newFileName=newFileName+r.nextInt(10);
}
//获取文件的扩展名
String originalFilename = cm.getOriginalFilename();
String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
//跨服务器上传图片
//创建jersy服务器
Client client = Client.create();
//关联图片服务器
WebResource resource = client.resource(Commons.PIC_HOST+"/upload/"+newFileName+suffix);
//上传v
resource.put(String.class, fbytes);
//ajax回调函数
//图片回显:需要远程图片服务器图片绝对地址
//数据库保存是图片相对路径:需要图片相对路径
String fullPath = Commons.PIC_HOST+"/upload/"+newFileName+suffix;
String relativePath="/upload/"+newFileName+suffix;
//手动构造json格式:{"":"","":""}
String result="{\"fullPath\":\""+fullPath+"\",\"relativePath\":\""+relativePath+"\"}";
//向ajax回调函数写值
out.print(result);
}
修改图片服务器权限
com.sun.jersey.api.client.UniformInterfaceException: PUT http://127.0.0.1:8003/ssmImage0926/upload/20160109160438966600.jpg returned a response status of 403 Forbidden
修改图片服务器权限:
图片上传位置:
图片列表回显
添加图片回显列:
使用img图片回显标签回显:
使用远程图片服务器地址+数据库相对地址组合绝对路径实现了图片回显。
服务器地址定义:
获取数据库相对路径:
使用el表达式。
页面
缓存
互联网架构
缓存
缓存插件
Oscache页面缓存插件。
导入以上2个Oscache的jar文件,测试Oscache页面缓存。
创建一个web项目
测试缓存
访问地址
http://localhost:8080/oscache0926/index.jsp
http://localhost:8080/oscache0926/
以上两个地址访问同一个页面,但是缓存发生变化。
缓存原理:缓存数据结构是一个map,map的key存储url地址。
如果key发生变化,缓存就发生变化。
上面2个地址不一样,缓存发生了变化。
存储域
缓存默认存储域application
改变存储在session
换一个浏览器,缓存就消失。
固定key
固定时间同步数据库
每隔4秒同步一次:
持久化缓存
在classpath定义:Oscache.properties
cache.memory=false//不能缓存内存
cache.persistence.class=com.opensymphony.oscache.plugins.diskpersistence.DiskPersistenceListener//持久化类
cache.path=F:\\cache//持久化到F盘
缓存持久化:
Oscache
整合项目
把缓存包导入项目
在web.xml配置缓存过滤器
测试
测试方案:
在代码里面打一个断点,如果第二次不走断点,证明缓存成功。
Springmvc
支持
freemarker
导入相关jar
修改springmvc.xml支持freemarker视图
测试
定义ftl页面hello.ftl
后台代码
修改ItemsList
拦截器
定义全局拦截器
局部拦截器参考教案
全局拦击器定义如下:
自定义拦截器
publicclass Interceptor1 implements HandlerInterceptor {
/**
* controller执行前调用此方法
* 返回true表示继续放行,返回false拦截
* 这里可以加入登录校验、权限拦截等
*/
publicboolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
System.out.println("这是第一个拦截器Interceptor1。。。preHandle");
returntrue;
}
/**
* controller执行后但未返回视图前调用此方法
* 这里可在返回用户前对模型数据进行加工处理,比如这里加入公用信息以便页面显示
*/
publicvoid postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("这是第一个拦截器Interceptor1。。。postHandle");
}
/**
* controller执行后且视图返回后调用此方法
* 这里可得到执行controller时的异常信息
* 这里可记录操作日志,资源清理等
*/
publicvoid afterCompletion(HttpServletRequest arg0,
HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
System.out.println("这是第一个拦截器Interceptor1。。。afterCompletion");
}
}
测试:
第一个拦截放行,第二拦截放行:
这是第一个拦截器Interceptor1。。。preHandle
这是第2个拦截器Interceptor2。。。preHandle
这是第2个拦截器Interceptor2。。。postHandle
这是第一个拦截器Interceptor1。。。postHandle
这是第2个拦截器Interceptor2。。。afterCompletion
这是第一个拦截器Interceptor1。。。afterCompletion
第一个放行,第二个拦截:
Springmvc规定:凡是preHandle返回true,afterCompletion必须执行。
这是第一个拦截器Interceptor1。。。preHandle
这是第2个拦截器Interceptor2。。。preHandle
这是第一个拦截器Interceptor1。。。afterCompletion