​ springboot在开发web项目的时候具备天然的优势,现在的很多企业级开发都是依托于springboot的。

​ 使用springboot的步骤:

​ 1、创建一个SpringBoot应用,选择我们需要的模块,SpringBoot就会默认将我们的需要的模块自动配置好

​ 2、手动在配置文件中配置部分配置项目就可以运行起来了

​ 3、专注编写业务代码,不需要考虑以前那样一大堆的配置了。

1、springboot整合servlet

​ 很多同学在刚接触web开发的时候第一个接触的都是servlet,下面我们来使用springboot整合servlet

​ (1)编写servlet类

@WebServlet(name = "myServlet",urlPatterns = "/srv")
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("111");
super.doGet(req, resp);
}
}

​ (2)在启动类上添加如下配置

@SpringBootApplication
@ServletComponentScan
public class ConfigApplication { public static void main(String[] args) {
SpringApplication.run(ConfigApplication.class, args);
}
/* 或者启动如下方式,servlet上不需要添加注解
@Bean
public ServletRegistrationBean<MyServlet> getServletRegistrationBean(){
ServletRegistrationBean<MyServlet> bean = new ServletRegistrationBean<>(new MyServlet());
ArrayList<String> url = new ArrayList<>();
url.add("/srv");
bean.setUrlMappings(url);
bean.setLoadOnStartup(1);
return bean;
}
*/
}

​ (3)编写filter类

@WebFilter(filterName = "MyFilter", urlPatterns = "/filter")
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("init");
} @Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("filter");
chain.doFilter(request,response);
} @Override
public void destroy() {
System.out.println("destory");
}
}

​ (4)编写监听器

​ listener是servlet规范定义的一种特殊类,用于监听servletContext,HttpSession和ServletRequest等域对象的创建和销毁事件。监听域对象的属性发生修改的事件,用于在事件发生前、发生后做一些必要的处理。可用于以下方面:1、统计在线人数和在线用户2、系统启动时加载初始化信息3、统计网站访问量4、记录用户访问路径。

编写监听器类



import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener; public class MyHttpSessionListener implements HttpSessionListener { public static int online=0; @Override
public void sessionCreated(HttpSessionEvent se) {
System.out.println("创建session");
online++;
} @Override
public void sessionDestroyed(HttpSessionEvent se) {
System.out.println("销毁session");
}
}

添加到配置类



import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Bean
public ServletListenerRegistrationBean listenerRegist(){
ServletListenerRegistrationBean srb = new ServletListenerRegistrationBean();
srb.setListener(new MyHttpSessionListener());
System.out.println("listener");
return srb;
}
}

添加控制层代码



import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession; @Controller
public class ThymeleafController {
@RequestMapping("/login")
public String login(HttpServletRequest request){
HttpSession session = request.getSession(true);
return "login";
} @RequestMapping("online")
@ResponseBody
public String online(){
return "当前在线人数:"+MyHttpSessionListener.online +"人";
}
}

先发送login请求,然后再发送online的请求

2、静态资源的配置

​ 默认情况下,Spring Boot 将在 classpath 或者 ServletContext 根目录下从名为 /static (/public、/resources 或 /META-INF/resources)目录中服务静态内容。它使用了 Spring MVC 的 ResourceHttpRequestHandler,因此您可以通过添加自己的 WebMvcConfigurerAdapter 并重写 addResourceHandlers 方法来修改此行为。

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
return;
}
Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
if (!registry.hasMappingForPattern("/webjars/**")) {
customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/")
.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
if (!registry.hasMappingForPattern(staticPathPattern)) {
customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern)
.addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations()))
.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
}

(1)加载webjars文件

​ 在pom文件中添加jquery的相关依赖,直接可以通过浏览器访问到http://localhost:8080/webjars/jquery/3.4.1/jquery.js

<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.4.1</version>
</dependency>

(2)加载静态资源

