20160611-20160714springmvc入门进阶

springmvc第二阶段 高级知识

复习:

springmvc框架:

DispatcherServlet前端控制器:接收request,进行response

HandlerMapping处理器映射器:根据url查找Handler。(可以通过xml配置方式,注解方式)

HandlerAdapter处理器适配器:根据特定规则去执行Handler,编写Handler时需要按照HandlerAdapter的要求去编写。

Handler处理器(后端控制器):需要程序员去编写,常用注解开发方式。

                   Handler处理器执行后结果 是ModelAndView,具体开发时Handler返回方法值类型包括 :ModelAndView、String(逻辑视图名)、void(通过在Handler形参中添加request和response,类似原始 servlet开发方式,注意:可以通过指定response响应的结果类型实现json数据输出)

View resolver视图解析器:根据逻辑视图名生成真正的视图(在springmvc中使用View对象表示)

View视图:jsp页面,仅是数据展示,没有业务逻辑。

注解开发:

使用注解方式的处理器映射器和适配器:

<!--注解映射器 -->
    <beanclass="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
<!--注解适配器 -->
    <beanclass="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>

在实际开发,使用<mvc:annotation-driven>代替上边处理器映射器和适配器配置。

@controller注解必须要加,作用标识类是一个Handler处理器。

@requestMapping注解必须要加,作用:

1、对url和Handler的方法进行映射。

2、可以窄化请求映射,设置Handler的根路径,url就是根路径+子路径请求方式

3、可以限制http请求的方法

映射成功后,springmvc框架生成一个Handler对象,对象中只包括 一个映射成功的method。

注解开发中参数绑定:

将request请求过来的key/value的数据(理解一个串),通过转换(参数绑定的一部分),将key/value串转成形参,将转换后的结果传给形参(整个参数绑定过程)。

springmvc所支持参数绑定:

1、默认支持很多类型,HttpServletRequest、response、session、

model/modelMap(将模型数据填充到request域)

2、支持简单数据类型,整型、字符串、日期。。

只要保证request请求的参数名和形参名称一致,自动绑定成功

如果request请求的参数名和形参名称不一致,可以使用@RequestParam(指定request请求的参数名),@RequestParam加在形参的前边。

3、支持pojo类型

只要保证request请求的参数名称和pojo中的属性名一致,自动将request请求的参数设置到pojo的属性中。

注意:形参中即有pojo类型又有简单类型,参数绑定互不影响。

自定义参数绑定:

日期类型绑定自定义:

定义的Converter<源类型,目标类型>接口实现类,比如:

Converter<String,Date>表示:将请求的日期数据串转成java中的日期类型。

注意:要转换的目标类型一定和接收的pojo中的属性类型一致。

将定义的Converter实现类注入到处理器适配器中。

    <mvc:annotation-drivenconversion-service="conversionService">
</mvc:annotation-driven>
<!-- conversionService -->
    <beanid="conversionService"
        class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <!-- 转换器 -->
        <propertyname="converters">
            <list>
                <beanclass="cn.itcast.ssm.controller.converter.CustomDateConverter"/>
            </list>
        </property>
    </bean>

springmvc和struts2区别:

springmvc面向方法开发的(更接近service接口的开发方式),struts2面向类开发。

springmvc可以单例开发,struts2只能是多例开发。

1       课程安排

上午:

在商品查询和商品修改功能案例驱动下进行学习:

包装类型pojo参数绑定(掌握)。

集合类型的参数绑定:数组、list、map..

商品修改添加校验,学习springmvc提供校验validation(使用的是hibernate校验框架)

数据回显

统一异常处理(掌握)

下午:

上传图片

json数据交互

RESTful支持

拦截器

2      包装类型pojo参数绑定

2.1       需求

商品查询controller方法中实现商品查询条件传入。

2.2       实现方法

第一种方法:在形参中 添加HttpServletRequest request参数,通过request接收查询条件参数。

第二种方法:在形参中让包装类型的pojo接收查询条件参数。

分析:

页面传参数的特点:复杂,多样性。条件包括 :用户账号、商品编号、订单信息。。。

