1、springmvc对多视图的支持

(1)导入xml格式视图支持的jar包

  注意:springmvc本身就支持xml格式,所以不用导入其他支持的jar包了。

(2)在springmvc.xml中配置支持多视图

  1.     <!-- 配置支持多视图 -->
        <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
            <!-- 配置支持的媒体类型 -->
            <!-- spring3.2后改成如下配置 -->
            <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>
                            <!-- <entry key="pdf" value="application/pdf"></entry> 需要额外的jar包 -->
                        </map>
                    </property>
                </bean>
            </property>
  2.         <!-- 指定默认的视图 -->
            <property name="defaultViews">
                <!-- 支持多个视图 -->
                <list>
                    <!-- 对json格式视图的支持 -->
                    <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"></bean>
                    <!-- 对xml格式视图的支持,需要注入构造函数,需要一个jar包:spring-oxm-3.2.0.RELEASE.jar -->
                    <bean class="org.springframework.web.servlet.view.xml.MarshallingView">
                        <constructor-arg>
                            <bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
                                <!-- 配置对哪些类进行xml转换的支持,即绑定多个类,演示代码中我们只绑定了一个类 -->
                                <property name="classesToBeBound">
                                    <list>
                                        <!-- 注意:需要在绑定的类中加入对xml格式视图转换的注解:@XmlRootElement -->
                                        <value>com.itheima.domain.User</value>
                                    </list>
                                </property>
                            </bean>
                        </constructor-arg>
                    </bean>
                </list>
            </property>
        </bean>

  小结:通过以上配置,模拟了WebService对多视图的支持的功能。
(3)配置javabean,即在绑定的类User中加入对xml格式视图转换的注解:@XmlRootElement


