SpringMVC的handMapping
比较重要的部分
比较重要的部分
比较重要的部分
关于组件的部分
这里以 RequestMappingHandlerMapping 为例子
默认的3个组件是:
org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
org.springframework.web.servlet.function.support.RouterFunctionMapping
如果在spring-mvc.xml中配置了自定义的 HandlerMapping 组件,则不会加载默认的3个组件(你自定义了组件就不用springmvc默认的组件了)
下面的代码的加载过程
SpringMVC的请求处理
SpringMVC的请求处理-Bean
SpringMVC的请求处理-转为对象
文件上传
获取head
静态资源
1、tomcat是defaultServlet 默认接受请求 /
2、dispatherServlet 的 默认路径 / ,覆盖了原先的 defaultServlet 。找不到原来的资源
3、解决方法:
方法1
方法2
<mvc:default-servlet-handler />的作用原理
总结:
向容器中注入了SimpleUrlHandlerMapping (SimpleUrlHandlerMapping 是一个Mapping)
是 Spring MVC 中的一项配置,用于处理静态资源请求。它的主要作用是在 Spring MVC 的 DispatcherServlet 无法处理的请求时,将这些请求传递给 servlet 容器的默认 servlet,例如 Tomcat 的 DefaultServlet
。
<mvc:annotation-driven>干了点啥
配置上注解就等于把大的红色框里的东西替代了
总结:
启用注解支持:
- 当你添加
<mvc:annotation-driven />
时,Spring 会自动配置相关的组件,以支持使用注解定义的控制器。这样,你可以使用如@Controller
和@RequestMapping
等注解而无需额外的配置。
- 当你添加
HTTP 消息转换:
- 此配置会自动注册
HttpMessageConverter
,用于将 HTTP 请求和响应中的数据类型(如 JSON 和 XML)进行转换。通过这个功能,Spring 可以根据请求的Content-Type
和Accept
头部自动选择合适的转换器。 - 例如,使用
@ResponseBody
和@RequestBody
注解时,Spring 会使用 JSON 或 XML 转换器将 Java 对象与 HTTP 消息体内容相互转换。
- 此配置会自动注册
视图解析器:
- 启用后,Spring 会自动配置默认的
ViewResolver
,处理不同的视图解决方案,使得返回的视图能够被正确解析。
- 启用后,Spring 会自动配置默认的
作用原理:
`<mvc:annotation-driven />` 在 Spring MVC 中的作用是启用基于注解的 MVC 配置。这个功能的底层实现机制和原理相对复杂,以下是它的主要原理和功能组件:
### 1. **HttpMessageConverters**
使用 `<mvc:annotation-driven />` 时,Spring 会自动注册一组 `HttpMessageConverter`,这些转换器负责将请求体转换为 Java 对象,同时也将 Java 对象转换为响应体。常见的 `HttpMessageConverter` 包括:
- `MappingJackson2HttpMessageConverter`:用于 JSON 转换,使用 Jackson 库。
- `Jaxb2RootElementHttpMessageConverter`:用于 XML 转换。
- 其他用于处理文本、字节流等的转换器。
### 2. **RequestMappingHandlerMapping**
添加 `<mvc:annotation-driven />` 后,Spring 会注册一个 `RequestMappingHandlerMapping` 实例,这是用来管理请求映射的。它的工作原理如下:
- **URL 路由**:根据请求的 URL、HTTP 方法等信息,将请求映射到一个具体的处理方法(使用了 `@RequestMapping` 或类似注解的方法)。
- 此外,它会解析控制器半径(可以通过 `@Controller` 注解标识)。
### 3. **RequestMappingHandlerAdapter**
`RequestMappingHandlerAdapter` 是用来调用处理器方法的适配器。其作用包括:
- **参数解析**:将 HTTP 请求中的参数、请求体、路径变量等映射到处理器方法的参数上。
- **返回值处理**:处理方法返回结果的转换,确保将 Java 对象转换成适当的 HTTP 响应格式(比如 JSON 或 HTML)。
### 4. **@Controller 和 @RequestMapping**
- 当你使用 `@Controller` 注解标记的类时,该类会被 Spring 识别为控制器,并由 Spring 的 IOC 容器管理。
- 在类中的方法上使用 `@RequestMapping` 注解,Spring 会建立 URL 路由与方法之间的对应关系。
### 5. **视图解析器**
虽然 `<mvc:annotation-driven />` 本身并不直接配置视图解析器,但这项配置通常与视图解析相关联。Spring 会提供默认的视图解析器,帮助根据返回的视图名称(例如返回字符串 `"viewName"`)来解析到实际的视图资源(如 JSP)。
### 6. **总结**
总体来看,`<mvc:annotation-driven />` 的核心原理是将一系列基于注解的配置和组件集成在一起,以便简化使用 Spring MVC 开发时的配置工作。它自动加入了很多关键的支持,确保请求可以被适当地映射、处理和响应,同时也提供了一种更清晰和声明式的编程风格。
如果你对这个主题还有更深入的疑问或需要具体的代码示例,请告诉我!
SpringMVC的转发重定向
Springmvc拦截器
Springmvc配置路径
--- ? :匹配文件名中得一个字符
--- * :匹配文件名得任意字符
---** : ** 匹配多层路径
/* --> /a /success /text
/** --> 所有的路径
// 例子如下:
/user/*/createrUser ====>匹配:/user/aaa/createrUser
/user/**/createrUser ====>匹配:/user/createrUser /user/aaa/bbb/createrUser
/user/createrUser?? ====>匹配:/user/createrUseraa /user/createrUserbb
乱码
- get乱码:修改tomcat 的server.xml 中的 connector port =’8080’ URIEncoding=’UTF-8’
- post乱码:设置web.xml中的过滤器
springmvc异常
域对象共享数据
- 使用request ----> request.setAttribute(“key”,”value”);
- 使用modelAndView ----> 推荐使用
- 使用model
- 使用map
- 使用session ----> 推荐使用
- 使用application ----> 推荐使用
- model、 modelMap、Map的关系
springmvc使用注解替换XML- 组件扫描
以上配置替换为
springmvc使用注解替换XML- 文件上传
<!-- 处理文件上传与下载-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 必须和用户JSP 的pageEncoding属性一致,以便正确解析表单的内容 -->
<property name="defaultEncoding" value="UTF-8"></property>
<!-- 文件最大大小(字节) 1024*1024*50=50M-->
<property name="maxUploadSize" value="52428800"></property>
<!--resolveLazily属性启用是为了推迟文件解析,以便捕获文件大小异常-->
<property name="resolveLazily" value="true"/>
</bean>
以上配置替换为
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
@Configuration
public class WebConfig {
@Bean
public CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
// 设置编码
resolver.setDefaultEncoding("UTF-8");
// 设置最大上传文件大小
resolver.setMaxUploadSize(52428800); // 50 MB
// 启用延迟解析
resolver.setResolveLazily(true);
return resolver;
}
}
springmvc使用注解替换XML- 其他配置替换
以上配置替换为 @EnableWebMvc
这个地方就需要了解WebMvcConfigure 。
实现这个接口,放到容器中,会被springmvc发现。
springmvc使用注解替换XML- 消除web.xml
在启动的时候,会加载这个,会走onStartup方法来加载配置
上面这段话的意思是:tomcat启动需要一个 servlertContainerInitializer接口的类
可以自己定义一个类来创建代替web.xml
配置视图映射:
1、自定义的类WebInit 需要 springmc、spirng、filter、请求路径映射
2、创建了springmc配置类
3、创建了spirng配置类
4、重写了 filter 方法
5、重写了请求路径映射方法
6、在springmvc的配置类SpringMvcConfig 配置了thymeleaf的视图解析器、包扫描、注解驱动
7、综上在tomcat启动的时候会加载自定义类WebInit
8、WebInit 类会加载springmc、spirng、filter、请求路径映射
web.xml 中指定了springmc、spirng、filter、请求路径映射
public class WebInit extends AbstractAnnotationConfigDispatcherServletInitializer {
//1指定spirng的配置类
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
//2指定springmvc的配置类
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
//3指定dispathcServlet的路径映射
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
// 4过滤器
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("utf-8");
characterEncodingFilter.setForceResponseEncoding(true);
HiddenHttpMethodFilter hiddenHttpMethodFilter = new HiddenHttpMethodFilter();
return new Filter[]{characterEncodingFilter,hiddenHttpMethodFilter};
}
}
/**
代替springmvc的配置文件
1、扫描组件
2、视图解析
3、view-controller
4、<mvc:default-servlet-handler/>
5、mvc注解驱动
6、文件上传解析器
7、异常处理
8、拦截器
*/
@Configuration
@ComponentScan("com.nuc") // 1、组件扫描
@EnableWebMvc //5、mvc注解驱动
public class SpringMvcConfig implements WebMvcConfigurer {
//2、视图解析 配置 thyleaf 的视图解析器 就可以访问
//3、view-controller
@Override
public void addViewControllers(ViewControllerRegistry registry) {
// hello 是请求地址
// success 是跳转页面
registry.addViewController("/hello").setViewName("success");
}
//4、<mvc:default-servlet-handler/>
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();//默认servler可用
}
// 6、文件上传解析器
@Bean
public MultipartResolver multipartResolver(){
CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver();
return commonsMultipartResolver;
}
//7、异常处理
@Override
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
SimpleMappingExceptionResolver simpleMappingExceptionResolver = new SimpleMappingExceptionResolver();
Properties properties = new Properties();
properties.put("java.lang.Arithmeticexception","error"); //这个错误 跳error页面
properties.put("java.lang.NullpointerException","errorNull"); //这个错误 跳 errorNull 页面
simpleMappingExceptionResolver.setExceptionMappings(properties);
simpleMappingExceptionResolver.setExceptionAttribute("exception"); //将错误信息放在域对象中
resolvers.add(simpleMappingExceptionResolver);
}
//8、拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
//实现自定义拦截器
registry.addInterceptor(new TestInterceptors()).addPathPatterns("/**");
}
}
//实现自定义拦截器
class TestInterceptors implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
springmvc的组件原理-获取applicationContext容器
GenericServlet 的init方法 在 HttpServletBean 实现了 。
在HttpServletBean 的init方法 中 this.initServletBean(); 方法由子类来实现
FrameworkServlet 中实现了 initServletBean 方法
总结:会有2个容器。一个是spring的,一个是springmvc容器的
先从springmvc容器中获取bean
在尝试从spring容器中获取bean
这个地方时从小到大容器的获取.。。。springmvc是子容器,spring是父容器。
springmvc的组件原理-注册9大容器
容器创建完毕,会发一个监听的事件。
监听事件,会调用一个方法
方法里会调用 initStrategies