一、HelloWorld程序

(1)导包:四个spring 核心包(core、beans、context、expression)、一个aop包、两个 web 包和一个logging 包;

(2)配置 web xml 就是配置一个 dispatcherServlet,设置开机自启,指定springmvc配置文件位置(init-param);

(3)配置springmvc文件,就是一个包扫描和一个视图解析器(前后缀),还有注解驱动的配置!!!

(4)写一个类用@controller 标记,其中的方法用@requestMapping来实现和url 的映射关系;

(5)出现 classnotfound,idea 环境下打开 projectstructure --problems--fix 即可;

(6)配置文件参考如下:

<!--web xml config-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
</init-param>
<!--<load-on-startup>1</load-on-startup>-->
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--springmvc config-->
<!-- 包扫描 -->
<context:component-scan base-package="com.stan.hello"/>
<!-- 静态资源处理 -->
<mvc:default-servlet-handler />
<!-- springmvc 注解驱动 -->
<mvc:annotation-driven />
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
id="internalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>

二、注解开发

1、@requestMapping 注解

  • 可以用在方法和类上,起到窄化请求的作用;
  • 其中的属性还包含 method、param 和 header,都是更加精确请求的作用;
  • @PathVariable 注解指定 url 占位符(/hello/{name})和方法参数之间的映射;

2、参数相关注解

(1)@RequestParam注解

  • 作用就是将请求参数映射到方法参数;
  • 注解有三个属性:value(请求参数的名字)、required(默认为true)、defaultValue(请参的默认值);
  • 请求参数名称和方法参数名称相同的时候不用设置value的值即可完成映射,不同的时候要设置 value 的值为请求参数的名称;
  • @RequestHeader 和 @CookieValue 注解:作用就是将请求头和cookie 的信息映射到方法的参数;注解的属性和用法都和requestParam 差不多;

(2)请求参数映射到 pojo

  • 保证请求参数的名字和 pojo 的属性名一致即可自动完成映射,还支持级联属性;
  • 名字不一则无法映射,相应的值为 null;

(3)方法参数还支持 servlet 的原生 API,支持的类型包括:

  • request、response、session、Principal
  • InputStream、outputStream、reader、writer

3、目标方法 pojo 类型入参过程

(1)@ModelAttribute注解:

  • 这个注解标记的方法会在每个目标方法执行前被执行;
  • 修饰目标方法参数:指定 pojo 的键名;

(2)pojo 入参过程

  • key 和 pojo 保存在 implicitModel 中,进而保存到 request 中;
  • 第一步先去 implicitModel(map) 中去找,用默认的键名去匹配(类名首字母小写),当然也可以用 @ModelAttribute 指定键名去匹配,找到了就入参;
  • implicitModel 中的 pojo 对象来源于 @ModelAttribute 修饰的方法中存入到 map 中的 pojo 对象;
  • implicitModel 中找不到,当前的 Controller 又用了 @SessionAttributes 注解进行修饰的话,就去 session 中根据相应的键名去匹配,找到入参,没有则抛出异常;
  • 如果没有 @SessionAttributes 或者键值不包括在注解的值里面的话,则会通过反射来创建一个新的 pojo 对象作为方法入参;
  • 总结:键名----- implicitModel ------session-------(反射生成新对象)-------对象属性设置为相应的请求参数的值-------赋值给目标方法的参数

 (3)使用 @sessionAttributes 注解抛出异常的解决方法

  • sessionAttributes 中的名称和方法参数 modelAttribute 中指定的名称不一致即可;
  • 要么就是必须得有 modelAttribute  标记的方法,保证能够取到 sessionAttributes 名称对应的对象就不会抛异常;
  • 干脆不用这个注解也可以;

4、模型数据处理

4.1 方法可以添加 Map 或者 Model 类型的参数

4.2 方法返回 ModelAndView

  • mv 可以包含视图和模型的信息;
  • 最终这些数据都是存放到 request 域中;

4.3 再说 @sessionAttributes

  • 注解的作用:就是将 request 域中的模型数据备份一份到 session,方便不同的请求之间共享;
  • 使用时注意:这个注解是类注解,不能修饰方法;既可通过名称也可通过类型指定放到 session 中的数据(@SessionAttributes(value={"names"},types={Integer.class}));
  • 示例请参考:https://www.cnblogs.com/caoyc/p/5635914.html

5、视图解析