如果将用户账号、商品编号、订单信息等放在简单pojo(属性是简单类型)中,pojo类属性比较多,比较乱。

建议使用包装类型的pojo,pojo中属性是pojo。

2.3       页面参数和controller方法形参定义

页面参数:

商品名称:<input name="itemsCustom.name" />

注意:itemsCustom和包装pojo中的属性一致即可。

controller方法形参:

public ModelAndView queryItems(HttpServletRequest request,ItemsQueryVo itemsQueryVo) throws Exception

3       集合类型绑定

3.1       数组绑定

3.1.1     需求

商品批量删除,用户在页面选择多个商品,批量删除。

3.1.2     表现层实现

关键:将页面选择(多选)的商品id,传到controller方法的形参,方法形参使用数组接收页面请求的多个商品id。

controller方法定义:

页面定义:

3.2       list绑定

3.2.1     需求

通常在需要批量提交数据时,将提交的数据绑定到list<pojo>中,比如:成绩录入(录入多门课成绩,批量提交),

本例子需求:批量商品修改,在页面输入多个商品信息,将多个商品信息提交到controller方法中。

3.2.2     表现层实现

controller方法定义:

1、进入批量商品修改页面(页面样式参考商品列表实现)

2、批量修改商品提交

使用List接收页面提交的批量数据,通过包装pojo接收,在包装pojo中定义list<pojo>属性

页面定义:

3.3      map绑定

也通过在包装pojo中定义map类型属性。

在包装类中定义Map对象,并添加get/set方法,action使用包装对象接收。

包装类中定义Map对象如下:

Public classQueryVo {
private Map<String, Object>itemInfo = new HashMap<String, Object>();
  //get/set方法..
}

页面定义如下:

<tr>
<td>学生信息:</td>
<td>
姓名:<inputtype="text"name="itemInfo[‘name‘]"/>
年龄:<inputtype="text"name="itemInfo[‘price‘]"/>
.. .. ..
</td>
</tr>

Controller方法定义如下:

public String useraddsubmit(Model model,QueryVoqueryVo)throws Exception{
System.out.println(queryVo.getStudentinfo());
}

4     springmvc校验

4.1       校验理解

项目中,通常使用较多是前端的校验,比如页面中js校验。对于安全要求较高点建议在服务端进行校验。

服务端校验:

控制层conroller:校验页面请求的参数的合法性。在服务端控制层conroller校验,不区分客户端类型(浏览器、手机客户端、远程调用)

业务层service(使用较多):主要校验关键业务参数,仅限于service接口中使用的参数。

持久层dao:一般是不校验的。

4.2       springmvc校验需求

springmvc使用hibernate的校验框架validation(和hibernate没有任何关系)。

校验思路:

页面提交请求的参数,请求到controller方法中,使用validation进行校验。如果校验出错,将错误信息展示到页面。

具体需求:

商品修改,添加校验(校验商品名称长度,生产日期的非空校验),如果校验出错,在商品修改页面显示错误信息。

4.3       环境准备

hibernate的校验框架validation所需要jar包:

4.4      配置校验器

<!-- 校验器 -->
    <bean id="validator"
        class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
        <!-- hibernate校验器-->
        <property name="providerClass" value="org.hibernate.validator.HibernateValidator" />
        <!-- 指定校验使用的资源文件,在文件中配置校验错误信息,如果不指定则默认使用classpath下的ValidationMessages.properties -->
        <property name="validationMessageSource" ref="messageSource" />
    </bean>
<!-- 校验错误信息配置文件 -->
    <bean id="messageSource"
        class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <!-- 资源文件名-->
        <property name="basenames">
            <list>
            <value>classpath:CustomValidationMessages</value>
            </list>
        </property>
        <!-- 资源文件编码格式 -->
        <property name="fileEncodings" value="utf-8" />
        <!-- 对资源文件内容缓存时间,单位秒 -->
        <property name="cacheSeconds" value="120" />
    </bean>

4.5       校验器注入到处理器适配器中

