当前位置: 首页> 汽车> 时评 > 二建咨询在线_东莞网站建设怎么做_外贸网站大全_免费自助建站平台

二建咨询在线_东莞网站建设怎么做_外贸网站大全_免费自助建站平台

时间:2025/7/9 4:22:47来源:https://blog.csdn.net/jlihan/article/details/144807221 浏览次数: 0次
二建咨询在线_东莞网站建设怎么做_外贸网站大全_免费自助建站平台

文章目录

  • 1.SpringMVC的自动管理
    • 1.1中央转发器
      • 1.1.1Spring boot配置多个DispatcherServlet
    • 1.2控制器
      • 1.2.1找到启动类的位置
        • 1.2.1.1SpringApplication.run()
        • 1.2.1.2SpringApplication 构造方法
        • 1.2.1.3deduceMainApplicationClass()
      • 1.2.2@ComponentScan 注解
    • 1.3视图解析器自动管理
    • 1.4静态资源访问
    • 1.5消息转换和格式化
    • 1.6欢迎页面的自动配置
  • 2.SpringBoot扩展springmvc
    • 2.1WebMvcConfigurer 接口
    • 2.2在容器中注册视图控制器(请求转发)
    • 2.3注册格式化器
    • 2.4消息转换器扩展fastjson
    • 2.5拦截器注册


1.SpringMVC的自动管理

中央转发器(DispatcherServlet)

控制器

视图解析器

静态资源访问

消息转换器

格式化

静态资源管理

1.1中央转发器

在之前的SSM项目中,中央转发器需要在.xml中配置

<servlet><servlet-name>chapter2</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping><servlet-name>chapter2</servlet-name><url-pattern>/</url-pattern>
</servlet-mapping>

使用SpringBoot后,中央转发器被SpringBoot自动接管,不需要在web.xml中配置

image-20241229115030621

1.1.1Spring boot配置多个DispatcherServlet

org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration中有个DispatcherServletRegistrationBean这里只能指定一个path

源码如下:

image-20241229142823511

image-20241229142947698

image-20241229143012138

如果想指定多个DispatcherServlet,我们需要自己写DispatcherServletRegistrationBean这个Bean

示例代码如下:

@Autowired
private WebMvcProperties webMvcProperties;
@Autowired
private MultipartConfigElement multipartConfig;@Bean
@Primary
public DispatcherServletRegistrationBean dispatcherServlet1(DispatcherServlet dispatcherServlet) {DispatcherServletRegistrationBean registration = new DispatcherServletRegistrationBean(dispatcherServlet, "/*");registration.setName("dispatcherServlet1");registration.setLoadOnStartup(this.webMvcProperties.getServlet().getLoadOnStartup());if (this.multipartConfig != null) {registration.setMultipartConfig(this.multipartConfig);}return registration;
}@Bean
public DispatcherServletRegistrationBean dispatcherServlet2(DispatcherServlet dispatcherServlet) {DispatcherServletRegistrationBean registration = new DispatcherServletRegistrationBean(dispatcherServlet, "/aaa/*");registration.setName("dispatcherServlet2");registration.setLoadOnStartup(this.webMvcProperties.getServlet().getLoadOnStartup());if (this.multipartConfig != null) {registration.setMultipartConfig(this.multipartConfig);}return registration;
}@Bean
public DispatcherServletRegistrationBean dispatcherServlet3(DispatcherServlet dispatcherServlet) {DispatcherServletRegistrationBean registration = new DispatcherServletRegistrationBean(dispatcherServlet, "/bbb/*");registration.setName("dispatcherServlet3");registration.setLoadOnStartup(this.webMvcProperties.getServlet().getLoadOnStartup());if (this.multipartConfig != null) {registration.setMultipartConfig(this.multipartConfig);}return registration;
}

这里是做了三个Bean,注意有一个一定要加上@Primary注解,否则启动会有报错。

如果我们系统有一个接口url是/api/test,那么通过/aaa/api/test或者/bbb/api/test也都可以访问了。

1.2控制器

控制器Controller在springboot的注解扫描范围内自动管理。底层逻辑为java反射。

Spring Boot 的 @ComponentScan 默认会扫描启动类所在包及其子包。这是通过 @SpringBootApplication 中的 @ComponentScan 实现的。因此,启动类的位置对组件扫描范围至关重要。