(4)在web.xml中配置约定访问的url

  1.     <servlet-mapping>
            <servlet-name>springmvc</servlet-name>
            <url-pattern>/rest/*</url-pattern>
        </servlet-mapping>

(5)定义Controller

  1.     // 多视图支持
        // 返回的是对象,把返回的对象转换成json格式视图和xml格式的视图
        @RequestMapping("multiView")
        public User multiView() {
            User user1 = new User();
            user1.setId(1);
            user1.setUsername("晓艺");
            user1.setAge("26");
            user1.setAddress("物资学院");
            user1.setBirthday(new Date());
  2.         return user1;
        }

(6)访问
  根据官方文档约定:访问的时候需要加上响应的扩展名。
  即:访问json格式的数据,需要加上json扩展名;访问html格式的数据,需要加上html的扩展名;访问xml格式的数据,需要加上xml的扩展名。
  根据我们web.xml文件的访问约定:扩展名.do是访问jsp页面的。
  我们约定rest目录下所有以json和xml扩展名都支持相应的视图。

我们访问json格式数据的访问形式如下:


我们访问xml格式数据的访问形式如下:

(7)<mvc:annotation-driven/>

  1.     <mvc:annotation-driven/> 默认创建:注解处理器映射器、注解处理器适配器、并提供对json格式数据的支持。

在springmvc.xml中进行配置:

  1.     <!-- 表示默认创建:处理器映射器对象、处理器映射器对象,还表示默认启动json格式数据的支持 -->
        <mvc:annotation-driven />

但是注意:此时javaBean不能添加注解@XmlRootElement了。@XmlRootElement表示提供对xml视图支持。

2、SSM整合小案例

2.0、需求

  • 实现商品查询列表,从mysql数据库中查询商品信息。

2.1、使用eclipse,创建一个动态web工程并导入jar包

  • 其中Dynamic web module version版本选择 2.5,这样兼容性好一些;
  • Default output folder设置为 WebRoot\WEB-INF\classes
  • Content directory设置为 WebRoot
  • 更改JRE System Library[J2SE-1.5]为 JRE System Library[jre1.7.0_80]
  • 删掉没用的库:EAR Libraries
  • 增加服务器运行环境库 Server Runtime,不然jsp文件会报错。
  • 创建完项目后,将整个项目的编码改为UTF-8。
  • 操作步骤:选中项目右键 --> Properties --> Resource --> Text file encoding --> Other中选择UTF-8。
  • 对于动态的java web项目,为了工程目录结构的清爽,我们将引入的jar包放到“Web App Libraries”中,可以通过“小三角”选择是否“Show 'Referenced Libraries' Node ”进行调节。
  • 对于普通的java项目,为了工程目录结构的清爽,我们将引入的jar包放到“Referenced Libraries”中,可以通过“小三角”选择是否“Show 'Referenced Libraries' Node ”进行调节。

导入jar包
  包括:spring(包括springmvc)、mybatis、mybatis-spring整合包、数据库驱动、第三方连接池、jstl、c3p0管理数据源、log4j、junit。
  参考:“mybatis与springmvc整合全部jar包”目录。

本次案例共导入28个jar包。如下图所示:

2.2、web.xml配置文件(入口)

web.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://java.sun.com/xml/ns/javaee"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
        id="WebApp_ID" version="2.5">
        <display-name>day63_SpringMVC_01</display-name>
  2.     <!-- 配置spring编码过滤器 -->
        <filter>
            <filter-name>characterEcoding</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>characterEcoding</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
  3.     <!-- 配置前端控制器:DispatcherServlet -->
        <servlet >
            <servlet-name>springmvc</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <!-- 显示配置加载springmvc.xml文件,即配置springmvc.xml文件的初始化参数 -->
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:springmvc.xml</param-value>
            </init-param>
        </servlet>
        <!-- 配置servlet拦截扩展名 -->
        <servlet-mapping>
            <servlet-name>springmvc</servlet-name>
            <url-pattern>*.do</url-pattern>
        </servlet-mapping>
        <!-- 配置servlet拦截目录 -->
        <servlet-mapping>
            <servlet-name>springmvc</servlet-name>
            <url-pattern>/rest/*</url-pattern>
        </servlet-mapping>
  4.     <!-- 配置加载spring的配置文件:beans.xml -->
        <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> <!-- 这两种方式均可 -->
            <!-- <param-value>/WEB-INF/classes/beans.xml</param-value> -->
        </context-param>
  5.     <welcome-file-list>
            <welcome-file>index.html</welcome-file>
            <welcome-file>index.htm</welcome-file>
            <welcome-file>index.jsp</welcome-file>
            <welcome-file>default.html</welcome-file>
            <welcome-file>default.htm</welcome-file>
            <welcome-file>default.jsp</welcome-file>
        </welcome-file-list>
    </web-app>

2.3、springmvc.xml配置文件

  1. <?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 ">
        <!-- 配置扫描,把Controller交给spring管理 -->
        <context:component-scan base-package="com.itheima"></context:component-scan>
  2.     <!-- 表示默认创建处理器映射器对象、处理器映射器对象,还表示默认启动json格式数据的支持 -->
        <mvc:annotation-driven />
  3.     <!-- 配置jsp视图解析器,InternalResourceViewResolver负责解析出真正的逻辑视图 -->
        <!-- 后台返回逻辑视图:index,jsp视图解析器解析出真正的物理视图:前缀+逻辑视图+后缀 ==>/WEB-INF/jsps/index.jsp -->
        <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/WEB-INF/jsps/"></property>
            <property name="suffix" value=".jsp"></property>
        </bean>
    </beans>

2.4、bean.xml配置文件(相当于applicationContext.xml)

bean.xml

  1. <?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 ">
        <context:component-scan base-package=""></context:component-scan>
  2.     <!-- 1、配置数据源 -->
        <context:property-placeholder location="classpath:jdbc.properties"/>
        <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
            <property name="driverClass" value="${jdbc.driver}"></property>
            <property name="jdbcUrl" value="${jdbc.url}"></property>
            <property name="user" value="${jdbc.username}"></property>
            <property name="password" value="${jdbc.password}"></property>
        </bean>
  3.     <!-- 2、配置sqlSessionFactory,用于生产sqlSession -->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource"></property>
            <property name="configLocation" value="classpath:sqlMapConfig.xml"></property>
        </bean>
        <!-- 配置mybatis的Mapper接口代理开发,需要遵循的几点规范 -->
        <!-- 
            1、mapper接口的全限定名要和mapper映射文件的namespace的值相同。
            2、mapper接口的方法名称要和mapper映射文件中的statement的id相同。
            3、mapper接口的方法参数只能有一个,且类型要和mapper映射文件中statement的parameterType的值保持一致。
            4、mapper接口的返回值类型要和mapper映射文件中statement的resultType的值或resultMap中的type的值保持一致。
            5、mapper接口和mapper映射文件必须在同一目录下。
        -->
        <!-- mapper代理开发方式之批量mapper配置,默认bean的id为类名首字母小写 -->
        <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
            <!-- 指定批量mapper配置的包名 -->
            <property name="basePackage" value="com.itheima.dao"></property>
            <!-- 当只有一个SqlSessionFactory时,默认是不需要配置SqlSessionFactory的 -->
            <!-- 当有多个SqlSessionFactory时,可以指定使用的SqlSessionFactory -->
            <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
        </bean>
  4.     <!-- 3、配置事务管理 -->
        <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="insert*" propagation="REQUIRED"/>
                <tx:method name="*" propagation="REQUIRED"/>
            </tx:attributes>
        </tx:advice>
        <!-- 配置拦截service:切面编程 -->
        <aop:config>
            <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.itheima.service.*.*(..))"/>
        </aop:config>
    </beans>

2.6、编写代码

mapper层(dao层):
  mapper接口代码使用Mybatis的逆向工程生成的。
service层:
  ItemsService.java

  1. public interface ItemsService {
  2.     public List<Items> findAll();
  3.     public Items findById(Integer id);
  4.     public void saveOrUpdate(Items items);
  5.     public void deleteById(Integer id);
  6. }

  ItemsServiceImpl.java

  1. @Service
    public class ItemsServiceImpl implements ItemsService {
  2.     // 注入接口对象(Mapper接口使用代理类)
        @Resource
        private ItemsMapper itemsMapper;
  3.     public List<Items> findAll() {
            List<Items> list = itemsMapper.findAll();
            return list;
        }
  4.     public Items findById(Integer id) {
            Items items = itemsMapper.selectByPrimaryKey(id);
            return items;
        }
  5.     public void saveOrUpdate(Items items) {
            itemsMapper.updateByPrimaryKey(items); // 商品id通过页面隐藏域传过来的
        }
  6.     public void deleteById(Integer id) {
            itemsMapper.deleteByPrimaryKey(id);
        }
  7. }

controller层(web层/Action层):
  ItemsController.java

  1. @Controller
    @RequestMapping("/items")
    public class ItemsController {
  2.     // 注入service对象
        @Resource
        private ItemsService itemsService;
  3.     // 查询所有商品方法
        @RequestMapping("list")
        // springmvc使用Model对象进行页面数据回显,Model对象相当于javaweb时所学的application对象(应用域对象),所以Model对象中的数据,在页面上可以通过EL表达式进行获取。
        // 有了Model对象,才可以向对象中放值,那么Model对象该如何创建呢?
        // 答:“由于springmvc中放到方法里面的对象会自动被创建”,那么我们就把Model对象放到方法里面。
        public String list(Model model) { 
            List<Items> itemsList = itemsService.findAll();
            model.addAttribute("itemsList", itemsList);
            return "itemsList";
        }
  4.     // 修改商品方法
        @RequestMapping("editById")
        public String editById(Integer id, Model model) {
            // 跟据id查询商品
            Items items = itemsService.findById(id);
            model.addAttribute("items", items);
            return "editItems";
        }
  5.     // 修改后保存方法
        @RequestMapping("saveOrUpdate")
        public String saveOrUpdate(Items items) {
            itemsService.saveOrUpdate(items); // 商品id通过页面隐藏域传过来的
            return "redirect:list.do";
        }
  6.     // 跟据id进行删除
        @RequestMapping("deleteById")
        public String deleteById(Integer id) {
            itemsService.deleteById(id); 
            return "redirect:list.do";
        }
  7.     // 跟据ids进行批量删除
        @RequestMapping("deleteByIds")
        public String deleteByIds(Integer[] ids) { // 特别注意:标签input的name的属性值id要与方法的形式参数名称id相同。形参名称也可以起别名!但需要其他注解配合哦!
            for (Integer id : ids) {
                itemsService.deleteById(id); 
            }
            return "redirect:list.do";
        }
    }

2.7、springmvc文件上传

需求分析:
  使用ajax,响应json格式数据的形式上传图片并立刻回显。页面不刷新图片回显立刻。

  1. ajax能不能提交表单?
    答:ajax自己不能提交表单。要想ajax提交表单,需要借助一个插件。
  2. 为什么我们要提交表单?
    答:因为我们要提交一个文件对象,需要将文件对象关联到表单里面。
    当我们点击一个按钮的时候,这个被关联到表单里的对象,才会被提交。
  3. 伪代码示例如下:
        // 图片回显
        <img src=“图片路径”/>
        // 把文件关联表单,触发ajax事件
        <input type="file" onchange="ajax事件"/>
        <input type="hidden" value="图片相对路径"/>
  4.     // 本示例开始,我们不使用 enctype="multipart/form-data" 提交文件对象了
        // 我们直接使用ajax提交文件对象,我们添加隐藏域,向后台提交图片相对路径

(1)导入跨服务器上传文件的jar包、IO、fileupload

(2)模拟2台服务器
  创建一个动态的java web项目:图片服务器项目,图片服务器项目的服务器和上传图片项目的服务器端口不一致即可。如下图所示:

(3)springmvc支持文件上传,需要先在springmvc.xml配置文件中开启文件上传
  在springmvc.xml配置文件中新加入的内容如下:

  1.     <!-- 配置开启文件上传,因为我们要跨服务器上传,需要写上id,该id名称固定 -->
        <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
            <!-- 配置文件上传大小 -->
            <property name="maxUploadSize" value="1024000"></property>
        </bean>

(4)前台页面ajax
  功能:发送请求,请求上传图片,图片需要被关联在表单里。


使用ajax提交form表单的插件:jquery.form.js

(5)后台代码

  1. @Controller
    @RequestMapping("/upload")
    public class UploadController {
  2.     @RequestMapping("uploadPic")
        public void uploadPic(HttpServletRequest request, String fileName, PrintWriter out) {
            // 1、准备文件上传流
            // 由于上传的图片在请求里面,它是流类型的,直接通过Request对象不能操作
            // 所以先要把Request对象强转成多部件请求对象
            MultipartHttpServletRequest mhr = (MultipartHttpServletRequest) request;
            // 根据文件名称获取普通多部件文件对象
            CommonsMultipartFile cmFile = (CommonsMultipartFile) mhr.getFile(fileName);
            // 获取文件上传流
            byte[] fbytes = cmFile.getBytes();
  3.         // 2、准备文件名称
            // 文件名称在服务器有可能重复,我们使用时间来区分他们
            String newFileName = "";
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
            newFileName = sdf.format(new Date());
            // 在毫秒的时候文件名也可能重复,我们再加点盐
            Random r = new Random(); // [0,1)
            for (int i = 0; i < 3; i++) {
                newFileName = newFileName + r.nextInt(10);
            }
  4.         // 3、获取文件扩展名
            String originalFilename = cmFile.getOriginalFilename();
            // int x = a.lastIndexOf(b); // 表示b字符串在a字符串中最后出现的位置,从0开始
            String suffix = originalFilename.substring(originalFilename.lastIndexOf(".")); 
  5.         // 4、创建jesy服务器,进行跨服务器上传
            Client client = Client.create();
            // 把文件关联到远程服务器
            // 图片文件的完整路径为:http://127.0.0.1:9005/day64_SSMImageServer/upload/20181027174523998.png
            WebResource resource = client.resource(Commons.PIC_HOST + "/upload/" + newFileName + suffix);
            // 上传图片文件
            resource.put(String.class, fbytes);
  6.         // 5、ajax回调函数需要回显什么东西呢?
            // 图片需要回显:需要图片的完整路径
            // 数据库保存图片:需要图片的相对路径
            String fullPath = Commons.PIC_HOST + "/upload/" + newFileName + suffix;
            String relativePath = "/upload/" + newFileName + suffix;
            // json格式的数据:{"":"","":""}
            String result = "{\"fullPath\":\"" + fullPath + "\",\"relativePath\":\"" + relativePath + "\"}";
            out.print(result);
        }
    }

(6)修改图片服务器文件上传权限

(7)图片上传位置

(8)图片列表回显
  回显图片需要使用<img/>标签
itemsList.jsp

  1.     <c:set var="picPath" value="http://127.0.0.1:9090/day64_SSMImageServer"></c:set>
    ......
        <td>
            <img id='imgSize1ImgSrc' src='${picPath}${items.pic}' height="100" width="100"/>
        </td>

editItems.jsp

  1.     <c:set var="picPath" value="http://127.0.0.1:9090/day64_SSMImageServer"></c:set>
    ......
        <img id='imgSize1ImgSrc' src='${picPath}${items.pic}' height="100" width="100"/>
    ......

3、页面缓存

  需求:使用页面缓存来提高用户体验度。

3.1、简单理解缓存原理

简单理解缓存原理图解如下:


优点:提升性能。
缺点:不访问数据库,不是实时数据。
思考:怎么样能中和一下优缺点呢?

  • 页面静态化:

    • 静态化技术连缓存都不走了,直接给你一个HTML页面,缺点更大。
  • 分布式缓存:
    • 分布式缓存能控制`颗粒的大小`,分布式缓存使用的是redis,memcached等等
    • 这相当于是数据库,因为我们在任何一层都可以进行操作数据库。所以可以进行颗粒大小的控制。

3.2、浅谈互联网架构

浅谈互联网架构图解:

3.3、实现页面缓存

  使用Oscache实现页面缓存。
(1)创建一个动态的java web项目,导入所需的jar包


(2)测试:创建一个index.jsp页面,使用时间来测试

(3)访问测试
http://localhost:8080/day64_Oscache/index.jsp
http://localhost:8080/day64_Oscache/
  分析:上面2个地址都访问同一个页面,为什么缓存会变化呢?
缓存原理:
  缓存数据结构:是一个map集合。
  key存储的是浏览器访问的url,上面2个url不一致,缓存肯定变化。
  value存储的是缓存页面的数据。
(4)缓存的存储范围
  缓存默认存储在application域当中。在不同的浏览器之间访问同一地址,缓存时间不会发生变化。
(5)改变缓存的存储范围
  改变缓存的存储范围为session域中。在不同的浏览器之间访问同一地址,缓存时间会发生变化。

(6)固定缓存的key

  由于固定了缓存的key,所以以下2个地址访问同一个页面,缓存时间不会发生变化。
  http://localhost:8080/day64_Oscache/index.jsp
  http://localhost:8080/day64_Oscache/
(7)要求每隔4秒缓存同步(刷新)一次

(8)要求缓存持久化到磁盘或者保存到redis缓存服务器中
  创建oscache.properties,这个配置文件必须在classpath下面,文件内容如下:
oscache.properties

  1. cache.memory=false      // 不使用缓存内存
    cache.persistence.class=com.opensymphony.oscache.plugins.diskpersistence.DiskPersistenceListener    // 持久化类
    cache.path=E:\\oscache  // 持久化到E盘oscache目录下

  查看持久化文件

3.4、在SSM项目中使用Oscache

  约定:假如商品页面访问量特别大,我们给商品页面使用缓存。即:约定items路径下所有请求都缓存。
(1)将oscache-2.4.1.jar拷贝至项目lib目录下,并添加至构建路径
(2)在web.xml中配置缓存过滤器


(3)测试缓存
  打一个断点(给商品查询列表),第一次断点必须走,第二次断点不走,走缓存页面。
(4)配置缓存的持久化
  将配置文件oscache.properties拷贝至项目的config目录下即可。

4、使用springmvc的其他视图

4.1、整合freemarker视图

  • 需求:使用springmvc本身的视图解析器来解析页面静态化。

(1)导入所需要的jar包
  com.springsource.freemarker-2.3.15.jar和spring-context-support-3.2.0.RELEASE.jar
(2)在springmvc.xml中配置对freemarker视图的支持
  配置对freemarker视图的支持后,我们发现我们可以不使用jsp来开发了,我们可以直接使用freemarker视图来开发。
  即:我们可以删除掉在springmvc.xml中配置的jsp视图解析器了。


(3)编写freemarker的页面
  WebRoot/WEB-INF/jsps/ftl.ftl

(4)编写后台代码

  1. @Controller
    @RequestMapping("/ftl")
    public class FtlController {
  2.     @RequestMapping("hello")
        public String hello(Model model) {
            model.addAttribute("hello","页面静态化技术之freemarker");
            return "ftl";
        }
    }

(5)修改itemsList.jsp页面为静态化页面itemsList.ftl
itemsList.ftl

  1. <#assign picPath="http://127.0.0.1:9090/day64_SSMImageServer"/>
    <#assign projectName="day64_SpringMVC_02"/>
    <!DOCTYPE html 
        PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
        "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>查询商品列表</title>
    </head>
    <body>
        <form action="${projectName}/items/deleteByIds.do" method="post">
            查询条件:
            <table width="100%" border=1>
                <tr>
                    <td><input type="submit" value="查询"/></td>
                    <td><input type="submit" value="批量删除"/></td>
                </tr>
            </table>
  2.         商品列表:
            <table width="100%" border=1>
                <tr>
                    <td>商品ID</td>
                    <td>商品名称</td>
                    <td>商品图片</td>
                    <td>商品价格</td>
                    <td>生产日期</td>
                    <td>商品描述</td>
                    <td>操作</td>
                </tr>
                <#list itemsList as items>
                    <tr>
                        <!-- 添加复选框 -->
                        <td><!-- 特别注意:标签input的name的属性值id要与方法的形式参数名称id相同。 -->
                            <input type="checkbox" name="ids" value="${items.id}"><!-- 复选框中的值需要提交表单才能传递给后台 -->
                        </td>
                        <td>${items.name}</td>
                        <td>
                            <img id='imgSize1ImgSrc' src='${picPath}${items.pic}' height="100" width="100"/>
                        </td>
                        <td>${items.price}</td>
                        <td>${items.detail}</td>
                        <td>
                            <a href="${projectName}/items/editById.do?id=${items.id}">修改</a>
                            <a href="${projectName}/items/deleteById.do?id=${items.id}">删除</a>
                        </td>
                    </tr>
                </#list>
            </table>
        </form>
    </body>
  3. </html>

(6)访问测试
  访问地址:http://localhost:8080/day64_SpringMVC_02/items/list.do
  访问测试没有问题,以上演示就是springmvc对freemarker的支持。

5、拦截器

定义:
  Spring Web MVC 的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。

5.1、局部拦截器

  针对某个HandlerMapping进行配置,只对当前HandlerMapping有效。即针对单个处理器映射器,称为局部拦截器。
在springmvc.xml中的配置示例如下:

  1.     <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
            <property name="interceptors">
                <list>
                    <ref bean="handlerInterceptor1"/>
                    <ref bean="handlerInterceptor2"/>
                </list>
            </property>
        </bean>
        <bean id="handlerInterceptor1" class="springmvc.intercapter.HandlerInterceptor1"/>
        <bean id="handlerInterceptor2" class="springmvc.intercapter.HandlerInterceptor2"/>

拦截器代码编写:需要实现HandlerInterceptor接口

  1. public class HandlerInterceptor1 implements HandlerInterceptor {
  2.     /**
         * controller执行前调用此方法
         * 返回true表示继续执行,返回false中止执行
         * 这里可以加入登录校验、权限拦截等
         */
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, 
                Object handler) throws Exception {
            return false;
        }
  3.     /**
         * controller执行后但未返回视图前调用此方法
         * 这里可在返回用户前对模型数据进行加工处理,比如这里加入公用信息以便页面显示
         */
        public void postHandle(HttpServletRequest request, HttpServletResponse response, 
                Object handler, ModelAndView modelAndView) throws Exception {
        }
  4.     /**
         * controller执行后且视图返回后调用此方法
         * 这里可得到执行controller时的异常信息
         * 这里可记录操作日志,资源清理等
         */
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, 
                Object handler, Exception ex) throws Exception {    
        }
    }