5.1 视图解析流程

  • 目标方法无论返回的是 string、model还是 mv,最终都是包装成 modelAndView返回;
  • 视图的作用:渲染模型数据;
  • 视图解析器的作用:将逻辑视图转换为物理视图;
  • 常用的视图解析器:BeanNameViewResolver 和 InternalResourceViewResolver;配置多个解析器的话存在优先级的;

5.2 自定义视图和重定向

  • 自定义视图:实现view 接口,重写 render 方法;最后还要在 springmvc 的配置文件中配置beanNameViewresolver,注意解析器的优先级;
  • 转发和重定向:就是在 return 的 String 中加入前缀 forward: 或者 redirect:
  • view-controller 标签:view-controller 可实现直接将请求跳转到视图,不用经过 controller;

三、RESTful风格CRUD

1、CRUD 示例

  • 新增:/order       post
  • 删除:/order/1    delete
  • 修改:/order/1    put
  • 查询:/order/1    get

2、发送 put | delete 请求

  • web xml 中配置 HiddenhttpMethodFilter;
  • 表单中增加一个 name=_method  value=delete 或 put 的隐藏域,发送 post 请求;
  • a 标签的 get 请求转 post ,js中用return false 阻止 a 标签默认行为,再通过 ajax 发送一个 post 请求即可;

3、表单标签|静态资源映射配置

3.1 spring 表单标签

  • 自带数据的回显功能;
  • 数据回显的前提是 form 的 commandName属性的值要和 request 域中存放的 pojo 对象的键值一致;
  • 还支持级联属性的写法;
<form:form action="/mvc/rest/user" method="post" commandName="user">
编号:<form:input path="id"/><br>
姓名:<form:input path="name"/><br>
余额:<form:input path="balance"/><br>
<input type="submit" value="提交">
</form:form>
<!-- 如果request中取不到 user ,则会报异常,需要在之前手动加一个 user 进去 -->

3.2 静态资源映射配置

<mvc:default-servlet-handler></mvc:default-servlet-handler>
<mvc:annotation-driven></mvc:annotation-driven>

4、关于转发和重定向

  • controller 方法里 return String 默认是作为逻辑视图,要进行 controller 间的转发或者重定向要在前面加上 forward 和 redirect;
  • 关于转发和重定向的路径问题:绝对路径(/)默认就是在当前的项目下,相对路径是在当前的controller 内;

四、数据处理

1、数据绑定(DataBinder)

(1)基本流程

(2)数据转换:springmvc 内置了很多类型转换器,一般情况下不需要我们自己写;

(3)自定义类型转换器

  • 第一步:实现 Converter<S,T>接口,重写方法实现想要的类型转换;
  • 第二步:在 spring 的 ioc 容器中配置convertionService;
  • 第三步:mvc:annotion-driven注解中配置 convertionService,将这个注册到 springmvc 的上下文中;
<mvc:annotation-driven conversion-service="conversionService2"></mvc:annotation-driven>
<!-- myconveter config-->
<bean id="conversionService2" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.stan.test.MyConverter"></bean>
</set>
</property>
</bean>

(4)关于mvc:annotation-driven

  • 这个标签会自动注册RequestMappingHandlerMapping(处理器映射器) 、RequestMappingHandlerAdapter(处理器适配器)、ExceptionHandlerExceptionResolver(异常解析器) 三个bean;
  • 此外还支持配置convertionService,还支持格式化注解(@NumberFormat annotation、@DateTimeFormat)验证注解(@Valid)请求响应体注解(@RequestBody 和 @ResponseBody)

(5)@InitBinder 注解

  • WebDataBinder 是 DataBinder 的子类,用于完成由表单字段到 JavaBean 属性的绑定 ;
  • @InitBinder 标识的方法,可以对 WebDataBinder 对象进行初始化;
  • @InitBinder方法不能有返回值,必须声明为void;
  • @InitBinder方法的参数通常是WebDataBinder;
@RequestMapping("object")
@ResponseBody
public String object(User user,Admin admin) {
return user.toString()+" "+admin.toString();
} @InitBinder("user")
public void initUser(WebDataBinder binder) {
binder.setFieldDefaultPrefix("user.");
} @InitBinder("admin")
public void initAdmin(WebDataBinder binder) {
binder.setFieldDefaultPrefix("admin.");
}

2、数据格式化

(1)使用前提

  • 数据格式化相关的bean:FormattingConversionServiceFactroyBean;
  • <mvc:annotation-driven/> 默认创建的ConversionService 实例即为FormattingConversionServiceFactroyBean;
  • 如果自定义类型转换器配置了 conversionService 一定要手动配置 FormattingConversionServiceFactroyBean;
