SpringBoot 入门学习笔记(三)Web 开发下篇

1 Springboot 整合 springmvc

参考官方文档: https://docs.spring.io/spring-boot/docs/2.0.2.RELEASE/reference/htmlsingle/#boot-features-spring-mvc

学习 springmvc 和 springboot 的自动配置必须熟知 springmvc 常用组件。Springmvc 核心组件均由 SpringBoot 完成自动配置。

1 Springmvc 的自动解管理

包含中央转发器、控制器、视图解析器、静态资源访问、消息转换器、格式化、静态资源管理

1 中央转发器

传统 web.xml 配置方式

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 自动接管中央转发器,项目无需 web.xml 文件 自动配置类:org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration

2 控制器

处于注解扫描范围内的 Controller,会被容器自动管理

3 视图解析器自动管理

自动注入 ContentNegotiatingViewResolver 组合视图解析器,替代传统手动配置 旧版视图解析器配置

XML 复制代码
<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>

视图解析器源码

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

文件上传解析器同样自动配置,直接使用即可 页面表单

html 复制代码
<form action="/upload" method="post" enctype="multipart/form-data">
    <input name="pic" type="file">
    <input type="submit">
</form>

文件上传控制器代码

java 复制代码
@ResponseBody
@RequestMapping("/upload")
public String upload(@RequestParam("pic")MultipartFile file, HttpServletRequest request){
    String contentType = file.getContentType();
    String fileName = file.getOriginalFilename();
    String filePath = "D:/imgup/";
    try {
        this.uploadFile(file.getBytes(), filePath, fileName);
    } catch (Exception e) {

    }
    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();
}

可在配置文件修改文件上传大小限制,默认上限 10MB

4 静态资源访问

规则同前文静态资源映射内容

5 消息转换和格式化

框架自动配置消息转换器,同时自动注册格式化转换器 可在配置文件自定义时间格式化格式

6 欢迎页面的自动配置

默认识别 resources 目录下 index.html 作为项目欢迎页

2 Springboot 扩展 springmvc

业务个性化需求可通过实现 WebMvcConfigurer 接口完成扩展,保留原有自动配置

java 复制代码
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) {
    }

    @Nullable
    default Validator getValidator() {
        return null;
    }

    @Nullable
    default MessageCodesResolver getMessageCodesResolver() {
        return null;
    }
}
1 注册视图控制器

无需编写业务方法,直接实现请求跳转

java 复制代码
@Configuration
public class MyMVCCofnig implements WebMvcConfigurer{
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/tx").setViewName("success");
    }
}
2 注册格式化器

自定义日期格式解析规则

java 复制代码
@Override
public void addFormatters(FormatterRegistry registry) {
    registry.addFormatter(new Formatter<Date>() {
        @Override
        public String print(Date date, Locale locale) {
            return null;
        }
        @Override
        public Date parse(String s, Locale locale) throws ParseException {
            return new SimpleDateFormat("yyyy-MM-dd").parse(s);
        }
    });
}
3 消息转换器扩展 fastjson

引入依赖

XML 复制代码
<dependency>
   <groupId>com.alibaba</groupId>
   <artifactId>fastjson</artifactId>
   <version>1.2.47</version>
</dependency>

配置替换消息转换器

java 复制代码
@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);
}

实体类格式化注解

java 复制代码
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;
}
4 拦截器注册

自定义拦截器类

java 复制代码
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("最终拦截");
    }
}

注册拦截器,设置拦截与放行路径

java 复制代码
@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new MyInterceptor())
            .addPathPatterns("/**")
            .excludePathPatterns("/hello2");
}

5 配置嵌入式服务器

1 定制 Servlet 容器配置

通过 server 开头配置项修改参数

复制代码
server.port=8081
server.context-path=/tx
server.tomcat.uri-encoding=UTF-8

2 注册 Servlet 三大组件

无 web.xml 环境下,通过 Bean 方式注册 Servlet、Filter、Listener

  1. 注册 Servlet
java 复制代码
@Bean
public ServletRegistrationBean myServlet(){
ServletRegistrationBean registrationBean = new ServletRegistrationBean(new
MyServlet(),"/myServlet");
return registrationBean;
}
  1. 注册 Filter
java 复制代码
@Bean
public FilterRegistrationBean myFilter(){
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(new MyFilter());
registrationBean.setUrlPatterns(Arrays.asList("/hello","/myServlet"));
return registrationBean;
}
  1. 注册 Listener
java 复制代码
@Bean
public ServletListenerRegistrationBean myListener(){
ServletListenerRegistrationBean<MyListener> registrationBean = new
ServletListenerRegistrationBean<>(new MyListener());
return registrationBean;
}

框架自动注册 DispatcherServlet 前端控制器

java 复制代码
@Bean(name = DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME)
@ConditionalOnBean(value = DispatcherServlet.class, name =
DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
public ServletRegistrationBean dispatcherServletRegistration(
DispatcherServlet dispatcherServlet) {
ServletRegistrationBean registration = new ServletRegistrationBean(
dispatcherServlet, this.serverProperties.getServletMapping());
registration.setName(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME);
registration.setLoadOnStartup(
this.webMvcProperties.getServlet().getLoadOnStartup());
if (this.multipartConfig != null) {
registration.setMultipartConfig(this.multipartConfig);
}
return registration;
}

6 使用外置的 Servlet 容器

容器对比

嵌入式容器:打包为可执行 jar,部署便捷,不支持 JSP 外置 Tomcat:打包 war 部署,兼容 JSP,自定义程度更高

部署步骤

  1. 创建 war 类型项目
  2. 修改内嵌 tomcat 依赖作用域
XML 复制代码
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
  1. 编写初始化子类,关联主启动类
java 复制代码
public class ServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(SpringBoot04WebJspApplication.class);
}
}
  1. 打包后部署至外置 Tomcat 服务器运行

启动原理

Jar 包:执行主类 main 方法,启动内嵌容器与 IOC 容器 War 包:外部 Tomcat 启动,调用初始化类加载 SpringBoot 项目,初始化 IOC 容器

小结

本篇完成 SpringMVC 整合学习,掌握组件自动配置、自定义扩展方式,同时讲解嵌入式与外置 Servlet 容器的配置、组件注册及项目部署方式,完成 SpringBoot Web 开发全部基础内容。

相关推荐
承渊政道13 小时前
Linux系统学习【进程概念从入门到深入理解】
linux·服务器·笔记·学习·ubuntu·系统架构·bash
魔法阵维护师13 小时前
从零开发游戏需要学习的c#模块,第二十二章(音效与背景音乐)
学习·游戏·c#
西凉的悲伤13 小时前
SpringBoot RestTemplate 介绍
java·spring boot·后端·resttemplate
Roselind_Yi14 小时前
池化对比:CNN池化 VS Java线程池
java·人工智能·经验分享·笔记·深度学习·神经网络·cnn
心中有国也有家14 小时前
hixl:昇腾分布式推理的「快递专线」
人工智能·经验分享·笔记·分布式·学习·算法
爱睡懒觉的焦糖玛奇朵21 小时前
【从视频到数据集:焦糖玛奇朵的魔法工具使用说明】
人工智能·python·深度学习·学习·算法·yolo·音视频
IT_Octopus21 小时前
Spring Boot 实战:@PostConstruct + Caffeine 缓存初始化与定时刷新
spring boot·后端·缓存
夏天想1 天前
人类将从“执行者“变为“总导演”,学习Ai知识
人工智能·学习
玄米乌龙茶1231 天前
LLM成长笔记(二):数据处理与工具链
笔记