springmvc新手入门教程

提示:本篇文章共15000字左右,篇幅比较长,大家可以通过目录点击直达你需要的模块,一篇文章帮你解决springmvc所有常用的知识点!

文章目录

    • 一、springmvc的第一个程序
    • 二、@RequestMapping映射及其属性
    • 三、参数接收:@RequestParam和@PathVariable注解
    • 四、处理模型数据
    • 五、@ModelAttribute详解
    • 六、视图、视图解析器(了解)
    • 七、国际化操作
    • 八、页面跳转常见功能
    • 九、处理静态资源
    • 十、自定义类型转换器
    • 十一、数据的格式化
    • 十二、JSR-303以及Hibernate-Validator后台校验
    • 十三、@ResponseBody处理json数据
    • 十四、文件上传
    • 十五、拦截器
    • 十六、异常处理


一、springmvc的第一个程序

springmvc本质上其实就是一个servlet,他通过前台访问自己内置的servlet然后对数据进行操作,所以说他是web层或者说controller层框架。

<servlet>
        <servlet-name>servlet1</servlet-name>
        <servlet-class>com.test.controller.ServletTest</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>servlet1</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

这是我们在java web时,配置的web.xml文件中的servlet,使用springmvc与其基本是同一个道理
springmvc配置:

<servlet>
		<servlet-name>springDispatcherServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<!-- 配置文件的路径,他是DispatcherServlet类的一个参数 -->
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:spring-mvc.xml</param-value>
		</init-param>
		<!-- 表示启动时立即加载 -->
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet-mapping>
		<--! 这里的名称任意,与上面对应即可,作用是通过映射找到mvc的servlet类 -->
		<servlet-name>springDispatcherServlet</servlet-name>
		<!-- 这里表示servlet请求处理路径,/表示拦截所有的请求 -->
		<url-pattern>/</url-pattern>
	</servlet-mapping>

通过上述方式,即可拦截所有请求,把所有请求都交给SpringMVC的DispatcherServlet去处理

然后我们还需要一个试图解析器:
视图解析器是用来对返回的数据和页面进行解析
在SpringMVC的配置文件中配置一个试图解析器的Bean:

<bean id="viewResolver"
   class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    视图解析器的类为InternalResourceViewResolver
      <property name="prefix" value="/" />
      <property name="suffix" value=".jsp" />
      </bean>

这个类有两个属性:
Prefix:表示前置
Suffix:表示后置
他会给后台返回的数据加上前置和后置,然后响应给页面。

SpringMVC开发,现在我们一般使用注解,所以需要在配置文件中开启注解:

<context:component-scan
      base-package="com.dcz.controller">
      <context:include-filter type="annotation"
         expression="org.springframework.stereotype.Controller" />
   </context:component-scan>

package指定注解的扫描路径
context:include-filter 表示他只扫描Spring框架的@controller注解,其他的跳过。Spring和SpringMVC在一起使用时,这一步的作用是将这两个框架进行分离

最后,附上配置中的源码:
简单点理解,配置xml文件就是为了启动框架和给框架中的属性赋值。(这个说法并不规范,但是易于理解)
springmvc的servlet
他的父类中有一个属性
springmvc mvc容器配置文件路径
负责保存mvc配置文件的路径

试图解析器:
在这里插入图片描述
他的父类
在这里插入图片描述
父类中有配置前缀和后缀
在这里插入图片描述

如果不指定springMVC配置文件路径,默认的地址为:WEB-INF/
在这里插入图片描述

默认的文件名为:
springMVC
Web.xml中配置的servletName的值-servlet.xml
例如springMVC-Servlet.xml

二、@RequestMapping映射及其属性

所谓的映射,就是前台访问后台,通过对应的路径去寻找对应的方法,在springmvc中,路径的寻找是基于@RequestMapping注解,他并不是去寻找类名、方法名,所以方法名称可以任意,但一般情况下需要遵循开发命名规范。

@RequestMapping有两个用法:
可以加在方法上,也可以加在类上面

参数列表中默认一般为映射的路径,前台通过访问该路径而访问controller的方法。

@RequestMapping(/web”)
Public class TestController{
    @RequestMapping(/test”)
    Public String test(){
 	//需要执行的代码
    }
}

当类上面同时使用该注解时,会先去寻找类映射,在去寻找方法映射,一般用于请求很多,不同请求分组的情况,此时查找的路径应该为:项目下:web/test

当然@RequestMapping(“web/test/aaa”)也可以直接进行指定组合的路径,

@RequestMapping注解的属性
Value : 映射
Method:指定前台的请求方式,多个用逗号隔开,值为requestMethod的枚举类型(get、post、 delete、put)。
Params:参数值,多个参数可用大括号{}

{“name”}表示参数必须包含name值,
{“name=zs”}表示必须包含那么且值只能等于zs,
{“age!=23”}表示age不能等于23或者干脆没有age
{“!height”}表示不能包含hight

Value属性中同样支持通配符:

例如:@RequestMapping(“welcome/*/test”)
*表示匹配任意字符(0个或多个)(1个*号 )
**表示任意的目录@RequestMapping(“welcome/**/test”),表示多个目录,此时任意目录均可以, 例如:welcome/a/b/c/test
Welcome/a/test
Welcome/asd/asg/test …….
?表示单个字符:
@RequestMapping(“welcome/a?b/test”)
此时请求只有 Welcome/axb/test可以

三、参数接收:@RequestParam和@PathVariable注解

他们两个注解都是用于前台向controller传递参数,controller用于接收的注解

@RequestParam:
这个注解最经常使用,加在方法的参数前,用于将指定的值赋值给注解后面的变量
他有三个常用属性:
1.value: 请求参数的参数名,作为参数映射名称,例如:test?name=zhangsan 则后台对应@RequestParam(“name”)
2.required:指定该值是不是前台必传,不传报错,值为true和false
3.defaultValue:指定参数默认值,在没有传值的情况下,默认为该值

@PathVariable
这个注解是可以将传递的参数值放在路径中,是一种使用url传值的方式:
请求:
在这里插入图片描述
后台:
在这里插入图片描述
此时 name的值为zs
将值放在url中,一般用于不需要保密的值

四、处理模型数据

此处的处理模型数据,简单来说主要就是指的controller向前台页面传值的过程

处理模型数据:
如果跳转时,需要带数据,则可以使用ModelAndView、ModelMap、Model、java.util.map
他们都会将数据放在request作用域,以及注解@sessionAttributes、@ModelAttribute,这都是传值的方式

ModelAndView :既有数据,又有视图
ModelMap、Model、包括java.util.Map 这三个都是光有数据,只需要把数据存到里面,不需要返回,也不需要管理,Spring就会自动将数据加载到作用域

上述方法默认只能将数据存储到request作用域

Session中如何进行存储呢?
可以在类的前面加上注解@sessionAttributes()

@SessionAttributes(“user”)
//该括号内参数与存入值的key相同,则同时存入session域中
@Controller
public class CarController {
   @Autowired
   CarService service;
   @RequestMapping("listCar.do")
   public String listCar(Model model) {
      User user = new User();
      model.addAttribute("user", user);
       //当方法中执行类似语句要将数据存入requset作用域时,如果key的值和类上面sessionAttributes(“”)
       //注解的值相同时,则会同时存入session域中
//此时request和session中均有值
      return "list";
   }
}

@sessionAttributes的参数有两种:
一种是String类型,表示在存值过程中,key值与当前string值相同,则同时将数据存入到session中
另一种是class类型,里面写类的class对象,如果存入的值是改对象类型,则同时保存入session

@sessionAttributes(value=“user1,user2,user3”)
括号内可以放多个,用逗号隔开

在注解中声明对象类型,则如果存入request域中的对象是该类型,则同时放入session
@sessionAttributes(types=User.class)
也可以写多个:@sessionAttributes(types={User.class,Student.class,…})

五、@ModelAttribute详解

@ModelAttribute注解
该注解一般有两种作用,一种加在方法上,另一种加载参数前
1.加在方法上
在不改变原方法,还想增加新功能时使用
此注解加在方法上,此时就表示在执行任何一次请求前,都会先执行@ModelAttribute修饰的方法