​ 当查找静态资源的时候能够发现静态资源的路径是/**,会去ResourceProperties这个类,可以看到对应的资源目录。

@ConfigurationProperties(prefix = "spring.resources", ignoreUnknownFields = false)
public class ResourceProperties { private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/",
"classpath:/resources/", "classpath:/static/", "classpath:/public/" }; /**
* Locations of static resources. Defaults to classpath:[/META-INF/resources/,
* /resources/, /static/, /public/].
*/
private String[] staticLocations = CLASSPATH_RESOURCE_LOCATIONS;
private String[] appendSlashIfNecessary(String[] staticLocations) {
String[] normalized = new String[staticLocations.length];
for (int i = 0; i < staticLocations.length; i++) {
String location = staticLocations[i];
normalized[i] = location.endsWith("/") ? location : location + "/";
}
return normalized;
}

​ 可以看到静态资源的目录一共有如下几个:

​ "classpath:/resources/"

​ "classpath:/static/"

​ "classpath:/public/"

(3)首页的配置信息

@Bean
public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext,
FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(
new TemplateAvailabilityProviders(applicationContext), applicationContext, getWelcomePage(),
this.mvcProperties.getStaticPathPattern());
welcomePageHandlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));
return welcomePageHandlerMapping;
} private Optional<Resource> getWelcomePage() {
String[] locations = getResourceLocations(this.resourceProperties.getStaticLocations());
return Arrays.stream(locations).map(this::getIndexHtml).filter(this::isReadable).findFirst();
}
private Resource getIndexHtml(String location) {
return this.resourceLoader.getResource(location + "index.html");
}

3、springmvc的扩展

​ springmvc框架是一个mvc的web框架,springmvc允许创建@controller和@RestController bean来处理传入的HTTP请求,控制器种的方法通过@RequestMapping注解映射到HTTP。

​ Springboot提供了适用于大多数Springmvc应用的自动配置。

引入 ContentNegotiatingViewResolver 和 BeanNameViewResolver bean视图解析器。
支持服务静态资源,包括对 WebJar 的支持。
自动注册 Converter(网页传入的数据封装成对象,完成数据类型的转化)、GenericConverter 和 Formatter bean(将日期转换成规定的格式)。
支持 HttpMessageConverter,用来转换http请求和响应。
自动注册 MessageCodesResolver,定义错误代码生成规则。
支持静态 index.html。
支持自定义 Favicon。
自动使用 ConfigurableWebBindingInitializer bean,将请求树绑定到javaBean中。

自动配置了ViewResolver,就是我们之前学习的SpringMVC的视图解析器:即根据方法的返回值取得视图对象(View),然后由视图对象决定如何渲染(转发,重定向)。

//WebMvcAutoConfiguration
@Bean //我们在这里确实看到已经给容器中注册了一个bean
@ConditionalOnBean({ViewResolver.class})
@ConditionalOnMissingBean(
name = {"viewResolver"},
value = {ContentNegotiatingViewResolver.class}
)
public ContentNegotiatingViewResolver viewResolver(BeanFactory beanFactory) {
ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
resolver.setContentNegotiationManager((ContentNegotiationManager)beanFactory.getBean(ContentNegotiationManager.class));
resolver.setOrder(-2147483648);
return resolver;
} //ContentNegotiatingViewResolver
@Nullable
public View resolveViewName(String viewName, Locale locale) throws Exception {
RequestAttributes attrs = RequestContextHolder.getRequestAttributes();
Assert.state(attrs instanceof ServletRequestAttributes, "No current ServletRequestAttributes");
List<MediaType> requestedMediaTypes = this.getMediaTypes(((ServletRequestAttributes)attrs).getRequest());
if (requestedMediaTypes != null) {
//获取候选的视图对象
List<View> candidateViews = this.getCandidateViews(viewName, locale, requestedMediaTypes);
//选择一个最适合的视图对象,然后把这个对象返回
View bestView = this.getBestView(candidateViews, requestedMediaTypes, attrs);
if (bestView != null) {
return bestView;
}
} String mediaTypeInfo = this.logger.isDebugEnabled() && requestedMediaTypes != null ? " given " + requestedMediaTypes.toString() : "";
if (this.useNotAcceptableStatusCode) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Using 406 NOT_ACCEPTABLE" + mediaTypeInfo);
} return NOT_ACCEPTABLE_VIEW;
} else {
this.logger.debug("View remains unresolved" + mediaTypeInfo);
return null;
}
} //getCandidateViews
private List<View> getCandidateViews(String viewName, Locale locale, List<MediaType> requestedMediaTypes)
throws Exception { List<View> candidateViews = new ArrayList<>();
if (this.viewResolvers != null) {
Assert.state(this.contentNegotiationManager != null, "No ContentNegotiationManager set");
for (ViewResolver viewResolver : this.viewResolvers) {
View view = viewResolver.resolveViewName(viewName, locale);
if (view != null) {
candidateViews.add(view);
}
for (MediaType requestedMediaType : requestedMediaTypes) {
List<String> extensions = this.contentNegotiationManager.resolveFileExtensions(requestedMediaType);
for (String extension : extensions) {
String viewNameWithExtension = viewName + '.' + extension;
view = viewResolver.resolveViewName(viewNameWithExtension, locale);
if (view != null) {
candidateViews.add(view);
}
}
}
}
}
if (!CollectionUtils.isEmpty(this.defaultViews)) {
candidateViews.addAll(this.defaultViews);
}
return candidateViews;
} //initServletContext
@Override
protected void initServletContext(ServletContext servletContext) {
Collection<ViewResolver> matchingBeans =
BeanFactoryUtils.beansOfTypeIncludingAncestors(obtainApplicationContext(), ViewResolver.class).values();
if (this.viewResolvers == null) {
this.viewResolvers = new ArrayList<>(matchingBeans.size());
for (ViewResolver viewResolver : matchingBeans) {
if (this != viewResolver) {
this.viewResolvers.add(viewResolver);
}
}
}
else {
for (int i = 0; i < this.viewResolvers.size(); i++) {
ViewResolver vr = this.viewResolvers.get(i);
if (matchingBeans.contains(vr)) {
continue;
}
String name = vr.getClass().getName() + i;
obtainApplicationContext().getAutowireCapableBeanFactory().initializeBean(vr, name);
} }
AnnotationAwareOrderComparator.sort(this.viewResolvers);
this.cnmFactoryBean.setServletContext(servletContext);
}

