1、springMVC相关注解解析
1、@RequestMapping()
该注解既可以放在控制器的类上,又可以放在控制器的方法上,当类上有该注解时,springMVC会将类上的路径做为父路径,给每个方法的路径都添加上,具体看代码
package com.francis.springmvc.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author Francis
* @create 2021-06-10-23:08
*/
@Controller
@RequestMapping("/request")
public class ReqMappingController {
@RequestMapping("/reqmapping1")//真实路径为/request/reqmapping1
public String reqmapping1(Model model){
model.addAttribute("msg", "reqmapping1");
return "hello";
}
@RequestMapping("/reqmapping2")//真实路径为/request/reqmapping2
public String reqmapping2(Model model){
model.addAttribute("msg", "reqmapping2");
return "hello";
}
}
另外@RequestMapping()可以接收所有请求,它还可以接收其他参数,来做出限制请求方式等
* method:限定请求方式,只接受限定类型的请求,默认是什么都可以
* HTTP中的所有请求方式:
* GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE
* method=RequestMethod.POST
* params:规定请求参数
* params 和 headers支持简单的表达式:
param1: 表示请求必须包含名为 param1 的请求参数
eg:params={"userName"}
发送请求的时候必须带上一个叫userName的参数,否则404
!param1: 表示请求不能包含名为 param1 的请求参数
eg:params={"!userName"}
param1 != value1: 表示请求包含名为 param1 的请求参数,但其值不能为 value1
eg:params={"userName!=123"}
发送请求的时候携带的userName值必须不是123
{“param1=value1”, “param2”}: 请求必须包含名为 param1 和param2 的两个
请求参数,且 param1 参数的值必须为 value1
* headers:规定请求头,和params一样写简单的表达式
* consumes:指接受内容类型是哪种的请求,只要规定(请求头中)的Content-Type
* produces:告诉浏览器返回的内容类型,给响应头中加入Content-Type
当然,在限制请求类型上,可以使用@GetMapping注解来表示只接收get请求, @PostMapping注解来表示只接收post请求
2、@Controller与@RestController
@RestController注解相当于@ResponseBody + @Controller合在一起的作用
1、@Controller注解
@Controller 是Spring框架提供的注解。
@Controller标识的类,该类代表控制器类(控制层/表现层)。
这里控制层里面的每个方法,都可以去调用@Service标识的类(业务逻辑层),@Service标识的类中的方法可以继续调用@Resposity标识的接口实现类(Dao层/持久层)。
MVC设计模式:M(model)指模型,V(view)指视图层,C(controller)指控制层。
M代表模型一般指service和DAO;view代表视图一般指页面eg:jsp,html ftl等;C代表控制器,比如springMVC 中的controller或struts2中的action 。
MVC其实我们正常理解应该是VMC:JSP/HTML页面数据–>控制器–>数据逻辑处理并持久化。
但官方是MVC,所以我们按照MVC这么记住就对了。
使用@Controller注解是,需要将模型传给视图显示,在方法中可以带上Model参数或者ModelAndView,然后往里面设置值,在前端页面就可以通过表达式取到了。
2、@RestController注解
@RestController 也是Spring框架提供的注解。(Spring4.0之后新增的)
@RestController 注解相当于 @Controller + @ResponseBody 合在一起的作用。
Controller类中的方法返回值,默认是json对象,也就是相当于@Controller里面的方法上添加了@ResponseBody
如果方法返回值,需要跳转,那么方法的返回类型必须是View 或者ModelAndView.
2、通过SpringMVC实现重定向和转发:
可以使用servlet来实现重定向和转发,但这样做太麻烦了,我们使用springMVC的方式。
先复习一下概念
请求重定向 和 请求转发都是web开发中资源跳转的方式。
(1)请求转发是服务器内部的跳转
地址栏不发生变化
只有一个请求响应
可以通过request域传递数据
(2)请求重定向是浏览器自动发起对跳转目标的请求
地址栏会发生变化
两次请求响应
无法通过request域传递对象
在SpringMVC中仍然可以使用传统方式实现转发和重定向
request.getRequestDispatcher("").forward(request, response);
response.sendRedirect("");
在SpringMVC中也提供了快捷方法实现转发和重定向
只要在返回视图时,使用如下方式指定即可:
redirect:/xxx.action
forward:/xxx.action
/**
* 实现转发
* @throws Exception
*/
@RequestMapping("/hello11")
public String hello11(HttpServletRequest request) throws IOException, Exception{
request.setAttribute("name", "francis");
return "forward:/hello";
}
/**
* 实现重定向
* @throws Exception
*/
@RequestMapping("/hello2")
public String hello12(HttpServletRequest request) throws IOException, Exception{
request.setAttribute("name", "francis");
return "redirect:/hello";
}
即是说,在视图前面加上==redirect:或者forward:来指定是重定向或转发。默认是forward:==可以省略。
3、拦截器
SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。开发者可以自己定义一些拦截器来实现特定的功能。
1、过滤器与拦截器的区别:
拦截器是AOP思想的具体应用。
过滤器
(1)servlet规范中的一部分,任何java web工程都可以使用
(2)在url-pattern中配置了/*之后,可以对所有要访问的资源进行拦截
**拦截器 **
(1)拦截器是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才能使用
(2)拦截器只会拦截访问的控制器方法, 如果访问的是jsp/html/css/image/js是不会进行拦截的
2、那如何实现拦截器呢?
想要自定义拦截器,必须实现 HandlerInterceptor 接口。
1、新建一个模块,添加web支持
2、配置web.xml及springmvc-servlet.xml
3、编写一个拦截器
package com.francis.springmvc.common.config.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author Francis
* @create 2021-06-13-15:21
*/
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("拦截器之前");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("处理后");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("清理");
}
}
4、在springmvc-servlet.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">
<!-- 自动扫描包,让指定包下的注解生效,由IOC容器统一管理 -->
<context:component-scan base-package="com.francis.springmvc.controller"/>
<!-- 让Spring MVC不处理静态资源 -->
<mvc:default-servlet-handler />
<!--
支持mvc注解驱动
在spring中一般采用@RequestMapping注解来完成映射关系
要想使@RequestMapping注解生效
必须向上下文中注册DefaultAnnotationHandlerMapping
和一个AnnotationMethodHandlerAdapter实例
这两个实例分别在类级别和方法级别处理。
而annotation-driven配置帮助我们自动完成上述两个实例的注入。
-->
<mvc:annotation-driven />
<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
id="internalResourceViewResolver">
<!-- 前缀 -->
<property name="prefix" value="/WEB-INF/view/" />
<!-- 后缀 -->
<property name="suffix" value=".jsp" />
</bean>
<mvc:interceptors>
<mvc:interceptor>
<!--拦截的路径,/**代表所有请求-->
<mvc:mapping path="/**"/>
<!--配置不拦截的请求-->
<mvc:exclude-mapping path="/login"/>
<!--拦截请求的拦截器-->
<bean class="com.francis.springmvc.common.config.interceptor.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
</beans>