//在前台访问test时,会首先执行有该注解的方法,然后再执行test方法
@ModelAttribute
    public void md(Model model) {
        User user = new User();
        model.addAttribute("user", user);
        //这里会将user给下面test方法的参数中User赋值
    }
    //他表示将上面的user对象传入下面方法的参数中
    //但是需要注意的是,上面model存值的key,只能是类名的首字母小写形势,不然无法正确传值
    //如果不是这个格式,需要在方法中参数前加@modelAttribue注解指定
    @RequestMapping("/test")
    public String test(@ModelAttribute("user")User user) {
        
        return "success";
    }

2.加在参数前
当该注解加在参数前时,会自动将后面的参数存入到request作用域中,
当作一个前台的对象模型使用,一般情况下,如果需要后台使用mvc表单,则需要传入该模型对象,
以供后台进行识别,有针对性的建立表单

六、视图、视图解析器(了解)

我们在controller中的返回值,无论是String,ModelAndView,或者是View,最终,统一都会变为ModelAndView类型,这样才能被试图解析器去解析,然后返回到前台,可以是jsp/html/excel等等

视图的顶级接口:View
视图解析器的顶级接口ViewResolver

常用的视图
springmvc新手入门教程_第1张图片
常见的视图解析器:
springmvc新手入门教程_第2张图片
InternalResourceViewResolver也是我们最常使用的视图解析器,在SpringMVC配置文件中配置
配置方式:

<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<!-- 配置前缀 -->
		<property name="prefix" value="/views/"></property>
		<!-- 配置后缀 -->
		<property name="suffix" value=".jsp"></property>
	</bean>

不同的解析器可以解析不同的文件,如果需要解析不同类型,就应该去根据需求配置不同的解析器,jsp的解析器是我们最常用的,它的作用就是解析jsp视图

JstlView是InternalResourceView的子类, 可以实现国际化操作,他可以解析jstl

但我们并不需要单独去配置他,springMVC解析jsp时,默认会使用父类InternalResourceView,但如果发现jsp中包含了jstl语言,则自动转为子类JstlView去解析

七、国际化操作

所谓的国际化,实际指的是针对不同的国家,显示不同的内容
具体的实现步骤如下:
1.创建资源文件:
资源文件就是国际化实现时,针对不同的国家,去资源文件中寻找不同的语言结果
常见的资源文件命名方式:
基名_en.properties 针对于所有英文语言的资源
基名_en_US.properties 针对于美国地区的语言
基名_zh_cn.properties 针对于中国地区的语言

类似的名称还有很多很多,自行去百度查找名称。。。。
这种命名方式一般是:基名_语言_国家.properties
如果遇到一些资源文件中没有的值,则去最大的通用文件中去找

范例:
i18n.properties 主文件,如果下面资源文件中都没有的值,则去该文件寻找
i18n_zh_CN.properties 中国大陆文件
i18n_en_US.properties 美国大陆文件
i18n_zh_HK.properties 中国香港文件

2.配置国际化的bean
springMVC在启动时,会自动寻找一个id=“messageSource”的bean,如果有,则自动加载,所以需要配置id值
配置类文件,加载资源文件方式:
在这里插入图片描述
他就会寻找所有的对应的i18n文件,没有指定语言和地区的i18n.properties则是缺省值

3.通过jstl标签实现国际化
Jstl两个jar包,jstl.jar,standard.jar
页面中导入fmt包
在这里插入图片描述
页面中编写:
在这里插入图片描述
Key为properties文件中的key
此时,针对于不同的国家,他就会寻找不同的资源文件,找到对应的值,然后进行显示

国际化必须通过xml中配置的解析器进行解析,跳转页面才可以实现,直接访问是不可以的
因为ResourceBundleMessageSource在MVC响应的时候才会介入,查找国际化文件

国际的化的测试依赖于浏览器的语言,当你把语言改为其他国家语言时,对应的也就会发生改变

八、页面跳转常见功能

在进行访问时,有时候我们不需要进行任何的操作,只想要从一个页面跳转到另一个页面
这时候可以用到mvc的一个配置,在xml配置文件中配置


Mvc同样会给他加前缀和后缀
此时Jsp页面访问view/test请求时,会通过配置文件中的配置直接跳转到success.jsp页面(需要加前缀和后缀)

但有了这个配置之后,mvc默认会对所有的请求都去xml配置文件中寻找,因此相当于屏蔽了controller,如果想要二者共存,就需要加入一个配置:

这个配置是协调作用,能够让许多功能共存,他是基本配置,一般我们为了保证所有功能共存,都会添加该注解

重定向:
Springmvc默认视图的跳转方式是请求转发,就是地址栏里的请求还是指向@requsetmapping,但实际跳转的页面却是成功之后的界面,
如果想要实现重定向,只需要在返回页面的值时加入
Redirect: 即可

@requsetMapping(“test”)
Public String test (){
    return “redirect:success.jsp”;
}
//请求转发是:forword:   但他是默认值,一般我们不需要加他
//需要注意的是,如果使用这个前缀,则视图解析器不会给你拼接前缀与后缀,
//需要自己手动去写,如果不写,他默认会访问success路径,因此还可以实现方法之间的跳转

九、处理静态资源

在SpringMVC中,如果直接访问静态资源,会出现404(找不到资源)
原因是:
在这里插入图片描述
默认拦截了一切请求,他会把所有的请求都去核心控制器去寻找
解决方式:如果需要SpringMVC处理的,则交给mvc,如果不需要,则对资源进行放行操作,
使用tomcat默认servlet处理(如果有默认servlet,则去servlet处理,否则就直接访问)

处理方式:

该注解会在SpringMVC接收到一个请求,并且mvc中没有该请求映射时,会自动将该请求交给tomcat默认servlet处理,(直接访问)
但是一般情况下,这些注解都需要依赖annotation-driven才可以使用,所以上文说基本上任何情况下都需要加这个配置

十、自定义类型转换器

转换器的作用主要是将前台传给后台的数据进行按条件转换,例如:前台传入:张三-男-18,通过转换器对字符串进行处理,将结果转换为对象等等操作

Spring自带一些常见的类型转换器,
在前台向后台传递数据时,例如前台传id=1,后台接收无论int,Integer,或者string均可接收到值,
但对于一些特定要求的值,我们就需要自己定义转换器

  1. 编写 自定义类型转换器的类
    实现Converter接口(泛型为传入类型,转换类型)
public class MyConverter implements Converter<String , Book>{
       //实现Converter接口,泛型的值指的是:<传入的数据,转换的数据>,此处
       //表示传入一个字符串,转换为book对象
    @Override
    public Book convert(String source) {
       // 在这里只需要进行正常的转换步骤即可,例如将字符串切割,并转换为对象
       
       Book book = new Book();
       return book;
    }
}

2.将编写的转换器加入到mvc中
将自定义转换器纳入SpringIOC容器管理
在SpringMVC中配置一个bean

<bean id=”myConverter” class=”com.dcz.util.MyConverter”></bean>

将配置的bean纳入到SpringMvc提供的转换器bean

<bean id=”conversionService” class=””org.springframework.context.support.ConversionServiceFactoryBean>
    <property name=”converters”>
           <set>
                <ref bean=”myConverter”>
     	</set>
    </property>
</bean>

Springmvc提供的转换器类中存储转换器的类型是set集合
将注册好的Spring转换器注册到annotation-driven中

<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>

测试:
在参数前加@requestParam(“mesage”)
当前台传入的请求中有message=”zs-18-男”时候,就会执行转换器
@requestParam(“mesage”)他接收到的是字符串,但他修饰的是对象,满足这两个条件就会触发转换器

十一、数据的格式化

SpringMVC提供了许多注解,方便我们对数据进行格式化
实现步骤:
1. Xml配置:

<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"></bean>
//配置数据格式化所依赖的bean

2.通过注解来使用