image-20241229144045927

1.2.1找到启动类的位置

1.2.1.1SpringApplication.run()

Spring Boot 启动器的定位通过,SpringBoot的入口类SpringApplication.run() 方法触发。

image-20241229145006785

SpringApplication.run() 是启动流程的入口,其源码如下:

public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {return run(new Class[]{primarySource}, args);}

这里的 primarySource 就是启动类(启动器)。

  • primarySource 的来源: 通过调用 SpringApplication 的构造方法传入。
1.2.1.2SpringApplication 构造方法
public SpringApplication(Class<?>... primarySources) {this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));this.webApplicationType = deduceWebApplicationType();setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));this.mainApplicationClass = deduceMainApplicationClass();
}

this.primarySources:存储传入的启动类。

deduceMainApplicationClass():尝试自动推断启动类。

1.2.1.3deduceMainApplicationClass()
private Class<?> deduceMainApplicationClass() {try {StackTraceElement[] stackTrace = new RuntimeException().getStackTrace();for (StackTraceElement stackTraceElement : stackTrace) {if ("main".equals(stackTraceElement.getMethodName())) {return Class.forName(stackTraceElement.getClassName());}}} catch (ClassNotFoundException ex) {// 忽略异常}return null;
}
  • 通过分析当前线程的调用堆栈,找到调用 main 方法的类。
  • 找到第一个包含 main 方法的类并返回。

这就是为什么 Spring Boot 能自动定位启动类的位置。

1.2.2@ComponentScan 注解

@ComponentScan 是 Spring 框架用于自动扫描和注册组件的注解。@SpringBootApplication 中自带了 @ComponentScan,默认会扫描启动类所在的包及其子包。

通过excludeFilters来过滤掉,到底应该扫描哪些包

1.3视图解析器自动管理

Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.

ContentNegotiatingViewResolver:组合所有的视图解析器的;

曾经的配置文件无需再配

<bean id="de" class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/jsp/"></property><property name="suffix" value="*.jsp"></property>
</bean>

源码:

public ContentNegotiatingViewResolver viewResolver(BeanFactory beanFactory) {ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();resolver.setContentNegotiationManager((ContentNegotiationManager)beanFactory.getBean(ContentNegotiationManager.class));resolver.setOrder(-2147483648);return resolver;
}

用不同的模板引擎会有不同的自动配置

Thymeleaf 示例

image-20241229154806853

如果你的视图文件路径或者文件名不同,可以通过配置文件来修改。

spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html

当我们做文件上传的时候我们也会发现是multipartResolver自动被配置好的

<form action="/upload" method="post" enctype="multipart/form-data"><input name="pic" type="file"><input type="submit">
</form>
@ResponseBody
@RequestMapping("/upload")
public String upload(@RequestParam("pic")MultipartFile file, HttpServletRequest request){String contentType = file.getContentType();String fileName = file.getOriginalFilename();/*System.out.println("fileName-->" + fileName);System.out.println("getContentType-->" + contentType);*///String filePath = request.getSession().getServletContext().getRealPath("imgupload/");String filePath = "D:/imgup/";try {this.uploadFile(file.getBytes(), filePath, fileName);} catch (Exception e) {// TODO: handle exception}return "success";
}public static void uploadFile(byte[] file, String filePath, String fileName) throws Exception {File targetFile = new File(filePath);if(!targetFile.exists()){targetFile.mkdirs();}FileOutputStream out = new FileOutputStream(filePath+fileName);out.write(file);out.flush();out.close();
}

文件上传大小可以通过配置来修改

打开application.properties, 默认限制是10MB,我们可以任意修改

image-20241229155137711

1.4静态资源访问

Spring Boot 会默认将以下路径作为静态资源的目录:

  • src/main/resources/static
  • src/main/resources/public
  • src/main/resources/resources
  • src/main/resources/META-INF/resources

将静态文件放在这些目录中,可以通过 HTTP 直接访问它们。

1.5消息转换和格式化

Springboot自动配置了消息转换器

源码部分

@Overridepublic void configureMessageConverters(List<HttpMessageConverter<?>> converters) {this.messageConvertersProvider.ifAvailable((customConverters) -> converters.addAll(customConverters.getConverters()));}

image-20241229160047694

格式化转换器的自动注册

image-20241229160130155

我们可以在配置文件中修改时间类型

image-20241229160348199

image-20241229160803147

1.6欢迎页面的自动配置

Springboot自动指定resources下的index.html

image-20241229161109110

Spring Boot 会自动配置静态资源的路径,默认情况下,resources/staticresources/publicresources/resourcesresources/META-INF/resources 等目录下的资源会被自动映射到 HTTP 请求的根路径 /

2.SpringBoot扩展springmvc

在实际开发中,Spring Boot 确实提供了很多自动配置功能,帮助我们简化了很多配置和开发工作。但由于每个项目的业务需求不同,Spring Boot 并不能覆盖所有的场景,因此,开发者常常需要根据具体的业务需求对其进行扩展。

2.1WebMvcConfigurer 接口

public interface WebMvcConfigurer {default void configurePathMatch(PathMatchConfigurer configurer) {}default void configureContentNegotiation(ContentNegotiationConfigurer configurer) {}default void configureAsyncSupport(AsyncSupportConfigurer configurer) {}default void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {}default void addFormatters(FormatterRegistry registry) {}default void addInterceptors(InterceptorRegistry registry) {}default void addResourceHandlers(ResourceHandlerRegistry registry) {}default void addCorsMappings(CorsRegistry registry) {}default void addViewControllers(ViewControllerRegistry registry) {}default void configureViewResolvers(ViewResolverRegistry registry) {}default void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {}default void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) {}default void configureMessageConverters(List<HttpMessageConverter<?>> converters) {}default void extendMessageConverters(List<HttpMessageConverter<?>> converters) {}default void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {}default void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {}@Nullabledefault Validator getValidator() {return null;}@Nullabledefault MessageCodesResolver getMessageCodesResolver() {return null;}
}

