springMvc学习笔记

来源:互联网 发布:性教育读本 知乎 编辑:程序博客网 时间:2024/06/10 07:13

转换器

SpringMvc上下文中内建了很多转换器,可以完成大多数Java类型的转换工作。
ConversionService是Spring类型转换体系的核心接口。
可以利用ConversionServiceFactoryBean
在Spring的IOC容器中定义一个
ConversionService.Spring将自动识别出IOC容器中的ConversionService,并在Bean属性配置及SpringMvc处理方法入参绑定等场合使用它进行数据的绑定。
可通过ConversionServiceFactoryBean的converters 属性注册自定义的类型转换器。

Spring 定义了3种类型的转换器接口,实现任意一个转换器接口都可以作为自定义转换器注册到
ConversionServiceFactoryBean中

这里写图片描述

三个问题

  1. 数据类型转换
  2. 数据类型格式化
  3. 数据校验

数据绑定流程

  1. SpringMvc主框架将ServletRequest对象及目标方法的入参实例传递给
    WebDataBinderFactory实例,以创建DataBinder 实例对象
  2. DataBinder调用装配在SpringMvc上下文中的ConversionService组件进行数据类型转换,数据格式化工作,将servlet 中的请求信息填充到入参对象中
  3. 调用Validator 组件对已经绑定了请求消息的入参对象进行数据合法性校验,并最终生成数据绑定结果BindingData 对象
  4. Spring Mvc 抽取BindingResult中的入参对象和校验错误对象,将它们赋给处理方法的响应参数

这里写图片描述

数据绑定的核心部件是DataBinder

  1. validators
  2. ConversionService
  3. BindingResult

自定义转换器<mvc:annotation-driven conversion-service="conversionService"/>
会将自定义的ConversionService注册到Spring Mvc的上下文中

<mvc:annotation-driven conversion-service="conversion"></mvc:annotation-driven> <bean id="conversion" class="org.springframework.context.support.ConversionServiceFactoryBean">    <property name="converters" >        <set>            <ref bean="employeeConversion"/>        </set>    </property> </bean>

employeeConversion是我实现Converter接口的一个转换器方法

annotation-driven的作用

以前处理静态资源和直接

开发时候通常要加上这个配置<mvc:annotation-driven conversion-service="conversion"></mvc:annotation-driven>

  • 会自动注册
  • RequestMappingHandlerMapping
  • RequestMappingHandlerAdapter
  • ExceptionHandlerException
  • 三个bean
  • 还将提供以下支持
  • 支持使用ConversionService 实例对表单参数进行类型转换
  • 支持使用@NumberFormatannotation @DateTimeFormat注解完成数据类型的格式化
  • 支持使用@Valid 注解对javaBean实例进行JSR 303验证
    • 支持使用@RequestBody和@ResponseBody注解

从下图中可见,配置<mvc:default-servlet-handler/>
会消失AnnotationMethodHandlerAdapter,无法对RequestMapping映射的url配置,加上annotation-driven后,就添加了RequestMappingHandlerAdapter
另外,配置annotation-driven
后,在Binder里面会创建默认的DefaultConversionFormattingService

这里写图片描述

@InitBinder

  • 由@InitBinder标识的方法,可以对WebDataBinder
    对象进行初始化,WebDataBinder是DataBinder的子类,用于完成由表单字段到JavaBean 属性的绑定
  • @InitBinder方法不能有返回值,它必须声明为void
  • @InitBinder 方法的参数通常是WebDataBinder

格式转换

  • annotation-driven会自动配置一个DefaultFormattingConversionService
  • Spring在格式化模块中定义了一个实现ConversionService接口的FormattingConversionService
    实现类,该实现类扩展了GenericConversionService,因此既有类型转换的功能,又有格式化的功能

这里写图片描述

  1. 如果要自定义一个数据转换格式化
<mvc:annotation-driven conversion-service="conversion" ></mvc:annotation-driven> <bean id="conversion" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">    <property name="converters" >        <set>            <ref bean="employeeConversion"/>        </set>    </property> </bean>

错误信息的设置

在DataBind进行参数绑定的时候,错误信息会存储到BindingResult对象里面

“`
@RequestMapping(value=”/emp”,method=RequestMethod.POST)
public String add(Employee employee, BindingResult result){
System.out.println(“employee”+employee);

    if (result.getErrorCount()>0) {        System.out.println("出错了");        for(FieldError error:result.getFieldErrors()){          System.out.println(error.getField()+":"+error.getDefaultMessage());}    }    employeeDao.save(employee);    return "redirect:/emps";}```

数据校验

数据校验分为以下几个步骤

  • 导入hibernate-validator jar包和依赖包
  • 在相应的bean属性上进行注解
  • 在需要校验入参的方法里进行注解@validate
  • 错误信息的显示,使用

    jstl的form标签可以用于回显,但是具体实现是如何的,不得而知