5.2、全局拦截器

  拦截所有请求。
在springmvc.xml中的配置示例如下:

  1.     <!--配置全局拦截器 -->
        <mvc:interceptors>
            <!--配置多个拦截器,顺序执行 -->
            <mvc:interceptor>
                <mvc:mapping path="/**"/>
                <bean class="com.itheima.interceptor.HandlerInterceptor1"></bean>
            </mvc:interceptor>
            <mvc:interceptor>
                <mvc:mapping path="/**"/>
                <bean class="com.itheima.interceptor.HandlerInterceptor2"></bean>
            </mvc:interceptor>
        </mvc:interceptors>

拦截器代码编写:需要实现HandlerInterceptor接口
HandlerInterceptor1.java

  1. // 拦截器代码编写:需要实现HandlerInterceptor接口
    public class HandlerInterceptor1 implements HandlerInterceptor {
  2.     /**
         * controller执行前调用此方法,即在处理器映射器之前执行
         * 返回true表示继续执行,返回false中止执行
         * 这里可以加入登录校验、权限拦截等
         */
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, 
                Object handler) throws Exception {
            System.out.println("这是第1个拦截器的preHandle()方法");
            return false;
        }
  3.     /**
         * controller执行后但未返回视图前调用此方法,即调用Controller了,还没返回ModelAndView执行
         * 这里可在返回用户前对模型数据进行加工处理,比如这里加入公用信息以便页面显示
         */
        public void postHandle(HttpServletRequest request, HttpServletResponse response, 
                Object handler, ModelAndView modelAndView) throws Exception {
            System.out.println("这是第1个拦截器的postHandle()方法");
        }
  4.     /**
         * controller执行后且视图返回后调用此方法,即返回ModelAndView之后执行
         * 这里可得到执行controller时的异常信息
         * 这里可记录操作日志,资源清理等
         */
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, 
                Object handler, Exception ex) throws Exception {
            System.out.println("这是第1个拦截器的afterCompletion()方法");
        }

