核心组件:DispatcherServlet
DispatcherServlet:Spring-Mvc给我们的Servlet,这个Servlet会过滤所有请求,并根据请求的路径信息中找到Spring容器中对应的类中的方法,这样的好处是,不用再写那么多的Servlet类了,现在在一个Servlet中,不同的Servlet写成了Controller中的方法,就可以完成很多Servlet的功能。
web.xml中的配置文件的写法:
<web-app>
<display-name>Archetype Created Web Application</display-name>
<servlet>
<!--创建DispatcherServlet-->
<servlet-name>springservlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<!--加载Spring的配置文件-->
<param-name>contextConfigLocation</param-name>
<!--Spring配置文件的位置-->
<param-value>classpath:springConfigure.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springservlet</servlet-name>
<!--所有的请求都会过DispatcherServlet-->
<url-pattern> /* </url-pattern>
</servlet-mapping>
</web-app>
配置过程:
浏览器向服务器发送数据的过程
1、设置浏览器的请求方式
@RequestMapping(value = "/login.do", method = {RequestMethod.GET, RequestMethod.POST})
@GetMapping("/login.do")
两种注解方式:
- 可以在@RequestMapping中添加参数,设置是GET请求还是POST请求
- @GetMapping和@PostMapping直接设置请求方式
- 基础数据类型和String类型的数据
@Controller
@RequestMapping("/user")
public class Conroller {
@GetMapping("/login.do")
public void doget(int id, String str) {
System.out.println(id);
}
}
URL:http://localhost:8080/Spring_MVC_Test_war/user/login.do?id=1&str=hahaha
当浏览器的传送的数据名称等于参数名时,数据就会传递过来
- 对象数据类型
@Controller
@RequestMapping("/user")
public class Conroller {
@Autowired
IUserService service;
@GetMapping("/login.do")
public void doget(User user) {
System.out.println(user);
}
}
URL:http://localhost:8080/Spring_MVC_Test_war/user/login.do?username=lalaal&pwd=111
浏览器传入的参数和实体类的属性名一一对应,就会传入对象数据。
3、获取前端发过来的Cookie和Session
- 导入Servlet-api的jar包,拿到HttpServletRequest,获得Cookie和Session
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
@Controller
@RequestMapping("/user")
public class Conroller {
@Autowired
IUserService service;
@GetMapping("/login.do")
public void doget(User user, HttpServletRequest request) {
Cookie[] cookie = request.getCookies();
HttpSession session = request.getSession();
}
}
- 直接在方法参数上设置,获取Session
@Controller
@RequestMapping("/user")
public class Conroller {
@Autowired
IUserService service;
@GetMapping("/login.do")
public void doget( User user, HttpSession session) {
System.out.println(session.getId());
System.out.println(user);
}
}
服务器向浏览器返还数据
1、直接发送数据
ViewResolver(视图解析器)
1、用户发送请求到前端控制器(DispatcherServlet)。
2、前端控制器请求处理器映射器(HandlerMapping)去查找处理器(Handler)。
3、找到以后处理器映射器(HandlerMappering)向前端控制器返回执行链(HandlerExecutionChain)。
4、前端控制器(DispatcherServlet)调用处理器适配器(HandlerAdapter)去执行处理器(Handler)。
5、处理器适配器去执行Handler。
6、处理器执行完给处理器适配器返回ModelAndView。
7、处理器适配器向前端控制器返回ModelAndView。
8、前端控制器请求视图解析器(ViewResolver)去进行视图解析。
9、视图解析器向前端控制器返回View。
10、前端控制器对视图进行渲染。
11、前端控制器向用户响应结果。
异步提交:
1、向浏览器返回基本数据类型和Stirng类型的数据
加上@ResponseBody:由于返回值是String类型的,所以我们的Handler返回了一个ModelandView交给适配器,然后适配器将ModelandView传给DispatcherServlet,DispatcherServlet在将modelandview发给视图解析器解析,由于加上了@ResponseBody,所以视图解析器就会知道要将这个model解析成字符的形式,然后将字符返还给DispatcherServlet,之后将数据发给Ajax,这样前端就会获得一个String的数据。
@Controller
@RequestMapping("/user")
public class Conroller {
@Autowired
IUserService service;
@GetMapping("/login.do")
@ResponseBody
public String doget(int id) {
User user = service.get(id);
//直接向前端返回数据
return user + " ";
}
}
xmlns:mvc="http://www.springframework.org/schema/mvc"
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
<!-- 开启mvc注解驱动-->
<mvc:annotation-driven></mvc:annotation-driven>
2、向浏览器返回对象数据类型
添加jar包,返回的是一个json数据,加上@ResponseBody的话,我们的Handler将会返回了一个ModelandView交给适配器,然后适配器将ModelandView传给DispatcherServlet,DispatcherServlet在将modelandview发给视图解析器解析,由于加上了@ResponseBody,所以视图解析器就会将对象的属性转换成字符串的格式(也可以看成返回了toString()的返回值),然后将字符返还给DispatcherServlet,此时DispatcherServlet就会用fastjson将属性的字符串转换为一个json对象,之后将json对象发给Ajax,这样前端就会获得一个json对象。
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.10.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.2</version>
</dependency>
同步提交:
1、在web.xml文件中修该过滤的请求
<servlet-mapping>
<servlet-name>springservlet</servlet-name>
<url-pattern>*do</url-pattern>
</servlet-mapping>
让DispatcherServlet过滤所有.do的请求,所以此时html页面是会访问的,tomcat直接就去寻找.html页面,不会经过DispatcherServlet去找,所以可以访问到静态页面。
2、设置Spring中声明静态资源文件
<mvc:resources mapping="/static/**" location="/static/"></mvc:resources>
声明在static包下的文件都是静态页面,不由HandlerMapping映射,就可以访问html文件了。
由于在Spring的配置文件中声明了静态页面的位置,当DispatcherServlet过滤所有的请求之后,直接会去寻找静态页面的位置,然后把静态页面返回给前端,就不会再去找HandlerMapping映射了。
2、重定向
去掉@ResponseBody,在返回时添加redirect:/静态资源位置/重定向的html页面
@Controller
@RequestMapping("/user")
public class Conroller {
@Autowired
IUserService service;
@GetMapping("/login.do")
public String doget(int id) {
User user = service.get(id);
return "redirect:/static/index.html";
}
}
3、转发
1、spring中配置视图解析
- springmvc配置资源解析器
<!-- springmvc配置资源解析器-->
<mvc:view-resolvers>
<mvc:jsp prefix="/jsp/" suffix=".jsp" view-class="org.springframework.web.servlet.view.JstlView"></mvc:jsp>
</mvc:view-resolvers>
- 手动配置资源解析器
<!-- 配置资源解析器viewResolver-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 前置,前面-->
<property name="prefix" value="/jsp/"></property>
<!-- 后置,后面添加-->
<property name="suffix" value=".jsp"></property>
<!-- 告诉视图解析器这是个jsp页面-->
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>
</bean>
2、Controller中创建 ModelAndView
@Controller
@RequestMapping("/user")
public class Conroller {
@Autowired
IUserService service;
@GetMapping("/login.do")
public ModelAndView doget(int id) {
User user = service.get(id);
// 设置modelAndView,向前端返回一个对象
ModelAndView mav = new ModelAndView();
// 设置向前端返回对象数据的名称和,具体的数据
mav.addObject("result" ,user);
// 要将modelAndView转发到哪个视图解析器中去
mav.setViewName("success");
return mav;
}
}
3、jsp页面中拿到 ModelAndView的值,并在页面中显示出来
<%@ page import="com.lanou.test.entity.User" %><%--
Created by IntelliJ IDEA.
User: shiruntao
Date: 20-6-19
Time: 下午8:24
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
成功登陆,这是一个jsp页面 <%= ((User) request.getAttribute("result")).getUsername()%>
</body>
</html>