2.2在容器中注册视图控制器(请求转发)

创建一个MyMVCCofnig实现WebMvcConfigurer接口,实现一下addViewControllers方法,我们完成通过/tx访问,转发到success.html的工作

@Configuration
public class MyMVCCofnig implements WebMvcConfigurer{@Overridepublic void addViewControllers(ViewControllerRegistry registry) {registry.addViewController("/tx").setViewName("success");}
}

image-20241229164535087

2.3注册格式化器

用来可以对请求过来的日期格式化的字符串来做定制化。当然通过application.properties配置也可以办到。

@Overridepublic void addFormatters(FormatterRegistry registry) {registry.addFormatter(new Formatter<Date>() {@Overridepublic String print(Date date, Locale locale) {// 将 Date 对象转换为字符串(格式化)// 使用 SimpleDateFormat 将 Date 转换为指定格式的字符串return new SimpleDateFormat("yyyy-MM-dd").format(date);}@Overridepublic Date parse(String s, Locale locale) throws ParseException {// 将字符串解析为 Date 对象// 假设日期格式是 "yyyy-MM-dd"return new SimpleDateFormat("yyyy-MM-dd").parse(s);}});}

2.4消息转换器扩展fastjson

在pom.xml中引入fastjson

<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.47</version>
</dependency>

配置消息转换器,添加fastjson

@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {FastJsonHttpMessageConverter fc = new FastJsonHttpMessageConverter();FastJsonConfig fastJsonConfig = new FastJsonConfig();fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);fc.setFastJsonConfig(fastJsonConfig);converters.add(fc);
}
public class User {private String username;private String password;private int age;private int score;private int gender;@JSONField(format = "yyyy-MM-dd")private Date date;

2.5拦截器注册

  1. 创建拦截器
public class MyInterceptor implements HandlerInterceptor{public boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler) throws Exception {System.out.println("前置拦截");return  true;}public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("后置拦截");}public void afterCompletion(HttpServletRequest request,HttpServletResponse response,Object handler,Exception ex) throws Exception {System.out.println("最终拦截");}
}

拦截器注册

//配置注册自己的拦截器@Overridepublic void addInterceptors(InterceptorRegistry registry){registry.addInterceptor(new MyInterceptor())//配置拦截所有路径.addPathPatterns("/**")//配置不拦截路径  可变参数 可以使多个参数  数组.excludePathPatterns("/test2");}
关键字:二建咨询在线_东莞网站建设怎么做_外贸网站大全_免费自助建站平台

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: