1、springMVC的执行过程
![图片源自https://blog.csdn.net/number_oneengineer/article/details/82775419]
Spring MVC 组件
DispatcherServlet:SpringMVC 中的前端控制器,是整个流程控制的核心,负责接收请求并转发给对应的处理组件。
Handler:处理器,完成具体业务逻辑,相当于 Servlet 或 Action。
HandlerMapping:完成 URL 到 Controller 映射,DispatcherServlet 通过
HandlerMapping 将不同请求映射到不同 Handler。
HandlerInterceptor:处理器拦截器,是一个接口,如果需要完成一些拦截处理,可以实现该接口。
HandlerExecutionChain:处理器执行链,包括两部分内容:Handler 和 HandlerInterceptor。
HandlerAdapter:处理器适配器,Handler执行业务方法前需要进行一系列操作,包括表单数据验证、数据类型转换、将表单数据封装到JavaBean等,这些操作都由
HandlerAdapter 完成。DispatcherServlet 通过 HandlerAdapter 来执行不同的 Handler。ModelAndView:装载模型数据和视图信息,作为 Handler 处理结果返回给 DispatcherServlet。
ViewResolver:视图解析器,DispatcherServlet 通过它将逻辑视图解析为物理视图,最终将渲染的结果响应给客户端。
2、 配置web和Spring文件
配置web.xml
<servlet>
<servlet-name>SpringMvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringMvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
配置spring的配置文件
<?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/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
<!--扫描包-->
<context:component-scan base-package="com.lanou.test"></context:component-scan>
<!-- 开启mvc注解驱动-->
<mvc:annotation-driven></mvc:annotation-driven>
<!-- 映射资源文件
表示前面所有的static页面都从这里去找
此时表示父路径是static -->
<mvc:resources mapping="/static/**" location="/static/"></mvc:resources>
<!-- mvc自动配置视图解析器-->
<mvc:view-resolvers>
<!-- jsp页面解析-->
<mvc:jsp prefix="/jsp/" suffix=".jsp" view-class="org.springframework.web.servlet.view.JstlView"></mvc:jsp>
</mvc:view-resolvers>
<!-- 手动配置单个视图解析器
InternalResourceViewResolver——全局资源视图解析器
UrlBasedViewResolver——基于url的视图解析器-->
<!-- <bean id="ViewResolve" class="org.springframework.web.servlet.view.UrlBasedViewResolver">-->
<!--<!– 前置–>-->
<!-- <property name="prefix" value="/jsp/"></property>-->
<!--<!– 后置–>-->
<!-- <property name="suffix" value=".jsp"></property>-->
<!--<!– 解析类型–>-->
<!--<!– <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>–>-->
<!-- </bean>-->
<bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.lanou.test.mapper"></property>
</bean>
<bean id="dataSource" class="org.apache.ibatis.datasource.pooled.PooledDataSource">
<property name="url" value="jdbc:mysql://localhost:3306/db_foo?serverTimezone=UTC"></property>
<property name="driver" value="com.mysql.cj.jdbc.Driver"></property>
<property name="username" value="root"></property>
<property name="password" value="235689"></property>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="mapperLocations" value="classpath:mapper/*.xml"></property>
</bean>
</beans>
配置Controller类
在Controller类上加上
@Controller
@RequestMapping("/test")
在方法上加上
@RequestMapping("/foo.do")
@RequestMapping
@RequestMapping 是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。
RequestMapping的 value, method属性;
value: 指定请求的实际地址,指定的地址可以是URI Template 模式;
method: 指定请求的method类型, GET、POST、PUT、DELETE等;
还有一个注意的,@RequestMapping的默认属性为value。
映射单个url
@RequestMapping(value = "/foo.do")等价于@RequestMapping("/foo.do")
映射多个url
这时候两个接口执行同一个逻辑
@RequestMapping(value = {"/foo.do",/test.do...})
限制请求方法的URL 映射
只支持post请求
@RequestMapping(value = "/foo.do",method = RequestMethod.POST)
限制多个请求方法的url映射
支持post和get
@RequestMapping(value = "/foo.do", method = {RequestMethod.POST, RequestMethod.GET})
@RequestParam:
将请求参数绑定到你控制器的方法参数上(是springmvc中接收普通参数的注解)
语法:
@RequestParam(value=”参数名”,required=”true/false”,defaultValue=””)
属性:
value:参数名,此时请求路径只能传这个参数名
required:是否包含该参数,默认为true,表示该请求路径中必须包含该参数,如果不包含就报错。
defaultValue:默认参数值,如果设置了该值,required=true将失效,自动为false,如果没有传该参数,就使用默认值
@RequestParam(value = "yy", required = true, defaultValue = "我是String")
获得前端传过来的数据
方法加上参数
@RequestMapping(value = "/foo.do",method = {Requestethod.POST, RequestMethod.GET})
public void foo(@RequestParam(value = "yy", required = true, defaultValue = "我是String")String string) {
System.out.println("我也很无语啊" + string);
}
SpringMVC中使用HttpServletRequest 和 HttpServletResponse
@RequestMapping(value = "foo.do",method = {RequestMethod.POST, RequestMethod.GET})
public void foo(User user, HttpServletRequest req, HttpServletResponse resp) {
System.out.println(req.getParameter("account"));
try {
resp.setContentType("text/html;charset=utf8");
resp.getWriter().println("使用resp返回内容");
} catch (IOException e) {
e.printStackTrace();
}
}
获取session
@RequestMapping(value = "foo.do",method = {RequestMethod.POST, RequestMethod.GET})
public void foo(User user, HttpSession session) {
System.out.println(session.getId());
}
@GetMapping和@PostMapping
分别表示get请求和post请求
@GetMapping和@PostMapping属性里没有method
// @GetMapping = @RequestMapping(method = RequestMethod.GET)
// @PostMapping =@RequestMapping(method = RequestMethod.POST)
@ResponseBody
@ResponseBody是作用在方法上的,@ResponseBody 表示该方法的返回结果直接写入 HTTP response body 中,一般在异步获取数据时使用【也就是AJAX】。
注意:在使用 @RequestMapping后,返回值通常解析为跳转路径,但是加上 @ResponseBody 后返回结果不会被解析为跳转路径,而是直接写入 HTTP response body 中。 比如异步获取 json 数据,加上 @ResponseBody 后,会直接返回 json 数据。@RequestBody 将 HTTP 请求正文插入方法中,使用适合的 HttpMessageConverter 将请求体写入某个对象。
@RequestMapping(value = "login.do")
@ResponseBody
public User login(User user) {
User result = service.login(user);
return result;
}
需要在Spring配置文件中加入
开启mvc注解驱动
<mvc:annotation-driven></mvc:annotation-driven>
向前端返回数据的三种形式
1、直接写内容
方法上要加上@ResponseBody
@RequestMapping(value = "login.do")
@ResponseBody
public String login(User user) {
User result = service.login(user);
return "result";
}
2、重定向
不加@ResponseBody,返回值加redirect
//重定向到一个html页面
@RequestMapping(value = "login.do")
public String login(User user) {
User result = service.login(user);
if (result != null) {
return "redirect:/static/index.html";
}else {
return "redirect:/static/error.html";
}
}
重定向到一个html页面时,需要在applicationContext.xml中配置resources
<!-- 映射资源文件 表示前面所有的static页面都从这里去找 此时表示父路径是static -->
<mvc:resources mapping="/static/**" location="/static/"></mvc:resources>
3、转发
不加@ResponseBody,返回值不加redirect,
// 转发一个jsp
@RequestMapping(value = "login.do")
public String login(User user) {
User result = service.login(user);
return "success";//success视图名称
}
转发的时候,需要在spring配置文件里配置视图解析器
<!-- mvc自动配置视图解析器-->
<mvc:view-resolvers>
<!-- jsp页面解析-->
<mvc:jsp prefix="/jsp/" suffix=".jsp" view-class="org.springframework.web.servlet.view.JstlView"></mvc:jsp>
</mvc:view-resolvers>
<!-- 手动配置单个视图解析器
InternalResourceViewResolver——全局资源视图解析器
UrlBasedViewResolver——基于url的视图解析器-->
<bean id="ViewResolve" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<!-- 前置-->
<property name="prefix" value="/jsp/"></property>
<!-- 后置-->
<property name="suffix" value=".jsp"></property>
<!-- 解析类型-->
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>
</bean>
如果转发的时候带数据,就返回ModelAndView
//转发的时候带数据,返回ModelAndView
@RequestMapping(value = "login.do")
public ModelAndView login(User user) {
User result = service.login(user);
ModelAndView mav = new ModelAndView();
// 给页面填充的对象
mav.addObject("result",result);
mav.setViewName("success");
return mav;
}