<mvc:annotation-driven conversion-service="conversionService3"/>
<bean id="conversionService3" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.stan.data.MyConverter"></bean>
</set>
</property>
</bean>

(2)日期格式化和数值格式化示例(参考:https://www.cnblogs.com/dj-blog/p/7534907.html

@DateTimeFormat(pattern="yyyy-MM-dd")
private Date birth;
@NumberFormat(pattern="#,###,###.#")
private Float salary;

3、数据校验

(1)校验框架

  • JSR-303(Bean Validation) 是JAVAEE6中的一项子规范,用于 bean 数据合法性校验;
  • Hibernate Validator 是JSR303的参考实现,提供了 JSR 303 规范中所有内置 constraint 的实现,还有一些附加的 constraint;

(2)可以实现的校验

Constraint 详细信息
@Null 被注释的元素必须为 null
@NotNull 被注释的元素必须不为 null
@AssertTrue 被注释的元素必须为 true
@AssertFalse 被注释的元素必须为 false
@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max, min) 被注释的元素的大小必须在指定的范围内
@Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past 被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期
@Pattern(value) 被注释的元素必须符合指定的正则表达式
Hibernate Validator 独有的注解  
@Email 被注释的元素必须是电子邮箱地址
@Length 被注释的字符串的大小必须在指定的范围内
@NotEmpty 被注释的字符串的必须非空
@Range 被注释的元素必须在合适的范围内

(3)校验的流程

  • 实现数据校验的bean:LocalValidatorFactoryBean;
  • annotion-driven 会默认装配好一个 LocalValidatorFactoryBean;
  • 在对应 pojo 的属性字段上加上校验注解;
  • 在处理方法的入参上标注 @valid 注解,入参还可以加一个 bindingResult的参数;
  • 需校验的 Bean 对象和其绑定结果对象bindingResult或错误对象时成对出现的,之间不允许有其他参数;
  • 在方法里获取校验的结果(getFieldError、getFieldErrors、getFieldValue、getErrorCount);
  • 在页面上显示错误( 错误信息会随一个隐含模型传到jsp,页面直接用<form:errors path=“userName”>就可以获取);
//bean里面的字段的写法
@NotEmpty private String lastName;
//controller方法入参的写法
@Valid Employee employee,BindingResult bindingResult

五、JSON处理--国际化--文件上传

1、json 处理

1.1 步骤

  • 加入三个 jackson 的 jar(注意 jar 的版本);
  • 写一个返回值为 json 对应的对象或集合的目标方法;
  • 在目标方法加上 @responseBody 的注解;
@RequestMapping("/json")
@ResponseBody
public List<User> toJson(){
User[] users = {new User(1,"k1",100),new User(2,"k2",100)};
return new ArrayList<>(Arrays.asList(users));
}