HandlerInterceptor2.java

  1. // 拦截器代码编写:需要实现HandlerInterceptor接口
    public class HandlerInterceptor2 implements HandlerInterceptor {
  2.     /**
         * controller执行前调用此方法
         * 返回true表示继续执行,返回false中止执行
         * 这里可以加入登录校验、权限拦截等
         */
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, 
                Object handler) throws Exception {
            System.out.println("这是第2个拦截器的preHandle()方法");
            return false;
        }
  3.     /**
         * controller执行后但未返回视图前调用此方法
         * 这里可在返回用户前对模型数据进行加工处理,比如这里加入公用信息以便页面显示
         */
        public void postHandle(HttpServletRequest request, HttpServletResponse response, 
                Object handler, ModelAndView modelAndView) throws Exception {
            System.out.println("这是第2个拦截器的postHandle()方法");
        }
  4.     /**
         * controller执行后且视图返回后调用此方法
         * 这里可得到执行controller时的异常信息
         * 这里可记录操作日志,资源清理等
         */
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, 
                Object handler, Exception ex) throws Exception {
            System.out.println("这是第2个拦截器的afterCompletion()方法");
        }

5.3、测试

(1)第1个拦截器放行,第2个拦截器也放行。
  即两个拦截器的preHandle()方法都返回true。
