目录
二、Spring MVC简介
2.1什么是SpringMVC
SpringMVC就是一个Spring内置的MVC框架。
MVC框架,它解决WEB开发中常见的问题(参数接收、文件上传、表单验证、国际化等等),而且使用简单,与Spring无缝集成。支持 RESTful风格的URL请求。
采用了松散耦合可插拔组件结构,比其他 MVC 框架更具扩展性和灵活性。
2.2. SpringMVC的作用
MVC模式(Model-View-Controller):解决页面代码和后台代码的分离。
2.3. SpringMVC原理
在没有使用SpringMVC之前我们都是使用Servlet在做Web开发。但是使用Servlet开发在接收请求参数,数据共享,页面跳转等操作相对比较复杂。servlet是java进行web开发的标准,既然springMVC是对servlet的封装,那么很显然SpringMVC底层就是Servlet,SpringMVC就是对Servlet进行深层次的封装。
2.4.SpringMVC执行流程:
01、用户发送出请求被前端控制器DispatcherServlet拦截进行处理。 02、DispatcherServlet收到请求调用HandlerMapping(处理器映射器)。 03、HandlerMapping找到具体的处理器(查找xml配置或注解配置),生成处理器对象及处理器拦截器(如果有),再一 起返回给DispatcherServlet。 04、DispatcherServlet调用HandlerAdapter(处理器适配器)。 05、HandlerAdapter经过适配调用具体的处理器(Handler/Controller)。 06、Controller执行完成返回ModelAndView对象。 07、HandlerAdapter将Controller执行结果ModelAndView返回给DispatcherServlet。 08、DispatcherServlet将ModelAndView传给ViewReslover(视图解析器)。 09、ViewReslover解析ModelAndView后返回具体View(视图)给DispatcherServlet。 10、DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。 11、DispatcherServlet响应View给用户。
2.4.1涉及组件分析:
1、前端控制器DispatcherServlet(不需要程序员开发)由框架提供,在web.xml中配置。 作用:接收请求,响应结果,相当于转发器,中央处理器。 2、处理器映射器HandlerMapping(不需要程序员开发)由框架提供。 作用:根据请求的url查找Handler(处理器/Controller),可以通过XML和注解方式来映射。 3、处理器适配器HandlerAdapter(不需要程序员开发)由框架提供。 作用:按照特定规则(HandlerAdapter要求的规则)去执行Handler中的方法。 4、处理器Handler(也称之为Controller,需要程序员开发) 注意:编写Handler时按照HandlerAdapter的要求去做,这样适配器才可以去正确执行Handler。 作用:接受用户请求信息,调用业务方法处理请求,也称之为后端控制器。 5、视图解析器ViewResolver(不需要程序员开发)由框架提供。 作用:进行视图解析,把逻辑视图解析成真正的物理视图。 SpringMVC框架支持多种View视图技术,包括:jstlView、freemarkerView、ThymeleafView等。 6、视图View(需要工程师开发) 作用:把数据展现给用户的页面 View是一个接口,实现类支持不同的View技术(jsp、freemarker、pdf等) --根据以上分析,SpringMVC需要程序员完成的工作有三个: 【1】配置前端控制器DispatcherServlet。 【2】开发后端控制器Handler/Controller。 【3】开发视图View。
2.5搭建SpringMVC项目环境:
1、通过maven创建一个web项目,选择一个模板创建(骨架)
2、添加依赖
3、spring-mvc.xml 配置文件
4、在web.xml中配置一个核心Servlet,处理所有请求:DispatcherServlet, 在这个servlet中加载spring-mvc.xml配置文件
5、编写一个普通的java类,用来处理请求。 @Controller、@RequestMapping
6、把项目部署到tomcat中,启动,访问,测试,观察结果
2.5.1、代码实现
第一步:依赖
<dependencies>
<!--添加SpringMVC的依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.12.RELEASE</version>
</dependency>
<!--添加servlet包-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
</dependencies>
第二步:SpringMVC配置
spring-mvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--1、注解扫描-->
<context:component-scan base-package="com.wnxy.controller"/>
<!--2、开启注解驱动(自动开启SpringMVC内置的功能)-->
<mvc:annotation-driven/>
</beans>
第三步:web.xml配置
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<!--
配置SpringMVC的前端控制器: 所有的springmvc的请求必须经过这个前端控制器.就是一个servlet
需要做的事情: 加载spring-mvc.xml、拦截所有的请求
-->
<servlet>
<!--servlet名称,需要与servlet-mapping的名称对应-->
<servlet-name>DisatcherServlet</servlet-name>
<!--SpringMVC前端控制器,处理所有的springmvc请求-->
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--配置初始化参数,用来加载spring-mvc.xml-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<!--servlet默认是第一次访问时候创建;当配置load-on-startup后,就可以启动时候创建-->
<!--数字越小越先创建; 数字是1-6范围-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<!--servlet的名称,可以随意取名;需要与servlet标签的servlet-name对应-->
<servlet-name>DisatcherServlet</servlet-name>
<!--拦截所有的请求-->
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
第四步:编写控制器
/**
* 处理请求的控制器类
*/
@Controller // 必须用@Controller
public class HelloController {
/**
* 访问当前方法的url地址:
* http://localhost:8080/hello
*/
@RequestMapping("/hello")
@ResponseBody // 返回json格式的数据;自动把方法返回结果转换为json格式数据
public void hello(){
System.out.println("Hello,SpringMVC!");
}
/**
* 请求参数: http://localhost:8080/hello2?id=100
*/
@RequestMapping("/hello2")
@ResponseBody // 返回json格式的数据;自动把方法返回结果转换为json格式数据
public void hello2(Integer id){
System.out.println("id = " + id);
}
}
spring MVC模块注解
1、web模块常用到的注解
-
@Controller :表明该类会作为与前端作交互的控制层组件,通过服务接口定义的提供访问应用程序的一种行为,解释用户的输入,将其转换成一个模型然后将试图呈献给用户
Spring MVC 使用 @Controller 定义控制器,它还允许自动检测定义在类路径下的组件(配置文件中配置扫描路径)并自动注册。
-
@RequestMapping : 这个注解用于将url映射到整个处理类或者特定的处理请求的方法。可以只用通配符!
-
用于映射Web请求,包括访问路径和参数。(类或方法上)
@Controller
@RequestMapping("/happy")
public class HappyController {
@Autowired
private HappyService happyService;
@RequestMapping(/hello/*)
public void sayHello(){
//请求为 /happy/hello/* 都会进入这个方法!
//例如:/happy/hello/123 /happy/hello/adb
//可以通过get/post 请求
}
@RequestMapping(value="/haha",method=RequestMethod.GET)
public void sayHaHa(){
//只能通过get请求
}
...
}
@RequestMapping 既可以作用在类级别,也可以作用在方法级别。当它定义在类级别时,标明该控制器处理所有的请求都被映射到 /favsoft 路径下。@RequestMapping中可以使用 method 属性标记其所接受的方法类型,如果不指定方法类型的话,可以使用 HTTP GET/POST 方法请求数据,但是一旦指定方法类型,就只能使用该类型获取数据。
- @RequestParam :将请求的参数绑定到方法中的参数上,有required参数,默认情况下,required=true,也就是改参数必须要传。如果改参数可以传可不传,可以配置required=false。
@RequestMapping("/happy")
public String sayHappy(
@RequestParam(value = "name", required = false) String name,
@RequestParam(value = "age", required = true) String age) {
//age参数必须传 ,name可传可不传
...
}
- @PathVariable : 该注解用于方法修饰方法参数,会将修饰的方法参数变为可供使用的uri变量(可用于动态绑定)。
- 用于接收路径参数,比如@RequestMapping(“/hello/{name}”)申明的路径,将注解放在参数中前,即可获取该值,通常作为Restful的接口实现方法。
@RequestMapping(value="/happy/{dayid}",method=RequestMethod.GET)
public String findPet(@PathVariable String dayid, Model mode) {
//使用@PathVariable注解绑定 {dayid} 到String dayid
}
@PathVariable中的参数可以是任意的简单类型,如int, long, Date等等。Spring会自动将其转换成合适的类型或者抛出 TypeMismatchException异常。当然,我们也可以注册支持额外的数据类型。
@PathVariable支持使用正则表达式,这就决定了它的超强大属性,它能在路径模板中使用占位符,可以设定特定的前缀匹配,后缀匹配等自定义格式。
- @RequestBody : @RequestBody是指方法参数应该被绑定到HTTP请求Body上。
- 允许request的参数在request体中,而不是在直接连接在地址后面。(放在参数前)
@RequestMapping(value = "/something", method = RequestMethod.PUT)
public void handle(@RequestBody String body,@RequestBody User user){
//可以绑定自定义的对象类型
}
- @ResponseBody : @ResponseBody与@RequestBody类似,它的作用是将返回类型直接输入到HTTP response body中。
@ResponseBody在输出JSON格式的数据时,会经常用到。 - 支持将返回值放在response内,而不是一个页面,通常用户返回json数据。(返回值旁或方法上)
@RequestMapping(value = "/happy", method =RequestMethod.POST)
@ResponseBody
public String helloWorld() {
return "Hello World";//返回String类型
}
- @RestController :控制器实现了REST的API,只为服务于JSON,XML或其它自定义的类型内容,@RestController用来创建REST类型的控制器,与@Controller类型。@RestController就是这样一种类型,它避免了你重复的写@RequestMapping与@ResponseBody。相当于: @Controller + @ResponseBody
- 用于接收路径参数,比如@RequestMapping(“/hello/{name}”)申明的路径,将注解放在参数中前,即可获取该值,通常作为Restful的接口实现方法。
- @ModelAttribute :@ModelAttribute可以作用在方法或方法参数上,当它作用在方法上时,标明该方法的目的是添加一个或多个模型属性(model attributes)。
该方法支持与@RequestMapping一样的参数类型,但并不能直接映射成请求。控制器中的@ModelAttribute方法会在@RequestMapping方法调用之前而调用。 - 本来的作用是绑定键值对到 Model 里,在 @ControllerAdvice 中是让全局的@RequestMapping都能获得在此处设置的键值对。
@ModelAttribute :@ModelAttribute可以作用在方法或方法参数上,当它作用在方法上时,标明该方法的目的是添加一个或多个模型属性(model attributes)。
该方法支持与@RequestMapping一样的参数类型,但并不能直接映射成请求。控制器中的@ModelAttribute方法会在@RequestMapping方法调用之前而调用。
2、Restful请求
第一:为了让页面支持put、delete请求,需要配置一个Spring提供的过滤器
<!--为了解决页面不支持put、delete请求的问题-->
<filter>
<filter-name>hiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
第二:页面发送put、delete请求的方法: 表单提交方式是post、隐藏域存储真正的提交方式
<form action="/owner" method="post">
<!--隐藏域指定真实提交方式, 通过value指定-->
<!--隐藏域用来存储表单数据,但是不显示。-->
<input type="hidden" name="_method" value="put">
<input type="submit" value="put提交">
</form>
<div></div>
<form action="/owner" method="post">
<input type="hidden" name="_method" value="delete">
<input type="submit" value="delete提交">
</form>
第三:后台控制器
@Controller
public class OwnerController {
// get请求:查询操作
@RequestMapping(value = "/owner",method = RequestMethod.GET)
@ResponseBody
public String get(){
System.out.println(" get ");
return "get";
}
// post请求:添加操作
@RequestMapping(value = "/owner",method = RequestMethod.POST)
@ResponseBody
public String add(){
System.out.println(" add ");
return "add";
}
// delete请求:删除
@RequestMapping(value = "/owner",method = RequestMethod.DELETE)
@ResponseBody
public String del(){
System.out.println(" del ");
return "del";
}
// put请求:修改
@RequestMapping(value = "/owner",method = RequestMethod.PUT)
@ResponseBody
public String put(){
System.out.println(" put ");
return "put";
}
}
后台优化写法:@RestController // 相当于: @Controller + @ResponseBody
@RestController // 相当于: @Controller + @ResponseBody
@RequestMapping("/owner")
public class OwnerController {
// get请求:查询操作
@GetMapping
public String get(){
System.out.println(" get ");
return "get";
}
// post请求:添加操作
@PostMapping
public String add(){
System.out.println(" add ");
return "add";
}
// delete请求:删除
@DeleteMapping
public String del(){
System.out.println(" del ");
return "del";
}
// put请求:修改
@PutMapping
public String put(){
System.out.println(" put ");
return "put";
}
}
3、中文乱码问题解决
post提交出现中文乱码问题, 解决?
SpringMVC已经提供了编码过滤器,直接在web.xml配置即可!
web.xml 中配置编码过滤器:CharacterEncodingFilter
<!-- 编码过滤器,解决中文乱码问题 -->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
注意:filter的配置,要放到servlet配置之前。
原因:web.xml约束中规定的
4、静态资源无法访问
原因:
1、web.xml 中配置了DispatcherServlet,拦截的路径是:/ 表示所有的请求(不包含jsp请求)
2、Tomcat中处理静态资源的servlet是:DefaultServlet, 拦截的路径也是:/
3、导致我们项目中配置的拦截器路径【/】把tomcat中处理静态资源的servlet覆盖掉了。导致静态资源无法访问。
解决: spring-mvc.xml中添加一行配置
<!--3、处理静态资源无法访问的问题。把静态资源的处理交给默认servlet(DefaultServlet)-->
<mvc:default-servlet-handler/>
因为tomcat中conf目录下web.xml 被spring-mvc.xml覆盖掉了
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>readonly</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
5、SpringMVC如何封装请求数据?
5.1简单参数: 参数名称要和方法形参名称一致。
/**
* 访问地址: http://localhost:8080/user/findMapById?id=100&name=Jacky
*/
@RequestMapping("/findMapById")
@ResponseBody
public Map<String,Object> findMapById(Integer id,String name) {
Map<String,Object> map = new HashMap<>();
map.put("id",id);
map.put("name",name);
return map;
}
5.2请求参数封装为对象。
/**
* 访问地址: http://localhost:8080/user/save?id=100&name=Jacky
* 总结:请求参数名称,自动封装到对象的同名属性中。
*/
@RequestMapping("/save")
@ResponseBody
public void save(User user){
System.out.println("user = " + user);
}
6、SpringMVC如何返回JSON?
步骤1:使用注解@ResponseBody, 修饰到方法上,自动把方法返回的结果转换为json
@ResponseBody
1、自动把方法返回的对象转换为json
2、使用前需要添加jackson依赖包;
3、springmvc对象与json的转换使用的是jackson包
步骤2:运行前,需要添加jackson的依赖包
<!--添加jackson依赖包,实现对象与json的转换。(解决@ResponseBody返回json问题)-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.14.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.14.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.14.2</version>
</dependency>
标签:RequestMapping,SpringMVC,ResponseBody,Controller,public,请求 From: https://www.cnblogs.com/amor2818/p/17154934.html