4.6       在pojo中添加校验规则

4.7       CustomValidationMessages.properties

4.8    捕获校验错误信息

4.9      在页面显示校验错误信息

4.10   分组校验

4.10.1     需求

在pojo中定义校验规则,而pojo是被多个 controller所共用,当不同的controller方法对同一个pojo进行校验,但是每个controller方法需要不同的校验。

解决方法:

定义多个校验分组(其实是一个java接口),分组中定义有哪些规则

每个controller方法使用不同的校验分组

4.10.2     校验分组

4.10.3    在校验规则中添加分组

4.10.4    在controller方法使用指定分组的校验

5       数据回显

5.1       什么数据回显

提交后,如果出现错误,将刚才提交的数据回显到刚才的提交页面。

5.2       pojo数据回显方法

1、springmvc默认对pojo数据进行回显。

pojo数据传入controller方法后,springmvc自动将pojo数据放到request域,key等于pojo类型(首字母小写)

使用@ModelAttribute指定pojo回显到页面在request中的key

2、@ModelAttribute还可以将方法的返回值传到页面

在商品查询列表页面,通过商品类型查询商品信息。

在controller中定义商品类型查询方法,最终将商品类型传到页面。

页面上可以得到itemTypes数据。

3、使用最简单方法使用model,可以不用@ModelAttribute

5.3      简单类型数据回显

使用最简单方法使用model。

model.addAttribute("id", id);

6      异常处理

6.1       异常处理思路

系统中异常包括两类:预期异常和运行时异常RuntimeException,前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发、测试通过手段减少运行时异常的发生。

系统的dao、service、controller出现都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理,如下图:

springmvc提供全局异常处理器(一个系统只有一个异常处理器)进行统一异常处理。

6.2      自定义异常类

对不同的异常类型定义异常类,继承Exception。

6.3      全局异常处理器

思路:

系统遇到异常,在程序中手动抛出,dao抛给service、service给controller、controller抛给前端控制器,前端控制器调用全局异常处理器。

全局异常处理器处理思路:

解析出异常类型

如果该 异常类型是系统 自定义的异常,直接取出异常信息,在错误页面展示

如果该 异常类型不是系统 自定义的异常,构造一个自定义的异常类型(信息为“未知错误”)

springmvc提供一个HandlerExceptionResolver接口

6.4     错误页面

6.5       在springmvc.xml配置全局异常处理器

6.6      异常测试

在controller、service、dao中任意一处需要手动抛出异常。

如果是程序中手动抛出的异常,在错误页面中显示自定义的异常信息,如果不是手动抛出异常说明是一个运行时异常,在错误页面只显示“未知错误”。

在商品修改的controller方法中抛出异常 .

在service接口中抛出异常:

如果与业务功能相关的异常,建议在service中抛出异常。

与业务功能没有关系的异常,建议在controller中抛出。

上边的功能,建议在service中抛出异常。

7  上传图片

7.1       需求

在修改商品页面,添加上传商品图片功能。

7.2       springmvc中对多部件类型解析

在 页面form中提交enctype="multipart/form-data"的数据时,需要springmvc对multipart类型的数据进行解析。

在springmvc.xml中配置multipart类型解析器。

7.3      加入上传图片的jar

上边的解析内部使用下边的jar进行图片上传。

7.4    创建图片虚拟 目录 存储图片

通过图形界面配置:

也可以直接修改tomcat的配置:

在conf/server.xml文件,添加虚拟 目录 :

注意:在图片虚拟目录 中,一定将图片目录分级创建(提高i/o性能),一般我们采用按日期(年、月、日)进行分级创建。

7.5     上传图片代码

7.5.1     页面

7.5.2     controller方法

修改:商品修改controller方法:

8     json数据交互

8.1       为什么要进行json数据交互

json数据格式在接口调用中、html页面中较常用,json格式比较简单,解析还比较方便。

比如:webservice接口,传输json数据.

8.2       springmvc进行json交互

1、请求json、输出json,要求请求的是json串,所以在前端页面中需要将请求的内容转成json,不太方便。