1.2 原理(通过 HttpMessageConverter<T> 实现 java对象和json串的相互转换

1.3 spring提供两种使用途径:

  • 使用 @RequestBody(json转java对象)和 @ResponseBody(java对象转json)对目标方法进行标注;
  • 使用 HttpEntity<T> 和 ResponseEntity<T> 作为目标方法的入参或者返回值;

2、国际化

2.1 国际化

​2.1.1 springmvc 配置文件

<!-- 国际化配置 -->
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver"></bean>
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:messages"></property>
</bean>
<mvc:interceptors>
<bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang"></property>
</bean>
</mvc:interceptors>

2.1.2 国际化资源文件

  • messages_zh_CN.properties文件:
language.cn=中文
language.en=英文
welcome=欢迎光临
  • messages_en_US.properties文件:
language.cn=Chinese
language.en=English
welcome=welcome to my house enjoy yourself

2.1.3 页面显示

<h2>国际化测试</h2>
language: <a href="/mvc/rest/locale?lang=zh_CN"><spring:message code="language.cn"></spring:message></a>
<a href="/mvc/rest/locale?lang=en_US"><spring:message code="language.en"></spring:message></a>
<h2><spring:message code="welcome"></spring:message></h2>
locale:${pageContext.response.locale}

2.2 提示消息国际化

  • 建一个国际化properties文件,里面错误的键名类似Pattern.user.password,值是要显示的消息;
  • 在 spring 的ioc 容器里配置一个 messageSource 注册国际化资源文件;

2.3 jstlView

  • 项目加入jstl 的jar,springmvc 自动将视图解析为 jstlView;
  • 若要使用 jstl fmt 标签要在 springmvc 的配置文件中配置一个 messageSource;

3、文件上传

3.1 导入 commons io 和 fileupload 的包;

3.2 IOC 容器中配置 MultipartResolver 实现类;

<!--文件上传配置-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8"></property>
<property name="maxUploadSize" value="1024000"></property>
</bean>

3.3 controller 目标方法

@RequestMapping("/upload")
public String upload(@RequestParam("file") MultipartFile file){
if(file != null){
try {
file.transferTo(new File("d:\\test\\"+file.getOriginalFilename()));
} catch (IOException e) {
e.printStackTrace();
}
}
return "success";
}

3.4 上传页面:必须是post请求,必须设置 enctype

<h1>文件上传测试</h1>
<form action="/mvc/data/upload" enctype="multipart/form-data" method="post">
选择文件:<input type="file" name="file">
<input type="submit" value="开始上传">
</form>
</body>

六、拦截器使用--异常处理

1、拦截器使用

1.1 拦截器的基本使用

  • 写一个类继承 handlerIntercepter,重写三个方法;
  • 在 spring 中配置自己写的拦截器;

1.2 拦截器的配置(拦截所有资源和拦截指定资源)

<mvc:interceptors>
<bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang"></property>
</bean>
<!--拦截所有请求-->
<bean id="myIntercepter" class="com.stan.intercepter.MyIntercepter"></bean>
<!--拦截指定请求 这个映射路径默认是在当前的项目下-->
<mvc:interceptor>
<mvc:mapping path="/inter"/>
<bean id="myIntercepter2" class="com.stan.intercepter.MyIntercepter2"></bean>
</mvc:interceptor>
</mvc:interceptors>

1.3 拦截器各方法执行时机:HandlerIntercepter#preHandle > HandlerAdapter#handle > HandlerIntercepter#postHandle > dispatcherServlet#render > HandlerIntercepter#afterCompletion

1.4 多个拦截器的执行顺序

1.4.1 正常情况

1.4.2 prehandle 有 return false 的情况:​firstIntercepter#prehandle > secondIntercepter#prehandle(return false) > first#afterCompletion

2、异常处理

2.1 Spring 统一异常处理有 3 种方式:使用 @ ExceptionHandler 注解;实现 HandlerExceptionResolver 接口;使用 @controlleradvice 注解;

2.2 使用 @ ExceptionHandler 注解(基于controller)

  • 此方法的局限性在于抛出异常的方法和处理异常的方法必须要在同一个Controller里面;
@RequestMapping("/test")
public void test(){
throw new MyException("haha");
}
@ExceptionHandler({MyException.class})
public String error(){
return "error";
}

2.3 实现 HandlerExceptionResolver 接口(全局异常处理)

@Component
public class ExceptionTest implements HandlerExceptionResolver { @Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
ModelAndView mv = new ModelAndView();
mv.setViewName("error2");
return mv;
}
}

2.4 使用 @controlleradvice 注解(全局异常处理)

@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler({MyException.class})
public String error(){
return "error";
}
}

2.5 关于 @ResponseStatus 注解

  • 修饰自定义异常类;
  • 修饰目标方法和异常处理方法都可以;

七、springmvc运行流程--和spring整合

1、运行流程

  • 图片引用自:https://www.cnblogs.com/gxc6/p/9544563.html

2、和spring整合

  • 参考:https://blog.csdn.net/csdn_kenneth/article/details/78781522

3、和 struts2 比较

  • 参考:https://blog.csdn.net/jishuizhipan/article/details/79385190

