前言
MVC框架(Model+View+Controller):
1.将url映射到java类或Java类的方法;
2.封装用户提交的数据;
3.处理请求–调用相关业务处理—封装响应数据;
4.将响应的数据进行渲染.jsp/html等表示层数据;
常见的服务器端MVC框架:
1.Struts
2.Spring MVC
3.ASP.NET MVC
4.Zend Framwork
5.JSF
常见前端MVC框架:
1.vue(MVVM:由MVC演进而来)
2.angularjs
3.react
4.backbone
一.创建一个项目SpringMvcOrigin
这个项目完全使用spring的配置文件,实际开发不会这么使用,这里是为了说明springMVC的原理;新建项目时不建议在此处选择webapp模板,因为会出现maven版本问题可能需要修改:
而是在项目创建完成后,右键项目添加web支持:
使用springMVC,需要导入依赖包(spring-webmvc):
<dependencies>
<!--spring-webmvc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<!--servlet-api-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<!--jsp-api-->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
<!--jstl-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
添加web支持后,在web-info文件夹下新建jsp包,添加一个视图test.jsp用于测试
视图有了,下面配置web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--1.配置DispatcherServlet:springMVC的核心,请求分发器,前端控制器,所有的请求都会经过它-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--2.DispatcherServlet绑定spring配置文件-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<!--3.设置DispatcherServlet启动级别:1,和tomcat同时启动-->
<load-on-startup>1</load-on-startup>
</servlet>
<!--4.在springMVC中:建议使用 /
/ 表示只匹配所有的请求,不会去匹配jsp页面;
/* 匹配请求,也会匹配jsp页面
-->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
在web.xml中,绑定了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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--1.处理器映射器-->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<!--2.处理器适配器-->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<!--3.视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver">
<!--前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--后缀-->
<property name="suffix" value=".jsp"/>
</bean>
</beans>
接下来就可以写视图控制器了,这里通过实现Controller接口import org.springframework.web.servlet.mvc.Controller;
的方式:
package com.han.controller;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class SpringMvcOriginController implements Controller {
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
ModelAndView mv=new ModelAndView();
//业务代码
String result="hello,springMVC";
//数据封装:msg是返回给前端的数据
mv.addObject("msg",result);
//视图跳转:将test.jsp返回给前端;控制器处理后,经视图解析器拼接后就是/WEB-INF/jsp/test.jsp这个视图
mv.setViewName("test");
return mv;
}
}
还差一步,将控制器注册到spring-mvc.xml中:
id表示访问的路路径:localhost:8080/test;
<!--注册处理器-->
<bean id="/test" class="com.han.controller.SpringMvcOriginController"/>
代码就写好了,需要配置tomcat服务器
点击左上角的"+",选择Tomcat Server,选择Local,第一次使用需用Configure:
选择Deployment,选择右侧"+",选择Artifacts,表示选择需要打包的项目:
还差一步,否则tomcat无法成功运行:
在Artifacts的包的WEB_INF下有个classes文件夹,需要再建立一个于classes同级的文件夹lib;
选中lib,选择"+",library Files,将所有的依赖包添加进来就完成了;
运行tomcat测试,成功
输入之前设定的url:id=“test”,成功返回视图test.jsp
//业务代码
String result="hello,springMVC";
//数据封装:msg是返回给前端的数据
mv.addObject("msg",result);
//视图跳转:将test.jsp返回给前端
mv.setViewName("test");
<html>
<head>
<title>Title</title>
</head>
<body>
${msg}
</body>
</html>
注:这个项目是说明springMVC的原理的;
第一步:前端提交一个请求localhost:8080/test;
第二步:服务器tomcat处理请求,交给web.xml中配置的DispatcherServlet
(springMVC的核心,请求分发器,前端控制器,所有的请求都会经过它);
第三步:DispatcherServlet
根据请求的url:/test,去绑定的配置文件spring-mvc.xml中通过处理器映射器BeanNameUrlHandlerMapping
和处理器适配器SimpleControllerHandlerAdapter
寻找对应的控制器并适配到spring-mvc.xml中注册的控制器
<bean id="/test" class="com.han.controller.SpringMvcOriginController"/>
,发现对应/test的是SpringMvcOriginController
,于是去相应的包下面找到控制器处理请求;在这个控制器中,mv封装数据,最后被视图解析器InternalResourceViewResolver
拼接前缀和后缀,找到对应文件夹下的视图test.sjp,mv封装视图;封装完成后,再次交给DispatcherServlet
,由它将视图和数据返回给前端;
注意一个问题:将视图放在WEB-INF下的jsp文件夹下面,是为了保证视图安全,因为这个目录下的文件,客户端不能直接访问.
原理部分,完!
二.SpringMVC—注解
上面的项目是讲述原理,一般不会使用,而是通过注解的方式
确定几个环境:
已经导入spring-webmvc的依赖包;
已经加入了webapp的支持;
已经配置了tomcat服务器;
已经将所有依赖包添加到WEB_INF下的lib;
使用注解开发
1.web.xml这个配置文件是不变的
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--1.配置DispatcherServlet:springMVC的核心,请求分发器,前端控制器,所有的请求都会经过它-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--2.DispatcherServlet绑定spring配置文件-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<!--3.设置DispatcherServlet启动级别:1,和tomcat同时启动-->
<load-on-startup>1</load-on-startup>
</servlet>
<!--4.在springMVC中:建议使用 /
/ 表示只匹配所有的请求,不会去匹配jsp页面;
/* 匹配请求,也会匹配jsp页面
-->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
2.web.xml中绑定了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
https://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.han.controller"/>
<!--2.静态资源过滤掉,不走视图解析器-->
<mvc:default-servlet-handler/>
<!--3.支持mvc注解驱动:自动开启、配置和注入处理器的映射器和适配器-->
<mvc:annotation-driven/>
<!--4.视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver">
<!--前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--后缀-->
<property name="suffix" value=".jsp"/>
</bean>
</beans>
3.之前的控制器需要在spring-mvc.xml中注册,现在使用注解
@Controller
,表明当前的bean是一个控制器,无需注册;
@RequestMapping("/annoTest")
,表明当前控制器处理的请求是/annoTest
,也就是之前在配置文件中注册控制器是的bean的id;@RequestMapping可以加载方法或者类上面,如果加载类上面,就给每个方法上的请求前面加了一层父路径,比如:@RequestMapping(“Anno”)
没有注释掉,那么AnnotationController 这个控制器处理的请求应该是/Anno/annoTest
;
之前对数据的封装和视图的跳转是使用ModelandView这个类,使用setViewName和addObject方法;现在只要给方法添加参数Model model
,再通过方法model.addAttribute("msg","hello,springMvcAnnotation");
就可以封装返回给前端的数据了,如这里返回的是msg
,内容是hello,springMvcAnnotation
;视图的跳转:只要这个方法返回值类型是String,而且返回的值annotationTest是一个视图的名字,就会自动走视图解析器,返回这个视图.
package com.han.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
//@RestController
//@ResponseBody
//@RequestMapping("Anno")
public class AnnotationController {
@RequestMapping("/annoTest")
public String Annotation(Model model){
//封装数据
model.addAttribute("msg","hello,springMvcAnnotation");
//返回视图
return "annotationTest";
}
}
但是,如果//@ResponseBody
没有被注释掉,返回值annotationTest
就不会被解析,而是当作一个字符串被返回到前端;或者直接使用@RestController
也是返回字符串;所以,@RestController 等价于 @Controller + @ResponseBody
注意:视图是可以复用的,也就是不同的Controller有不同的RequestMapping,但是返回值可以相同,这样不同的请求就跳转到了相同的视图页面;
三.乱码过滤问题
产生乱码的原因比较多
比如Tomcat服务器(tomcat->config->server.xml)没有设置UFT-8编码;
IDEA开发工具没有设置UTF-8编码;
项目中没有乱码过滤的配置:在web.xml中配置下面的代码,这是spring帮我们做的过滤配置;导入即可
<!--配置乱码过滤-->
<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>
四.请求路径的Restful风格
https://editor.youkuaiyun.com/md?name=1&age=2
https://editor.youkuaiyun.com/md/1/2
写一个控制器,注意它的RequestMapping
需要给前端传来的参数加上注解@PathVariable
,否则很可能参数名对应上了也无法识别;
注意:前端传的参数名a,b必须和控制器中的方法接收的参数名完全一样
@RequestMapping("/restful/{a}/{b}")
public String restful(@PathVariable int a, @PathVariable int b, Model model){
System.out.println("a="+a);
System.out.println("b="+b);
int result=a+b;
model.addAttribute("result",result);
return "restful";
}
测试
五.组合注解
@GetMapping
比如@RequestMapping(value="/annoTest",method = RequestMethod.GET)
组合注解为@GetMapping(value="/annoTest")
@PostMapping
比如@RequestMapping(value="/annoTest",method = RequestMethod.POST)
组合注解为@PostMapping(value="/annoTest")
HEAD PUT PATCH DELETE OPTIONS TRACE...
完!