通过上面的代码分析,我们知道了springboot是在容器中去找视图解析器,因此,我们可以给容器自定义添加视图解析器,这个类会帮我们将他组合起来。

//自定义视图解析器
@Bean //放到bean中
public ViewResolver myViewResolver(){
return new MyViewResolver();
} //我们写一个静态内部类,视图解析器就需要实现ViewResolver接口
private static class MyViewResolver implements ViewResolver{
@Override
public View resolveViewName(String s, Locale locale) throws Exception {
return null;
}
}

扩展使用springmvc

/*如果您想保留 Spring Boot MVC 的功能,并且需要添加其他 MVC 配置(interceptor、formatter 和视图控制器等),可以添加自己的 WebMvcConfigurerAdapter 类型的 @Configuration 类,但不能带 @EnableWebMvc 注解。如果您想自定义 RequestMappingHandlerMapping、RequestMappingHandlerAdapter 或者 ExceptionHandlerExceptionResolver 实例,可以声明一个 WebMvcRegistrationsAdapter 实例来提供这些组件。
如果您想完全掌控 Spring MVC,可以添加自定义注解了 @EnableWebMvc 的 @Configuration 配置类
*/ import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/msb").setViewName("success");
}
}

注意:需要添加模板引擎

<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-java8time</artifactId>
</dependency>