java框架之springmvc的更多相关文章

  1. java框架之SpringMVC(1)-入门&整合MyBatis

    前言 SpringMVC简介 SpringMVC 是一个类似于 Struts2 表现层的框架,属于 SpringFramework 的后续产品. 学习SpringMVC的原因 SpringMVC 与 ...

  2. Java框架之SpringMVC 03-RequestMapping-请求数据-响应数据

    SpringMVC SpringMVC是一种轻量级的.基于MVC的Web层应用框架. 通过一套 MVC 注解,让 POJO 成为处理请求的控制器,而无须实现任何接口. 采用了松散耦合可插拔组件结构,比 ...

  3. java框架之SpringMVC(2)-补充及拦截器

    高级参数绑定 package com.zze.springmvc.web.controller; import org.springframework.stereotype.Controller; i ...

  4. Java - 框架之 SpringMVC

    一. 简单配置 (XML) 1. web.xml <?xml version="1.0" encoding="UTF-8"?> <web-ap ...

  5. Java框架之SpringMVC 05-拦截器-异常映射-Spring工作流程

    SpringMVC 拦截器 Spring MVC也可以使用拦截器对请求进行拦截处理,可以自定义拦截器来实现特定的功能,自定义的拦截器可以实现HandlerInterceptor接口中的三个方法,也可以 ...

  6. Java框架之SpringMVC 04-视图解析-Spring表单-JSON-上传下载

    SpringMVC 视图解析 请求处理方法(controller方法)执行完成后,最终返回一个 ModelAndView 对象,即使出现异常也会返回一个 ModelAndView 对象.对于那些返回 ...

  7. Java自学路线图之Java框架自学

    Java自学路线图的框架分为两个阶段,第一阶段的Java框架包含六个内容:MyBatis,Spring,SpringMVC,Maven高级,Git,Dubbo. 在Java自学过程中掌握框架的使用,对 ...

  8. java框架之SpringBoot(5)-SpringMVC的自动配置

    本篇文章内容详细可参考官方文档第 29 节. SpringMVC介绍 SpringBoot 非常适合 Web 应用程序开发.可以使用嵌入式 Tomcat,Jetty,Undertow 或 Netty ...

  9. 2016年7款最佳 Java 框架

    毫无疑问,Java 是目前最为流行的编程语言之一,这里我们挖掘出了一些比较受欢迎的框架的有效信息,它们可以减轻全球软件开发人员的日常工作. RebelLabs的一项调查显示,通过在线Java用户论坛( ...

随机推荐

  1. Git使用详细教程(7):.gitignore使用详解

    Git提供了一个.gitignore文件,帮助我们忽略掉一些不想或者不能提交到版本控制器中的文件.这个文件的使用时必须要掌握的. *.a # 忽略所有目录下的.a结尾的文件 !lib.a # 但lib ...

  2. Kali学习笔记6:二层发现

    先介绍下ARPING命令: arping命令是用于发送ARP请求到一个相邻主机的工具 arping使用arp数据包,通过PING命令检查设备上的硬件地址.能够测试一个IP地址是否是在网络上已经被使用, ...

  3. 一份从0到1的java项目实践清单

    虽说工作就是简单的事情重复做,但不是所有简单的事你都能有机会做的. 我们平日工作里,大部分时候都是在做修修补补的工作,而这也是非常重要的.做好修补工作,做好优化工作,足够让你升职加薪! 但是如果有机会 ...

  4. Oracle开窗函数笔记及应用场景

    介绍Oracle的开窗函数之前先介绍一下分析函数,因为开窗函数也属于分析函数 分析函数用于计算基于组的某种聚合值,它和聚合函数的不同之处是:对于每个组返回多行,而聚合函数对于每个组只返回一行. 上面是 ...

  5. PHP之ThinkPHP框架(数据库)

    PHP是网站后台开发语言,其重要的操作对象莫过于数据库,之前有了解过mysqli和pdo,但ThinkPHP的数据库交互必须使用其特定的封装方法,或者可以认为其是对PHP数据库操作的进一步封装,以达到 ...

  6. 教你使用docker部署淘宝rap2服务

    什么是rap2 先来说说起因,在上一个星期的分享会上,谈到前后端联调上,有同事提到了rap2,特意去了解了一下,觉得使用这个东西来进行前后端的接口联调来真是太方便了,对比我们之前公司内部开发的API ...

  7. 全网最全最详细的Windows下安装Anaconda2 / Anaconda3(图文详解)

    不多说,直接上干货! 说明: Anaconda2-5.0.0-Windows-x86_64.exe安装下来,默认的Python2.7 Anaconda3-4.2.0-Windows-x86_64.ex ...

  8. Mybatis 源码简述

    转载请注明来自:http://www.cnblogs.com/xmzJava/p/8578399.html 日常开发中,mybatis如果报错了调错起来会比较麻烦,因为一层套着一层,如果没有对myba ...

  9. 一款超人气代码格式化工具prettier

    一.prettier 介绍 官方自己介绍说,prettier是一款强势武断的代码格式化工具,它几乎移除了编辑器本身所有的对代码的操作格式,然后重新显示.就是为了让所有用这套规则的人有完全相同的代码.在 ...

  10. Django使用Channels实现WebSocket--下篇

    希望通过对这两篇文章的学习,能够对Channels有更加深入的了解,使用起来得心应手游刃有余 通过上一篇<Django使用Channels实现WebSocket--上篇>的学习应该对Cha ...