1,SpringMVC的概述
- 1.1,什么是MVC
- 1.2,什么是SpringMVC
- 1.3,中心控制器
- 1.4, Spring MVC的工作原理
2,编写SpringMVC程序
- 2.1,新建一个SpringMVC项目
- 2.2,编写web.xml
- 2.3,编写springmvc配置文件
- 2.4,创建对应的控制类
- 2.5,编写前端界面,然后进行测试
3,RestFul 风格
4,数据处理及跳转
- 4.1,ServletAPI
- 4.2,视图解析器
- 4.3,处理提交数据
- 4.4,数据显示到前端
- 4.5,乱码问题
SpringMVC的概述
1,什么是MVC
- MVC是模型(Model)、视图(View)、控制器(Controller)的简写,是一种软件设计典范。
- 是将业务逻辑、数据、显示分离的方法来组织代码。
- MVC主要作用是降低了视图与业务逻辑间的双向偶合。
- MVC不是一种设计模式,MVC是一种架构模式。当然不同的MVC存在差异。
Model(模型)
:数据模型,提供要展示的数据,因此包含数据和行为,可以认为是领域模型或JavaBean组件(包含数据和行为)。也就是模型提供了模型数据查询和模型数据的状态更新等功能,包括数据和业务。
View(视图)
:负责进行模型的展示,也就是页面。
Controller(控制器)
:接收用户请求,委托给模型进行处理(状态改变),处理完毕后把返回的模型数据返回给视图,由视图负责展示。
最典型的MVC就是JSP + servlet + javabean的模式。
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHLwEERNdXTU5EeRpHW4Z0MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL1kTN5EjN1gTMwEjNwAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
2,什么是SpringMVC
- Spring MVC是Spring Framework的一部分,是基于Java实现MVC的轻量级Web框架。
-
Spring MVC的特点:
轻量级,简单易学
高效 , 基于请求响应的MVC框架
与Spring兼容性好,无缝结合
约定优于配置
功能强大:RESTful、数据验证、格式化、本地化、主题等
简洁灵活
- Spring的web框架围绕DispatcherServlet [ 调度Servlet ] 设计
3,中心控制器
- Spring的web框架围绕DispatcherServlet设计。DispatcherServlet的作用是将请求分发到不同的处理器。从Spring 2.5开始,使用Java 5或者以上版本的用户可以采用基于注解的controller声明方式。
- Spring MVC框架像许多其他MVC框架一样, 以请求为驱动 , 围绕一个中心Servlet分派请求及提供其他功能,DispatcherServlet是一个实际的Servlet (它继承自HttpServlet 基类)。
4, Spring MVC的工作原理
- SpringMVC流程图如下:
(4)SpringMVC————概述,程序的编写,RestFul风格和数据处理及跳转 -
执行流程:
⑴,用户发起请求会经过前端控制DispatcherServlet
⑵,HandlerMapping为处理器映射。DispatcherServlet调用HandlerMapping,HandlerMapping根据请求url查找Handler。
⑶,HandlerExecution表示具体的Handler,其主要作用是根据url查找控制器。
⑷,HandlerExecution将解析后的信息传递给DispatcherServlet,如解析控制器映射等。
⑸,HandlerAdapter表示处理器适配器,其按照特定的规则去执行Handler。
⑹,Handler让具体的Controller执行。
⑺,Controller将具体的执行信息返回给HandlerAdapter,如ModelAndView。
⑻,HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet。
⑼,DispatcherServlet调用视图解析器(ViewResolver)来解析HandlerAdapter传递的逻辑视图名。
⑽,视图解析器将解析的逻辑视图名传给DispatcherServlet。
⑾,DispatcherServlet根据视图解析器解析的视图结果,调用具体的视图。
⑿,最终视图呈现给用户。
-
总结:
用户发起请求会经过前端控制DispatcherServlet,找到映射器,根据找到的映射器去适配映射器,controller执行,返回ModelAndView,通过ModelAndView配置具体视图解析器,返回给前端调用
- 示例代码
- web.xml:
<!--配置DispatchServlet:这个是SpringMVC的核心;请求分发器,前端控制器 -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<!-- 启功级别 1 -->
<load-on-startup>1</load-on-startup>
</servlet>
<!--在SpringMVC中,
/:只匹配所有的请求,不会去匹配jsp页面
/*:匹配所有的请求,包括jsp
-->
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
- spring-mvc.xml
<!-- 处理器映射器 -->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<!-- 处理器适配器 -->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<!-- 视图解析器:模板引擎Thymeleof Freemarker-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
<!-- 前缀 -->
<property name="prefix" value="/"/>
<!-- 后缀 -->
<property name="suffix" value=".jsp"/>
</bean>
<bean id="/index" class="com.controller.DemoController"/>
- DemoController类
public class DemoController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
ModelAndView mv = new ModelAndView();
String result = "测试MVC";
mv.addObject("msg",result);
return mv;
}
}
编写SpringMVC程序
1,新建一个SpringMVC项目
2,编写web.xml
<!--配置DispatchServlet:这个是SpringMVC的核心;请求分发器,前端控制器 -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<!-- 启功级别 1 -->
<load-on-startup>1</load-on-startup>
</servlet>
<!--在SpringMVC中,
/:只匹配所有的请求,不会去匹配jsp页面
/*:匹配所有的请求,包括jsp
-->
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
3,编写springmvc配置文件
- spring-mvc.xml:
<!-- 自动扫描包,让指定包下的注解生效,由IOC容器统一管理 -->
<context:component-scan base-package="com.controller"/>
<!-- 让Spring MVC不处理静态资源 -->
<mvc:default-servlet-handler />
<!--
支持mvc注解驱动annotation-driven配置帮助我们自动完成
DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter实例的注入。
-->
<mvc:annotation-driven />
<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
id="internalResourceViewResolver">
<!-- 前缀 -->
<property name="prefix" value="/" />
<!-- 后缀 -->
<property name="suffix" value=".jsp" />
</bean>
4,创建对应的控制类
- DemoController类:
@Controller
public class DemoController{
@RequestMapping("demo")
public String demo01(Model model){
//向模型中添加msg属性值,可在jsp页面直接取出
model.addAttribute("msg","welcome to SpringMVC");
return "index";
}
}
5,编写前端界面,然后进行测试
- index.jsp:
<body>
${msg}
</body>
- 配置Tomcat
- 测试地址:
http://localhost:8080/SpringMVCTest/demo
RestFul 风格
- Restful就是一个资源定位及资源操作的风格。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
- 传统方式操作资源,通过不同的参数来实现不同的效果!方法单一,post 和 get:
@Controller
public class DemoController{
@RequestMapping("demo")
public String demo01(int a,int b,Model model){
int sum = a + b;
//向模型中添加msg属性值,可在jsp页面直接取出
model.addAttribute("msg","welcome to SpringMVC" + sum);
return "index";
}
}
访问地址:
http://localhost:8080/SpringMVCTest/demo?a=1&b=1
- 使用RESTFul操作资源 :可以通过不同的请求方式来实现不同的效果!如下:请求地址一样,但是功能可以不同!
- 示例代码:
@RequestMapping("/demo/{a}/{b}")
public String demo01(@PathVariable int a, @PathVariable int b, Model model){
int sum = a + b;
//向模型中添加msg属性值,可在jsp页面直接取出
model.addAttribute("msg","welcome to SpringMVC,结果:" + sum);
return "index";
}
访问地址:
http://localhost:8080/SpringMVCTest/demo/1/9
- 使用method属性指定请求类型:
- Spring MVC 的 @RequestMapping 注解能够处理 HTTP 请求的方法, 比如 GET, PUT, POST, DELETE 以及 PATCH。
- 所有的地址栏请求默认都会是 HTTP GET 类型的。
- 方法级别的注解变体有如下几个:组合注解
@GetMapping -- 平时使用的会比较多,它所扮演的是 @RequestMapping(method =RequestMethod.GET) 的一个快捷方式
@PostMapping
@PutMapping
@DeleteMapping
@PatchMapping
数据处理及跳转
1,ServletAPI
-
通过设置ServletAPI , 不需要视图解析器 .
①、通过HttpServletResponse进行输出
②、通过HttpServletResponse实现重定向
③、通过HttpServletResponse实现转发
- 示例代码:
@GetMapping("demo02")
public String demo02(HttpServletRequest request, HttpServletResponse response, Model model){
HttpSession session = request.getSession();
model.addAttribute("msg","SessionID:"+session);
return "index";
}
@GetMapping("/demo03")
public void demo03(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.getWriter().println("Hello,Spring BY servlet API");
}
@RequestMapping("/demo04")
public void demo04(HttpServletRequest req, HttpServletResponse rsp) throws IOException {
rsp.sendRedirect("/SpringMVCTest/index.jsp");
}
@RequestMapping("/demo05")
public void demo05(HttpServletRequest req, HttpServletResponse rsp) throws Exception {
//转发
req.setAttribute("msg","/demo05");
req.getRequestDispatcher("/index.jsp").forward(req,rsp);
}
2,视图解析器
- 通过SpringMVC来实现转发和重定向,无需视图解析器
- 示例代码:
@RequestMapping("/demo06")
public String demo06(){
//默认:转发
// return "/index.jsp";
return "forward:/index.jsp";
}
@RequestMapping("/demo07")
public String demo07(){
//重定向
//return "redirect:hello.do"; hello.do为另一个请求
return "redirect:/index.jsp";
}
- 通过SpringMVC来实现转发和重定向,有视图解析器
@RequestMapping("/demo08")
public String demo08(){
return "index";
}
- 重定向 , 不需要视图解析器 , 本质就是重新请求一个新地方 , 注意路径问题
3,处理提交数据
- 提交的域名称和处理方法的参数名一致
@RequestMapping("/demo09")
public String demo09(String name){
System.out.println(name);
return "index";
}
- 提交的域名称和处理方法的参数名不一致
//@RequestParam("uname") : uname提交的域的名称 .
@RequestMapping("/demo10")
public String demo10(@RequestParam("uname") String name){
System.out.println(name);
return "index";
}
}
- 提交的是一个对象,要求提交的表单域和对象的属性名一致 , 参数使用对象即可,前端传递的参数名和对象名必须一致,否则就是null。
@RequestMapping("/user")
public String user(User user){
System.out.println(user);
return "index";
}
测试地址:
http://localhost:8080/SpringMVCTest/user?name=kuangshen&id=1&age=15
4,数据显示到前端
-
①,通过ModelAndView
具体可参照上面的示例代码
- ②,通过ModelMap
@RequestMapping("/demo11")
public String demo11(@RequestParam("username") String name, ModelMap model){
//封装要显示到视图中的数据
//相当于req.setAttribute("name",name);
model.addAttribute("name",name);
System.out.println(name);
return "index";
}
- ③,通过Model
@RequestMapping("/demo12")
public String demo12(@RequestParam("username") String name, Model model){
//封装要显示到视图中的数据
//相当于req.setAttribute("name",name);
model.addAttribute("msg",name);
System.out.println(name);
return "index";
}
-
对比
Model 只有寥寥几个方法只适合用于储存数据,简化了新手对于Model对象的操作和理解;
ModelMap 继承了 LinkedMap ,除了实现了自身的一些方法,同样的继承 LinkedMap 的方法和特性;
ModelAndView 可以在储存数据的同时,可以进行设置返回的逻辑视图,进行控制展示层的跳转。
5,乱码问题
- 以前乱码问题通过过滤器解决 , 而SpringMVC给我们提供了一个过滤器 , 可以在web.xml中配置
- 示例代码:
- encode.html
<form action="/SpringMVCTest/demo13" method="post">
<input type="text" name="name">
<input type="submit">
</form>
- DemoController.java
@RequestMapping("/demo13")
public String demo13(Model model,String name){
model.addAttribute("msg",name); //获取表单提交的值
return "index"; //跳转到index页面显示输入的值
}
- index.jsp
- web.xml
<!--配置DispatchServlet:这个是SpringMVC的核心;请求分发器,前端控制器 -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<!-- 启功级别 1 -->
<load-on-startup>1</load-on-startup>
</servlet>
<!--在SpringMVC中,
/:只匹配所有的请求,不会去匹配jsp页面
/*:匹配所有的请求,包括jsp
-->
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>encoding</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>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
下一章,(5)SpringMVC————JSON数据交互,Ajax,文件上传和下载以及拦截器