测试结果如下:

  1. 这是第1个拦截器的preHandle()方法
    这是第2个拦截器的preHandle()方法
    这是第2个拦截器的postHandle()方法
    这是第1个拦截器的postHandle()方法
    这是第2个拦截器的afterCompletion()方法
    这是第1个拦截器的afterCompletion()方法

(2)第1个拦截器放行,第2个拦截器不放行。
  即第一个拦截器的preHandle()方法返回true,第二个拦截器的preHandle()方法返回false。
  springmvc规定:凡是方法preHandle()返回true,则方法afterCompletion()必须执行。
测试结果如下:

  1. 这是第1个拦截器的preHandle()方法
    这是第2个拦截器的preHandle()方法
    这是第1个拦截器的afterCompletion()方法

(3)第1个拦截器不放行,第2个拦截器不放行。
  即两个拦截器的preHandle()方法都返回false。
测试结果如下:

  1. 这是第1个拦截器的preHandle()方法

5.4、拦截器应用:用户身份认证

示例代码如下:

  1. public class LoginInterceptor implements HandlerInterceptor{
  2.     /**
         * controller执行前调用此方法,即在处理器映射器之前执行
         * 返回true表示继续执行,返回false中止执行
         * 这里可以加入登录校验、权限拦截等
         */
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, 
                Object handler) throws Exception {
            // 如果是登录页面则放行
            if (request.getRequestURI().indexOf("login.action") >= 0) {
                return true; // 放行
            }
            HttpSession session = request.getSession();
            // 如果用户已登录也放行
            if (session.getAttribute("user") != null) {
                return true; // 放行
            }
  3.         // 用户没有登录跳转到登录页面
            request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
            return false; // 不放行
        }
  4.     /**
         * controller执行后但未返回视图前调用此方法,即调用Controller了,还没返回ModelAndView执行
         * 这里可在返回用户前对模型数据进行加工处理,比如这里加入公用信息以便页面显示
         */
        public void postHandle(HttpServletRequest request, HttpServletResponse response, 
                Object handler, ModelAndView modelAndView) throws Exception {
        }
  5.     /**
         * controller执行后且视图返回后调用此方法,即返回ModelAndView之后执行
         * 这里可得到执行controller时的异常信息
         * 这里可记录操作日志,资源清理等
         */
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, 
                Object handler, Exception ex) throws Exception {
        }
    }

