文章目录
SpringMVC
MVC模式
mvc设计模式原理图
M-Model模型:业务逻辑,主要有service+dao+entity
V-View视图:界面的展示
C-Controller控制器:接受请求,调用model,返回结果
springMVC概述
spring为展现层提供的基于MVC设计理念的优秀的WEB框架,是目前最主流的MVC框架之一.
一种轻量级的、基于MVC的Web层应用框架。它能让我们对请求数据的出来,响应数据的处理,页面的跳转等等常见的web操作变得更加简单方便。
SpringMVC执行流程
- 用户发送请求到前端控制器DispatchServlet
- 前端控制器DispatchServlet收到请求调用HandlerMapping(根据URL查找处理器),根据具体的请求查找能够处理该请求的处理器
- HandlerMapping返回一个能够处理该请求的执行链到DispachServlet(该链包含处理器和拦截器)
- DispatchServlet根据这个执行链去找处理器适配器HandlerAdater执行链中的方法
- HandlerAdapt执行对应的handler方法,把数据处理为合适的类型作为参数传入方法中
- handler执行后的返回值被HandlerAdapt转换成ModelAndView类型(HandlerAdapt主要进行参数的传入和方法的返回值)
- 将ModelAndView中返回给DispatchServlet
- 如果ModelAndView不为空,将值传到ViewResolver视图解析器
- ViewResolver将ModelAndView中的viewname转换成对应的view对象返回给DisptchServlet
- DispatchServler使用view对象进行页面展示
搭建项目
1.导入相关依赖
<!--springmvc的依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<!--端口-->
<port>81</port>
<!--项目路径-->
<path>/</path>
<!--解决get请求中文乱码-->
<uriEncoding>utf-8</uriEncoding>
</configuration>
</plugin>
</plugins>
</build>
2.配置web.xml
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--
为DispatcherServlet提供初始化参数的
设置springmvc配置文件的路径
name是固定的,必须是contextConfigLocation
value指的是SpringMVC配置文件的位置
-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<!--
指定项目启动就初始化DispatcherServlet
-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<!--
/ 表示当前servlet映射除jsp之外的所有请求(包含静态资源)
*.do 表示.do结尾的请求路径才能被SpringMVC处理(老项目会出现)
/* 表示当前servlet映射所有请求(包含静态资源,jsp),不应该使用其配置DispatcherServlet
-->
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--乱码处理过滤器,由SpringMVC提供-->
<!-- 处理post请求乱码 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<!-- name固定不变,value值根据需要设置 -->
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<!-- 所有请求都设置utf-8的编码 -->
<url-pattern>/*</url-pattern>
</filter-mapping>
3.配置springmvc文件
<!--
SpringMVC只扫描controller包即可
-->
<context:component-scan base-package="com.sangeng.controller"/>
<!-- 解决静态资源访问问题,如果不加mvc:annotation-driven会导致无法访问handler-->
<mvc:default-servlet-handler/>
<!--解决响应乱码-->
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="utf-8"/>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
4.测试
创建success.jsp页面进行测试
5.项目结构
搭建成功
请求映射规则@RequestMapping
@RequestMapping注解可以加到方法和类上,可以用来设定请求的一些要求,只有符合了请求,才能被处理
指定请求路径
path或者value属性都可以指定请求路径 下面代码只能让请求路径为hello的请求处理
@RequestMapping("/hello")
public String hello(String name){
System.out.println(name);
return "success.jsp";
}
指定请求方式
method属性可以用来处理请求方式,也就是说指定了请求方式,get请求只能被get请求处理
-
@PostMapping 等价于 @RequestMapping(method = RequestMethod.POST)
-
@GetMapping 等价于 @RequestMapping(method = RequestMethod.GET)
-
@PutMapping 等价于 @RequestMapping(method = RequestMethod.PUT)
-
@DeleteMapping 等价于 @RequestMapping(method = RequestMethod.DELETE)
@RequestMapping(value = "/testMethod",method = RequestMethod.POST)
public String testMethod(){
return "success.jsp";
}
指定请求参数
param属性指定请求参数,可以要求必须有某些参数或者某些参数必须是某个值或者某个参数不是某个值
- 要求请求参数里必须有code值
@RequestMapping(value = "/testParams",params = "code")
public String testParams(){
return "success.jsp";
}
- 要求请求参数里code值不能等于1
@RequestMapping(value = "/testParams",params = "code=1")
public String testParams(){
return "success.jsp";
}
- 要求请求参数里不包含code
@RequestMapping(value = "/testParams",params = "!code")
public String testParams(){
return "success.jsp";
}
指定请求头
headers属性指定请求的请求头
@RequestMapping(value = "/testHeaders",headers = "device-type")
public String testHeaders(){
return "success.jsp";
}
RestFul风格
RestFul是网络应用程序的设计风格和开发方式
主要规则如下:
- 每一个url代表一个资源(比如请求路径为/user***,代表请求用户资源)
- 客户端使用GET,POST,DELETE,PUT四种操作方式表示对资源进行的查,增,删,改
- 复杂的参数转换成json写请求体中
- 简单的参数可以写到url上(user/findById/1)
获取请求参数
获取路径参数
RestFul风格的接口一些参数是在请求路径上的。类似:user/findById/1
@GetMapping(value = "/user/{id}")
public String findUserById(@PathVariable("id") String id){
System.out.println(id);
return "success.jsp";
}
多个请求参数
@GetMapping(value = "/user/{id}/{name}")
public String findUserById1(@PathVariable("id") String id,@PathVariable("name") String name){
System.out.println(id+name);
return "/success.jsp";
}
获取请求体中的json参数
RestFul风格的接口一些比较复杂的参数会转换成Json通过请求体传递过来。这种时候我们可以使用**@RequestBody**注解获取请求体中的数据。
@PostMapping(value = "/insertuser")
public String findUserById2(@RequestBody User user){
System.out.println(user);
return "/success.jsp";
}
获取QueryString格式参数
如果接口的参数是使用QueryString的格式的话,我们也可以使用SpringMVC快速获取参数。
我们可以使用**@RequestParam**来获取QueryString格式的参数。
- 参数单独获取
如果我们想把id,name,likes单独获取出来可以使用如下写法:在方法中定义方法参数,方法参数名要和请求参数名一致,这种情况下我们可以省略**@RequestParam**注解。
@GetMapping("/getuser")
public String getuser(String name,String id){
System.out.println(name+id);
return "/success.jsp";
}
如果方法参数名和请求参数名不一致,我们可以加上**@RequestParam**注解例如:
@RequestMapping("/testRquestParam")
public String testRquestParam(@RequestParam("id") Integer uid,@RequestParam("name") String name, @RequestParam("likes")String[] likes){
System.out.println("testRquestParam");
System.out.println(uid);
System.out.println(name);
System.out.println(Arrays.toString(likes));
return "/success.jsp";
}
相关注解其他属性
- require
代表是否必须,默认值为true也就是必须要有对应的参数。如果没有就会报错。
如果对应的参数可传可不传则可以把去设置为fasle
@GetMapping("/getuser")
public String getuser(@RequestParam(value = "name",required = false) String names, String id){
System.out.println(names+id);
return "/success.jsp";
}
- defaultvalue
如果对应的参数没有,我们可以用defaultValue属性设置默认值。
@RequestMapping("/testRquestParam")
public String testRquestParam(@RequestParam(value = "id",required = false,defaultValue = "777") Integer uid,@RequestParam("name") String name, @RequestParam("likes")String[] likes){
System.out.println("testRquestParam");
System.out.println(uid);
System.out.println(name);
System.out.println(Arrays.toString(likes));
return "/success.jsp";
}
类型转换器Converter
内置类型转换器
在上一节中,获取参数看起来比较轻松,但是这个过程可能会出问题,比如请求参数为success=1,我们希望把这个请求参数获取出来赋值给boolean类型的变量
实际上SpringMVC中内置了很多类型转换器来进行类型转换。也有专门进行Stirng-——>Boolean类型转换的转换器StringToBooleanConverter。
例如下面:success为1,后台接受为Boolean类型
控制台输出为true
url:http://localhost:81/getuser?success=1
@GetMapping("/getuser")
public String getuser(boolean success){
System.out.println(success);
return "/success.jsp";
}
自定义类型转换器
- 自定义类并实现converter
public class MyConverter implements Converter<String, Date> {
/*第一个泛型表示要传入的值
* 第二个泛型表示要返回的值
* */
@Override
public Date convert(String o) {
Date parse=null;
try {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
parse = simpleDateFormat.parse(o);
} catch (ParseException e) {
throw new RuntimeException(e);
}
return parse;
}
}
2.配置让SpringMVC使用自定义转换器
<!--解决响应乱码-->
<mvc:annotation-driven conversion-service="myConverter">
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="utf-8"/>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<bean id="myConverter" class="org.springframework.context.support.ConversionServiceFactoryBean" >
<property name="converters">
<set>
<bean class="com.lsy.converter.MyConverter"></bean>
</set>
</property>
</bean>
日期转换简便方法
如果是String到Date的转换我们也可以使用另外一种更方便的方式。使用@DateTimeFormat来指定字符串的格式。
@RequestMapping("/testDateConverter")
public String testDateConverter(@DateTimeFormat(pattern = "yyyy-MM-dd") Date birthday){
System.out.println("testDateConverter");
System.out.println(birthday);
return "/success.jsp";
}
响应体响应数据
无论是RestFul风格还是我们之前web阶段接触过的异步请求,都需要把数据转换成Json放入响应体中。
数据放到响应体@ResponseBody
该注解放到类和方法上就可以将返回值放到响应体中
springMVC可以进行JSON的转换,需要导入JSON依赖
@GetMapping(value = "/user/{id}/{name}")
@ResponseBody
public User findUserById1(@PathVariable("id") String id,@PathVariable("name") String name){
System.out.println(id+name);
User user = new User();
user.setAge(13);
user.setName("lsy1");
return user;
}
如果一个Controller中的所有方法返回值都要放入响应体,那么我们可以直接在Controller类上加@ResponseBody。
我们可以使用**@RestController** 注解替换@Controller和@ResponseBody两个注解
请求转发和重定向
请求转发:客户端发送请求,服务器做出业务逻辑,服务器调用forward方法将结果返回给客户端
重定向:客户端发送请求.服务器接受并做出业务逻辑处理,服务器调用response.sendRedirect方法,将要访问的信息返回给客户端,客户端再次用返回的信息重新访问服务器
默认的跳转其实是转发的方式跳转的。我们也可以选择加上标识,在要跳转的路径前加上forward: 。这样SpringMVC也会帮我们进行请求转发。
例如:
@Controller
public class PageJumpController {
@RequestMapping("/testJump")
public String testJump(){
return "forward:/success.jsp";
}
}
如果想实现重定向跳转则可以在跳转路径前加上 redirect: 进行标识。这样SpringMVC就会帮我们进行重定向跳转。
例如:
@Controller
public class PageJumpController {
@RequestMapping("/testJump")
public String testJump(){
return "redirect:/success.jsp";
}
}