错误消息的定制

  • 写国际化资源文件
  • 在bean-configuration里面配置资源文件
  • 注意(资源文件的键由 ,校验注解类名为前缀,域中的键名,属性名组成NotEmpty.employee.lastName

处理Json

步骤如下
- 加入jar包,jackson
- 编写目标方法,使其返回JSON对应的对象或集合
- 在方法上添加@ResponseBody 注解

原理

  • HttpMessageConverter是Spring3.0新添加的一个接口,负责将请求信息转换为一个对象(类型为T),将对象输出为响应信息

    这里写图片描述
    三个对象

  • httpInputMessage
  • httpOutputMessage
  • httpMessageConverter

httpMessageConverter有很多的实现类

这里写图片描述

在加入上述jar包后

这里写图片描述

这里写图片描述

国际化资源文件的配置

问题概述

  • 在页面上能够根据浏览器客户端语言的设置情况对文本,时间,数值,进行国际化处理
  • 如何在bean中获取国际化资源文件Locale对应的消息
  • 可以通过超链接切换Locale,而不再依赖于浏览器的语言设置情况
    -

解决步骤

  • 使用jstl的fmt标签
  • 在bean中注ResourceBundleMessageResource 的示例,使用其对应的getMessage 方法
  • 可以通过超链接切换locale,而不再依赖于浏览器的语言设置

第一个解决步骤

  • 在source文件夹下配置资源文件i18n.properties
  • 在beanConfiguration.xml文件里面配置bean如下:
    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
    <property name="basename" value="i18n"></property>
    </bean>

  • 在网页端配置<fmt:message key="i18n" >

第二个问题的解决过程


  • @Autowired
    private ResourceBundleMessageSource messageSource;
    @RequestMapping("/i18n")
    public String i18n(Locale locale){
    String val=messageSource.getMessage("i18n.user", null, locale);
    System.out.println("val"+val);
    return "i18n";
    }

第三个问题的解决方法

原理
这里写图片描述

  1. 配置sessionlocaleresolver


<‘bean id=”localeResolver” class=”org.springframework.web.servlet.i18n.SessionLocaleResolver”>

<’mvc:interceptors>
<‘bean class=”org.springframework.web.servlet.i18n.LocaleChangeInterceptor”>

注意,需要把解析器的id设置为localeResolver,否则会出现无法解析的错误

文件上传

这里写图片描述

  • 加入jar包,commons-io,commons-fileupload
  • 在上下文中进行配置

自定义拦截器

这里写图片描述

三个方法

  • prehandle
  • 该方法在目标方法之前被调用
  • 该返回值若为true,则继续调用后续的拦截器和目标方法
  • 若返回值为false,则不会再调用后续的拦截器和目标方法
  • 作用
  • 可以考虑做权限,日志,事务
  • posthandle
  • 调用目标方法之后,渲染视图之前,可以对请求域中的属性或视图做出修改
  • afterCompletion
  • 渲染视图之后被调用,用来释放资源

这里写图片描述

这里写图片描述

不经过handler直接跳转的配置

  1. <mvc:view-controller path="/i18n" view-name="i18n"/>

为静态资源文件配置默认servlet

  • <mvc:default-servlet-handler/>

异常处理

这里写图片描述

接下来分别介绍这三个异常处理类

  • ExceptionHandlerExceptionResolver
  • ResponseStatusExceptionResolver
  • DefaultHandlerExceptionResolver

这里写图片描述

专门配置一个类来处理异常:代码

`@ControllerAdvice
public class ExceptionHandlers {

@ExceptionHandler({ArithmeticException.class})public ModelAndView handlerArithmeticException(Exception ex){    System.out.println("ok? 出异常了:"+ex);    ModelAndView mvAndView=new ModelAndView("error");    mvAndView.addObject("exception", ex);    return mvAndView;    }

}`

在处理器中配置一个异常处理

如下
@ExceptionHandler({ArithmeticException.class})
public ModelAndView handlerArithmeticException(Exception ex){
System.out.println("出异常了:"+ex);
ModelAndView mvAndView=new ModelAndView("error");
mvAndView.addObject("exception", ex);
return mvAndView;
}

注意

  1. 在@ExceptionHandler 方法的入参中可以加入Exception类型的参数,该参数即对应发生的异常对象
  2. @ExceptionHandler 方法的入参中不能传入Map,若希望把异常信息传到页面上,需要使用ModelAndView作为返回值
  3. @ExceptionHandler方法标记的异常有优先级的问题
  4. 如果在当前Handler中找不到@ExceptionHandler方法来处理当前方法出现的异常,则将去@ControllerAdvice标记的类中查找@ExceptionHandler

ResponseStatusExceptionResolver

作用:实现定制状态码和错误信息,既可以注解一个类,也可以注解一个方法

这里写图片描述

@ResponseStatus(reason=”测试”,value=HttpStatus.NOT_FOUND)
@RequestMapping(“testResponseStatusExceptionResolver”)
public String testResponseStatusExceptionResolver(@RequestParam(“i”)int i){
if(i==4){
throw new UserNameNotMatchPasswordException();
}
System.out.println(“testResponseStatusExceptionResolver”);

    return "success";}

++++++++++++++++++++++++++++++++++++++++++++

@ResponseStatus(value=HttpStatus.FORBIDDEN,reason=”用户名和密码不匹配”)
public class UserNameNotMatchPasswordException extends RuntimeException {
private static final long serialVersionUID = 1L;

}

SimpleMappingExceptionResolver

  1. 仅需要在xml文件里面进行配置即可
  2. 但是props的key需要相应错误的类名,如果发生该错误,就会进行映射

这里写图片描述

springMvc的运行流程

这里写图片描述

Spring和SpringMvc环境的整合

两种观点

  1. 将数据资源,事务,整合其它框架,以及service,dao等配置在Spring的配置文件中,而controller配置在springMvc文件中,做到条理分明,需要在web.xml里面配置启动SpringIOC容器的ContextListener的监听器
  2. 也可以分多个spring的文件,然后用import导入同一个spring文件中,或者使用通配符

建议使用第一种

解决方法

  1. 利用context:exclude-filter和context:include-filter,避免重合的问题
  2. 使springmvc和spring的容器扫描的包没有重合的部分。但是比较麻烦
原创粉丝点击