【Spring Boot】web开发的更多相关文章

  1. Springboot 系列(六)Spring Boot web 开发之拦截器和三大组件

    1. 拦截器 Springboot 中的 Interceptor 拦截器也就是 mvc 中的拦截器,只是省去了 xml 配置部分.并没有本质的不同,都是通过实现 HandlerInterceptor ...

  2. Springboot 系列(七)Spring Boot web 开发之异常错误处理机制剖析

    前言 相信大家在刚开始体验 Springboot 的时候一定会经常碰到这个页面,也就是访问一个不存在的页面的默认返回页面. 如果是其他客户端请求,如接口测试工具,会默认返回JSON数据. { &quo ...

  3. Springboot 系列(五)Spring Boot web 开发之静态资源和模版引擎

    前言 Spring Boot 天生的适合 web 应用开发,它可以快速的嵌入 Tomcat, Jetty 或 Netty 用于包含一个 HTTP 服务器.且开发十分简单,只需要引入 web 开发所需的 ...

  4. Spring Boot Web 开发注解篇

    本文提纲 1. spring-boot-starter-web 依赖概述 1.1 spring-boot-starter-web 职责 1.2 spring-boot-starter-web 依赖关系 ...

  5. 四、Spring Boot Web开发

    四.Web开发 1.简介 使用SpringBoot: 1).创建SpringBoot应用,选中我们需要的模块: 2).SpringBoot已经默认将这些场景配置好了,只需要在配置文件中指定少量配置就可 ...

  6. spring boot系列(二)spring boot web开发

    json 接口开发 在以前的spring 开发的时候需要我们提供json接口的时候需要做如下配置: 1 添加jackjson等jar包 2 配置spring controller扫描 3 对接的方法添 ...

  7. Spring Boot Web 开发@Controller @RestController 使用教程

    在 Spring Boot 中,@Controller 注解是专门用于处理 Http 请求处理的,是以 MVC 为核心的设计思想的控制层.@RestController 则是 @Controller ...

  8. 4.Spring Boot web开发

    1.创建一个web模块 (1).创建SpringBoot应用,选中我们需要的模块: (2).SpringBoot已经默认将这些场景配置好了,只需要在配置文件中指定少量配置就可以运行起来 (3).自己编 ...

  9. Spring Boot Web开发中Thymeleaf模板引擎的使用

    这里使用的是idea 1.新建Spring Boot项目 File-->New-->Project...,然后选择左边的Spring Initializr-->Next,可根据自己的 ...

  10. (5)Spring Boot web开发 --- Restful CRUD

    文章目录 `@RestController` vs `@Controller` 默认访问首页 设置项目名 国际化 登陆 & 拦截 Restful 风格 @RestController vs @ ...

随机推荐

  1. Jmeter之『多变量循环』

    假设存在两个参数a,b,需要在一个循环内,同时遍历a_1,a_2,a_3,b_1,b_2,b_3 添加一个循环控制器,循环次数为变量的大小 添加一个计数器,引用名称为index(用于拼接变量名称) 同 ...

  2. VS Code对Golang的基准测试研究

    初心 想要在VS Code比较方便的调试Go代码的性能,了解到基准测试对此很有帮助,但默认VS Code执行 Go 的基准测试默认的benchtime为1秒,但测试性能时需要设置为更多秒 办法 在VS ...

  3. farbic-sdk-java 学习部署

    准备工作 1.fabric基础网络环境 2.环境准备(jdk环境.maven环境) 3.启动fabric测试网络 4.在idea中测试java-sdk 1.fabric环境准备 1.fabric基础环 ...

  4. IDEA2020.2的破解

    第一种方式:http://code.39sd.cn/ 直接获取二维码: 第二种:下载破解工具(本方法只是提供个人学习使用) 1.下载2020.2的idea 链接:https://pan.baidu.c ...

  5. 三、Requests库的使用

    requests 的底层实现其实就是 urllib3 Requests 唯一的一个非转基因的 Python HTTP 库,人类可以安全享用. 学过关于urllib库的使用,你会发现它是很不方便的.而R ...

  6. CSP-S 2019 游记,以及AFO

    CSP-S:Day1 195 Day2 84 滚粗,AFO. Day0 和cyl神仙打了一会儿游戏,九点半教了cyl一下LCT,开始写板子题,写到十点半,睡觉. Day1 六点半起床.吃饭.赶赴考场, ...

  7. Java代码实现计算器加减乘除简易功能

    package test; import javax.swing.; import java.awt.; import java.awt.event.KeyAdapter; import java.a ...

  8. 【树形DP】ZJOI2008 骑士

    题目内容 洛谷链接 有\(n\)位骑士,每个人的战力可能不同,并且每一个人都有且仅有一个憎恨的人,互相憎恨的人不能在同一队中. 求组合为一个骑士队的最大战斗力. PS:可以去看看题目背景学学历史(雾) ...

  9. VS code开发工具的使用教程

    前言 工欲善其事必先利其器,提高程序员的开发效率必须要有一个好的开发工具,当前最好的前端开发工具主要有VS code.sublime Text.Atom.Webstorm.Notepad++. VS ...

  10. pmm-server 搭建

    1 搭建docker centos 下 参考文档搭建docker  https://www.cnblogs.com/brady-wang/p/11543237.html docker create \ ...