2、请求key/value、输出json。此方法比较常用。

8.3       环境准备

8.3.1     加载json转的jar包

springmvc中使用jackson的包进行json转换(@requestBody和@responseBody使用下边的包进行json转),如下:

8.3.2     配置json转换器

在注解适配器中加入messageConverters

<!--注解适配器 -->
    <beanclass="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
        <propertyname="messageConverters">
        <list>
        <beanclass="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
        </list>
        </property>
    </bean>

注意:如果使用<mvc:annotation-driven /> 则不用定义上边的内容。

8.4      json交互测试

8.4.1     输入json串,输出是json串

8.4.1.1              jsp页面

使用jquery的ajax提交json串,对输出的json结果进行解析。

8.4.1.2              controller

8.4.1.3      测试结果

8.4.2   输入key/value,输出是json串

8.4.2.1            jsp页面

使用jquery的ajax提交key/value串,对输出的json结果进行解析。

8.4.2.2           controller

8.4.2.3            测试

9     RESTful支持

9.1       什么是RESTful

RESTful架构,就是目前最流行的一种互联网软件架构。它结构清晰、符合标准、易于理解、扩展方便,所以正得到越来越多网站的采用。

RESTful(即Representational State Transfer的缩写)其实是一个开发理念,是对http的很好的诠释。

1、对url进行规范,写RESTful格式的url

非REST的url:http://...../queryItems.action?id=001&type=T01

REST的url风格:http://..../items/001

特点:url简洁,将参数通过url传到服务端

2、http的方法规范

不管是删除、添加、更新。。使用url是一致的,如果进行删除,需要设置http的方法为delete,同理添加。。。

后台controller方法:判断http方法,如果是delete执行删除,如果是post执行添加。

3、对http的contentType规范

请求时指定contentType,要json数据,设置成json格式的type。。

9.2       REST的例子

9.2.1     需求

查询商品信息,返回json数据。

9.2.2     controller

定义方法,进行url映射使用REST风格的url,将查询商品信息的id传入controller .

输出json使用@ResponseBody将java对象输出json。

9.2.3    REST方法的前端控制器配置

9.3     对静态资源的解析

配置前端控制器的url-parttern中指定/,对静态资源的解析出现问题:

在springmvc.xml中添加静态资源解析方法。

10     拦截器

10.1       拦截定义

定义拦截器,实现HandlerInterceptor接口。接口中提供三个方法。

package cn.dzq.ssm.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

/**
 * 测试拦截器1
 * @author 小强
 *
 */

public class HandlerIntercepter1 implements HandlerInterceptor{

    //在进入handler之前执行
    //用于身份认证、身份授权
    //比如身份认证,如果认证通过,表示当前用户没有登录,需要此方法拦截,不执行

    @Override
    public boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler) throws Exception {
        //return false表示拦截,不再向下执行
        //return true表示放行
        return false;
    }

    //在进入handler方法之后,返回modelandview之前执行
    //应用场景从modelAndView出发:将公用的模型数据(比如菜单导航)在这里传到视图,也可以在这里统一指定视图
    @Override
    public void postHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {

    }

    //执行handler完成之后执行
    //应用场景:统一异常处理,统一日志处理
    @Override
    public void afterCompletion(HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception ex)
            throws Exception {

    }

}

10.2       拦截器配置

10.2.1     针对HandlerMapping配置

springmvc拦截器针对HandlerMapping进行拦截设置,如果在某个HandlerMapping中配置拦截,经过该 HandlerMapping映射成功的handler最终使用该 拦截器。

<bean
    class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
    <propertyname="interceptors">
        <list>
            <refbean="handlerInterceptor1"/>
            <refbean="handlerInterceptor2"/>
        </list>
    </property>
</bean>
    <beanid="handlerInterceptor1"class="springmvc.intercapter.HandlerInterceptor1"/>
    <beanid="handlerInterceptor2"class="springmvc.intercapter.HandlerInterceptor2"/>

一般不推荐使用。

10.2.2     类似全局的拦截器