6、springmvc整合Hibernate

未完待续……

day64_SpringMVC学习笔记_02的更多相关文章

  1. SASS学习笔记_02

    导入 当模块化布局的时候 导入头和尾 私有化 不生成css文件 文件名前面加下划线   结果   嵌套导入   导入css文件 不推荐   注释 和默认变量值

  2. Python学习笔记_02:使用Tkinter连接MySQL数据库实现登陆注册功能

    1 环境搭建 1.1 Python安装 1.2 MySQL环境搭建 1.3安装MySQLdb  2 具体实现 2.1 登陆界面 2.2 注册界面 2.3 具体实现部分代码   1 环境搭建 1.1 P ...

  3. SpringMVC学习笔记_02

    1.springmvc对多视图的支持 (1)导入xml格式视图支持的jar包   注意:springmvc本身就支持xml格式,所以不用导入其他支持的jar包了. (2)在springmvc.xml中 ...

  4. node学习笔记_02 API详解

    一.知识点:url.parse方法 方法说明: 讲一个URL字符串转换成对象并返回. 语法:url.parse(urlStr, [parseQueryString], [slashesDenoteHo ...

  5. tkinter学习笔记_02

    4. 多行输入框 text # 按钮 # command 执行动作 def insert_point(): var = e.get() t.insert('insert', var) b = tk.B ...

  6. day46_Webservice学习笔记_02

    一.回顾昨天所学 什么是webservice?    什么是远程调用技术?答:系统和系统之间的调用,从远程系统当中获取业务数据.    Webservice是web服务,他是用http传输SOAP协议 ...

  7. Python基础学习笔记_02

    Python中的运算符 标准算术运算符 加(+) 减(-) 乘(*) 除(/) 整除(//) print(1+1) #加法运算 print(1-1) #减法运算 print(2*4) #乘法运算 pr ...

  8. OpenGL_Qt学习笔记之_03(平面图形的着色和旋转)(转)

    http://www.cnblogs.com/tornadomeet/archive/2012/08/23/2653305.html 在这一节中主要简单介绍下怎样给平面几何着色,以及怎样让绘制出来的几 ...

  9. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

随机推荐

  1. git 报错git-upload-pack 解决方法

    报错如下: bash: git-upload-pack: command not foundfatal: The remote end hung up unexpectedly 原因:原来代码服务器上 ...

  2. 树形DP ---- Codeforces Global Round 2 F. Niyaz and Small Degrees引发的一场血案

    Aspirations:没有结果,没有成绩,acm是否有意义?它最大的意义就是让我培养快速理解和应用一个个未知知识点的能力. ————————————————————————————————————— ...

  3. A02-java学习-classpath配置-标识符-java变量类型

    学习 1, classpath的配置和使用 2, java的标识符命名规则和命名规范 3, 字符编码 4, java的变量类型 5, 程序的入口main方法解释

  4. dx、aapt工具

    1.DX命令: Dalvik虚拟机不能直接运行Java代码编译出来的文件,只能运行.dex文件,所以需要将.class,.jar等文件通过DX工具转换成.dex文件. 2.AAPT命令 一个Andro ...

  5. array_column 函数, 以及在PHP5.5之下的替代方法

    array_column 函数, 是能够根据多维数组中共有的一个键值来提取多维数组中属于这个键的值 例如下面的数组: $test = array( 0 => array( 'id' => ...

  6. angular浏览器滚动条滚动到指定element 触发事件

    angular.module('app').directive('ScrollTrigger', () => { return { restrict: "A", link:f ...

  7. Semantic Versioning Specification & 语义化版本

    Semantic Versioning Specification & 语义化版本 Semantic Versioning Specification http://semver.org 16 ...

  8. windows文件共享 防火墙规则设置

    防火墙入站规则.完成以下两项设置即可. 设置一 操作:允许连接协议类型:UDP本地端口:137, 138远程端口:所有端口 设置二 操作:允许连接协议类型:TCP本地端口:139, 445远程端口:所 ...

  9. Codeforces 1097 G. Vladislav and a Great Legend

    题目链接 一道好题. 题意:给定一棵\(n\)个点的树,求: \[\sum_{S\subseteq \{1,2,\dots,n\}}f(S)^k\] 其中\(f(S)\)代表用树边将点集\(S\)连通 ...

  10. oracle无法通过IP地址进行连接

    在oracle安装完成之后有时候后无法使用IP地址进行连接或者压根无法进行连接,此时我们可以通过配置oracle的监听来解决这个问题: 在开始菜单中找到oracle文件夹的net manager,如下 ...