例如日期使用:@DateTimeFormat(partten=”yy-MM-dd”) 加在实体类Date类型前
此时,前台传入字符串为“2001-01-01” 但后台属性为Date类型,也能正确接收到

前台向后台传递格式化数据时,如果传递错误,student无法正确接收,会将错误信息
自动传递给加在Student参数后面的Bindresult

@RequestMapping("/test")
    public String test(Student student,BindingResult result) {
        //bindingResult就用于接收错误信息,如果没有这个参数,出错时,前台页面立马报错
        return "success";
    }

如果后台有BindResult 则前台就不会报错,相当于后台进行了try…catch
注意:Student和错误信息BindResult位置不能变换错误信息只能在第二个位置,因为BindResult的作用是保存它前一个数据的错误信息

数字格式化:
@NumberFormat(partten = “###,#”)
此时,前台传入的值必须是三个数字一个逗号在加一个数字(111,1)逗号只是占位符,实际值还是1111

FormattingConversionServiceFactoryBean
这个类既可以实现上述两个格式化,他同时也是配置自定义类型转换的bean,
以后我们配置类型转换的时候就可以直接配置这个bean,同时相当于拥有了两个功能

十二、JSR-303以及Hibernate-Validator后台校验

JSR-303以及Hibernate-Validator两种常用方式,后者是前者的补充,功能更全面

步骤
1. 导入jar包
2. 配置

/**在springmvc框架中实现各种校验,必须实现一个接口:ValidatorFactory
但Spring已经进行了实现LocalValidatorFactoryBean是ValidatorFactory的一个
实现类而配置annotation-driven就是把这个实现类自动给你配置进去 */

3.直接在实体类中加入注解,并在需要校验的controller中加入注解@valid

@RequestMapping("/test")
    public String test(@Valid Student student,BindingResult result) {
        //需要校验Student则在前面加入@valid注解,在后面写bindingResult收集错误信息
        return "success";
    }

在需要验证的类中加各种验证注解

public class Student {

    @NotNull
    @Size(max = 5,min = 2)
    private Integer id;
    
    @NotBlank
    private String name;
    
    @Future
    private Date birthday;
}

SpringMVC会自动将数据的错误信息存入BindingResult 我们只需要获取里面的值,即可接受到错误的信息,

NotNull和NotBlank的区别:

String name = null;
@NotNull: false
@NotEmpty: false
@NotBlank: false
String name = "";
@NotNull: true
@NotEmpty: false
@NotBlank: false
String name = " ";
@NotNull: true
@NotEmpty: true
@NotBlank: false
String name = "Great answer!";
@NotNull: true
@NotEmpty: true
@NotBlank: true

十三、@ResponseBody处理json数据

Ajax请求时,因为是同页面,不需要前往新的页面,所以只返回数据即可,

前台直接返回对象或者集合,只需要在方法上加@responseBody,springMVC即可自动给你转换为JSON
对象,前台ajax接收到之后,可以直接进行使用,不需要任何操作
前台接受到的数据是json数组的形式
后台直接返回集合、对象、数组等等即可、不需要tojsonString等等任何操作

@RequestMapping("/test")
    @ResponseBody
    public List<User> test() {
        List<User> list = new ArrayList<User>();
        
        
        return list;
    }

十四、文件上传

需要导入的包:
Commons-fileupload.jar
Commons-io.jar

springMVC可以简化文件上传的代码,但需要实现MultipartResolver接口,但MVC已经给我们提供了其对应的实现类:CommonsMultipartResolver
具体步骤:
配置xml文件,将CommonsMultipartResolver加入配置文件

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
      <property name="defaultEncoding" value="utf-8"></property>
   </bean>
   //需要注意的是,id的值不能变,改变之后spring无法识别

前台使用表单进行上传,要求请求方式必须是post , 必须加这个属性:enctype=”multipart/form-data”
后台接收时,可直接用MultipartFile 进行接收,然后对这个对象进行具体操作即可,操作如下:

MultipartFile类中常用方法 方法描述
getOriginalFilename() 获取对应的文件名称(包含后缀)
getInputStream() 获取对应的流对象,然后即可读取文件中内容,一般用于读取后直接写到服务器中
transferTo(File file) 将文件内容写入到指定的文件中

十五、拦截器

可以对请求进行拦截,拦截的位置为请求之前,请求之后,以及请求完成
1. 编写拦截器类,实现HandlerInterceptor接口
2. 重写其三个方法
preHandle:客户端请求服务器时拦截
postHandle:服务器处理完请求,响应给客户端时拦截
afterCompletion:页面渲染完毕之后拦截
三个方法的返回值均为boolean类型,true则表示放行,false表示拦截
3. 将拦截器配置到springmvc中:

<mvc:interceptors>
      <mvc:interceptor>
        <mvc:mapping path="/**" />   //表示拦截一切请求
        <mvc:exclude-mapping path="/login" />  //表示该请求不拦截
        <mvc:exclude-mapping path="/checkName" />
        <bean class="com.test.utils.MyInterceptor"></bean> //拦截器的bean
      </mvc:interceptor>
   </mvc:interceptors>

如果配置多个拦截器,preHandle方法按照配置的顺序执行,postHandle按照相反的顺序执行,afterCompletion也按照相反顺序执行。

十六、异常处理

Springmvc处理异常,必须实现顶级接口HandlerExceptionResolver
该接口的每个实现类,都是一种异常的处理方式
ExceptionHandlerExceptionResolver:主要提供了@ExceptionHandler注解,并通过该注解处理异常

@ExceptionHandler(RuntimeException.class)
    public String runtime(RuntimeException e) {
        //这里表示出现runtime异常时,会执行这个方法
        return "error";
    }

参数中的e 就相当于是catch块括号中捕获的异常,当捕获到异常时,就会走这个方法,

注意:异常方法参数括号中只能有一个异常的对象,不能包含其他对象,否则就会失效!!!

如果有多个异常方法都符合条件,则按照那个就近原则,有异常类就去找本身,没有对应的异常就去找齐父类,依次往上找
异常方法只能捕获当前类出现的异常,对于其他controller类的异常无法捕获

如果需要单独定义一个类,用于专业处理各个controller类中的异常
则可以在类上使用@ControllerAdvice他就表示我是专业处理异常的类,可以处理所有controller类中的异常

@ControllerAdvice
public class DisposeControllerException {
    /**
     * 这是一个专业处理异常的类
     * VerifyUserException 是自定义的一个异常
     * 方法参数中只能包含异常的对象
     * 我们在这里对异常进行处理
     */
    @ExceptionHandler(VerifyUserException.class)
    public ModelAndView loginException(VerifyUserException e) {
        String message = "异常啦!!";
        ModelAndView mv = new ModelAndView("error");
        mv.addObject("message", message);
        return mv;
    }
    
}

2.异常状态提示
ResponseStatusExceptionResolver类
他可以自定义用户页面异常显示的状态,以及文字
提供了注解@ResponseStatus
将注解加在自定义的异常类上面(注意:自定义异常需要继承Exception或者其子类)
如果有方法抛出了该自定义异常,则页面就显示此错误

这个注解有两个参数:
value:表示前面状态码,例如404, 有一个枚举类为他提供常用状态码: HttpStatus类
reason:表示异常的表述信息,即下图中message的内容,例如:SpringMVCProject/abcdefg.jsp

springmvc新手入门教程_第3张图片

@ResponseStatus(value= 枚举,reason = “错误”)
@requestMapping(“test”)
Public void test(){
 //此时如果访问test,则会出现此异常
}

总结:@ExceptionHandler是用来处理异常的,可以加在方法上
如果需要单独定义一个异常处理类,则需要在类上加@controllerAdvice
然后正常定义方法并加注解@ExceptionHandler

   @ResponseStatus是用来定义异常的,他可以定义用户页面的异常显示信息,

可以加在方法上(如果前台访问该方法则异常),也可以加在自定义异常类上(若抛出该异常则出现异常)
最后,需要注意的是,如果使用@ResponseStatus定义了异常,但@ExceptionHandler处理了该异常,则页面不会显示错误

你可能感兴趣的:(springmvc)