springmvc配置类似全局的拦截器,springmvc框架将配置的类似全局的拦截器注入到每个HandlerMapping中。

10.3       拦截测试

10.3.1     测试需求

测试多个拦截器各各方法执行时机。

10.3.2    编写两个拦截

10.3.3    两个拦截器都放行

HandlerInterceptor1 ... beforeHandle
HandlerInterceptor2 ... beforeHandle

HandlerInterceptor2 ... postHandle
HandlerInterceptor1 ... postHandle

HandlerInterceptor2 ... afterCompletion
HandlerInterceptor1 ... afterCompletion

总结:

preHandle方法按顺序执行,

postHandle和afterCompletion按拦截器配置的逆向顺序执行。

10.3.4     拦截器1放行,拦截器2不放行

HandlerInterceptor1 ... beforeHandle
HandlerInterceptor2 ... beforeHandle
HandlerInterceptor1 ... afterCompletion

总结:

拦截器1放行,拦截器2 preHandle才会执行。

拦截器2 preHandle不放行,拦截器2 postHandle和afterCompletion不会执行。

只要有一个拦截器不放行,postHandle不会执行。

10.3.5    拦截器1不放行,拦截器2不放行

HandlerInterceptor1...preHandle

拦截器1 preHandle不放行,postHandle和afterCompletion不会执行。

拦截器1 preHandle不放行,拦截器2不执行。

10.3.6    小结

根据测试结果,对拦截器应用。

比如:统一日志处理拦截器,需要该 拦截器preHandle一定要放行,且将它放在拦截器链接中第一个位置。

比如:登陆认证拦截器,放在拦截器链接中第一个位置。权限校验拦截器,放在登陆认证拦截器之后。(因为登陆通过后才校验权限)

10.4      拦截器应用(实现登陆认证)

10.4.1     需求

1、用户请求url

2、拦截器进行拦截校验

如果请求的url是公开地址(无需登陆即可访问的url),让放行

如果用户session 不存在跳转到登陆页面

如果用户session存在放行,继续操作。

10.4.2    登陆controller方法

10.4.3    登陆认证拦截实现

10.4.3.1              代码实现

10.4.3.2              拦截器配置

时间: 2024-11-05 23:35:33

20160611-20160714springmvc入门进阶的相关文章

Hadoop入门进阶步步高(六)-Hadoop1.x与Hadoop2的区别

六.Hadoop1.x与Hadoop2的区别 1.变更介绍 Hadoop2相比较于Hadoop1.x来说,HDFS的架构与MapReduce的都有较大的变化,且速度上和可用性上都有了很大的提高,Hadoop2中有两个重要的变更: l HDFS的NameNodes可以以集群的方式布署,增强了NameNodes的水平扩展能力和可用性: l MapReduce将JobTracker中的资源管理及任务生命周期管理(包括定时触发及监控),拆分成两个独立的组件,并更名为YARN(Yet Another Re

Hadoop入门进阶步步高(一)-环境准备

前言 Hadoop从存储上来说,是类似于冗余磁盘阵列(RAID)的存储方式,将数据分散存储并提供以提供吞吐量,它的存储系统就是HDFS(Hadoop Distuibute Fils System):从计算上来说,它通过MapReduce模型,将大数据的计算分发到多台计算机上完成,再将结果合并,减少计算的时间. Hadoop适合于: 1.超大数据的计算: 2.一次写入.多次读取的模式: 3.可以跑在普通的硬件上. Hadoop不适合: 1.低延迟的数据访问,它是为高数据吞吐量应用优化的: 2.大量

Hadoop入门进阶步步高(二)-目录介绍

二.Hadoop目录结构 这里重点介绍几个目录bin.conf及lib目录. 1.$HADOOP_HOME/bin目录 文件名称 说明 hadoop 用于执行hadoop脚本命令,被hadoop-daemon.sh调用执行,也可以单独执行,一切命令的核心 hadoop-config.sh Hadoop的配置文件 hadoop-daemon.sh 通过执行hadoop命令来启动/停止一个守护进程(daemon). 该命令会被bin目录下面所有以"start"或"stop&quo

Hadoop入门进阶步步高(三)-配置Hadoop

三.配置Hadoop 1.设置$HADOOP_HOME/conf/hadoop-env.sh 这个文件中设置的是Hadoop运行时需要的环境变量,在1.2.1版中共有19个环境变量,如下: 变量名称 默认值 说明 JAVA_HOME 设置JDK的路径,这个必须设置,否则Hadoop无法启动,值如: /usr/local/jdk1.6.0_33 HADOOP_CLASSPATH 空 这个用以设置用户的类路径,也可以在执行计算之前设置 HADOOP_HEAPSIZE 1000m 设置Hadoop堆的

Hadoop入门进阶步步高(四)-测试Hadoop

四.测试Hadoop 一个简单的求每年温度最大值的程序. 1.准备两个文本测试数据 准备两个名为data1.txt及data2.txt的文件,用于做为计算的输入数据,将其放于/home/fenglibin/java/data目录下: data1.txt data2.txt 1999 10 1999 20 1999 25 2000 21 2000 22 2000 18 2000 40 2001 45 2001 65 2002 90 2002 89 2002 70 2003 40 2003 80 1

Hadoop入门进阶步步高(五)-搭建Hadoop集群

五.搭建Hadoop集群 上面的步骤,确认了单机可以执行Hadoop的伪分布执行,真正的分布式执行无非也就是多几台slave机器而已,配置方面的有一点点区别,配置起来就非常简单了. 1.准备三台服务器 192.168.56.101 192.168.56.102 192.168.56.103 在每台机器的/etc/hosts中都将ip及hostname给映射上: 192.168.56.101  nginx1 192.168.56.102  nginx2 192.168.56.103  nginx3

Spring3.0 入门进阶(6):自定义校验器

在Spring 3 中,对表单提交的校验方式比较常见的有两种 (1)基于注解:对于简单的属性校验,例如,长度,非空等,可以使用Spring,或是Hibernate自带的校验注解 (2)自定义校验类:对于复杂的业务校验可以自定义校验类,该类继承自org.springframework.validation.Validator (3)前台JS校验 增加表单校验功能大概分一下几个步骤 定义校验规则 基于注解的验证 只需要在相关的实体字段上添加校验注解即可,下面的例子基于hibernate的校验标签 i

全网最热Python3入门+进阶 更快上手实际开发

详情请咨询  QQ  709639943 01.Python Flask 构建微电影视频网站 02.Python3 全网最热的Python3入门+进阶 比自学更快上手实际开发 03.Python3.6 强力Django+杀手级Xadmin打造上线标准的在线教育平台 04.python_进阶强化 05.Java秒杀系统方案优化 高性能高并发实战 06.企业级刚需Nginx入门,全面掌握Nginx配置+快速搭建高可用架构 07.快速上手Linux 玩转典型应用 08.全面系统讲解CSS 工作应用+面

全面系统Python3入门+进阶课程 ??

全面系统Python3入门+进阶课程 Python语言本身就是一门简单的语言,入门非常容易. 机器学习中用到的Python(语法)相对就更简单了. 本文从机器学习的视角来看需要具备的Python基础. 我们的目标是-- 没有蛀牙... 针对一个程序员(如Java程序员),在1个小时内学会足够机器学习中使用到的Python语法. 1. Python简介 Python是著名的“龟叔”Guido van Rossum在1989年圣诞节期间,为了打发无聊的圣诞节而编写的一个编程语言. Guido van

javascript入门进阶(一)

javascript 入门进阶 这里主要讲解一下在入门阶段很难注意的一些知识点,不一定有用.但是会了总比不会强. 1.HTML为<script>标签准备的6个属性: -async:可选.表示应该立刻下载脚本,但不应妨碍页面中的其他操作.(其他的下载可以等待) -charset:可选.表示通过src指定的代码的字符集. -defer:可选.表示脚本可以延迟到文档被解析和显示之后在执行.该版本值对外部JavaScript有效果 -src:可选.执行代码的外部文件. --type:可选.编写代码使用