编写servlet类
//web3.0后提供的注解的方式编写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);
}
}
注册servlet
package com.mashibing;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@SpringBootApplication
//启动器启动时,扫描本目录以及子目录带有@WebServlet注解的类自动注册
@ServletComponentScan
public class SpringbootApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootApplication.class, args);
}
}
编写servlet类
package com.mashibing.controller;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
//此处不需要使用@WebServlet注解
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("111");
super.doGet(req, resp);
}
}
注册servlet
package com.mashibing;
import com.mashibing.controller.MyServlet;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class SpringbootApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootApplication.class, args);
}
//需要自己创建一个ServletRegistrationBean对象,并交给spring管理,这样就完成了servlet的注册
@Bean
public ServletRegistrationBean<MyServlet> getServletRegistrationBean() {
//"/root","/home"可以为这个servlet指定多个访问url,即通过/root、/home都可以访问这个servlet
ServletRegistrationBean<MyServlet> bean = new ServletRegistrationBean<>(new MyServlet(), "/root", "/home");
bean.setLoadOnStartup(1);
return bean;
}
}
编写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");
}
}
注册filter
@ServletComponentScan
public class SpringbootApplication
...
编写filter
//不需要任何注释
public class MyFilter implements Filter
...
注册filter
@Bean
public FilterRegistrationBean<MyFilter> getFilterRegistrationBean() {
FilterRegistrationBean<MyFilter> bean = new FilterRegistrationBean<>(new MyFilter());
bean.addUrlPatterns("/filter");
return bean;
}
编写监听器类
package com.mashibing.controller;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
@WebListener
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");
}
}
注册监听器
@ServletComponentScan
public class SpringbootApplication
...
控制层测试代码
package com.mashibing.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
//使用两个浏览器分别输入:http://localhost:8080/login
//然后输入:http://localhost:8080/online,发现打印在线人数有2人
@RestController
public class ThymeleafController {
@RequestMapping("/login")
public String login(HttpServletRequest request) {
HttpSession session = request.getSession(true);
return "login";
}
@RequestMapping("online")
public String online() {
return "当前在线人数:" + MyHttpSessionListener.online + "人";
}
}
编写监听器类
//不需要任何注释
public class MyHttpSessionListener implements HttpSessionListener
...
注册监听器
@Bean
public ServletListenerRegistrationBean listenerRegist() {
ServletListenerRegistrationBean srb = new ServletListenerRegistrationBean();
srb.setListener(new MyHttpSessionListener());
System.out.println("listener");
return srb;
}
配置类
package com.test.spring.support.configuration;
//相当于定一个了一个xml配置文件,其内有一个bean,id为testBean。且@Configuration注释被@Component所注释,所以还会产生一个id为testConfiguration的bean对象由spring管理
@Configuration
public class TestConfiguration {
public TestConfiguration(){
System.out.println("spring容器启动初始化。。。");
}
//@Bean注解注册bean,同时可以指定初始化和销毁方法
//@Bean(name="testNean",initMethod="start",destroyMethod="cleanUp")
@Bean
@Scope("prototype")
public TestBean testBean() {
return new TestBean();
}
}
可以通过如下方式启动spring容器
package com.test.spring.support.configuration;
public class TestMain {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(TestConfiguration.class);
//获取bean
TestBean tb = context.getBean("testBean");
tb.sayHello();
// 如果加载spring-context.xml文件
// ApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");
}
}
springboot默认使用WebMvcAutoConfiguration中的WebMvcAutoConfigurationAdapter内部类的addResourceHandlers方法来提供静态资源的映射方式。内部类WebMvcAutoConfigurationAdapter实现了WebMvcConfigurer接口,addResourceHandlers方法就来自该接口
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/**")) {
//此处代码表示,一旦发现格式为"/webjars/**"的请求,就映射到"classpath:/META-INF/resources/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)) {
//1. staticPathPattern为/**
//2. getResourceLocations(this.resourceProperties.getStaticLocations())为"classpath:/META-INF/resources/","classpath:/resources/", "classpath:/static/", "classpath:/public/"
//3. 这表示,一旦发现格式为"/**"的请求,就依次到上面的几个路径中查找是否有匹配的静态资源
customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern)
.addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations()))
.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
}
访问webjars
webjars是将客户端(浏览器)资源(JavaScript,Css等)打成jar包文件,以对资源进行统一依赖管理。webjars的jar包在Maven中央仓库中
引入jquery的webjars
<dependency>
<groupId>org.webjarsgroupId>
<artifactId>jqueryartifactId>
<version>3.4.1version>
dependency>
引入的jar包中,包含路径META-INF/resources/webjars/jquery/3.4.1,里面有jquery.js文件
此时我们可以直接通过http://localhost:8080/webjars/jquery/3.4.1/jquery.js访问该js文件
访问自定义的静态资源
自定义静态资源映射
@Configuration
//1. 这个注解会覆盖掉SpringBoot的默认的静态资源映射配置
//@EnableWebMvc
//2. WebMvcConfigurerAdapter实际上已经过期,可以直接实现WebMvcConfigurer接口来自定义映射关系
class WebMvcConfig extends WebMvcConfigurerAdapter {
@Override
void addResourceHandlers(ResourceHandlerRegistry registry) {
//表示无论url中以什么方式访问"swagger-ui.html",都直接去"classpath:/META-INF/resources/"下查找对应文件
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/")
}
}
springboot默认使用WebMvcAutoConfiguration中的EnableWebMvcConfiguration内部类的welcomePageHandlerMapping方法来提供首页路径和文件名
welcomePageHandlerMapping方法分析
@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));
welcomePageHandlerMapping.setCorsConfigurations(getCorsConfigurations());
return welcomePageHandlerMapping;
}
private Optional<Resource> getWelcomePage() {
//1. this.resourceProperties.getStaticLocations()对应路径为"classpath:/META-INF/resources/","classpath:/resources/", "classpath:/static/", "classpath:/public/"
String[] locations = getResourceLocations(this.resourceProperties.getStaticLocations());
//2. getIndexHtml方法会找到上面所有路径中的index.html文件
//3. 因此首页为上述路径下的index.html文件
return Arrays.stream(locations).map(this::getIndexHtml).filter(this::isReadable).findFirst();
}
private Resource getIndexHtml(String location) {
return this.resourceLoader.getResource(location + "index.html");
}
访问首页
springboot提供了适用于大多数springmvc应用的自动配置
springboot默认使用的视图解析器,是WebMvcAutoConfiguration中的viewResolver方法所返回的ContentNegotiatingViewResolver类型的视图解析器。该方法上有@Bean,因此会作为bean交给spring管理,这样spring就会使用该视图解析器来解析视图
由于springboot使用的视图解析器是从bean中获取的,因此可以使用如下方式新增自定义视图解析器
//将返回的视图解析器对象放入bean中,交给spring管理
@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;
}
}
如果想保留springboot mvc的功能的前提下,增加其他mvc相关配置(资源映射、拦截器、格式化器、视图控制器等),可以添加自己的WebMvcConfigurer类型的@Configuration类,注意自定义的类上不要带@EnableWebMvc注解,这样会令springboot mvc默认的mvc功能失效。上面自定义静态资源映射就是使用这种方式实现的
如果想自定义RequestMappingHandlerMapping、RequestMappingHandlerAdapter、ExceptionHandlerExceptionResolver 实例,可以声明一个WebMvcRegistrationsAdapter实例来提供这些组件
自定义视图控制器:视图控制器不是视图解析器,视图控制器用于实现页面跳转
需要在resources/templates下建立success.html
由于要访问templates文件夹下内容,因此必须导入模版引擎的依赖包
<dependency>
<groupId>org.thymeleafgroupId>
<artifactId>thymeleaf-spring5artifactId>
dependency>
<dependency>
<groupId>org.thymeleaf.extrasgroupId>
<artifactId>thymeleaf-extras-java8timeartifactId>
dependency>
通过实现WebMvcConfigurer,并重写addViewControllers来提供视图控制器
package com.mashibing.controller;
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 {
//过去要访问一个页面需要先创建个Controller控制类,再写方法跳转到页面,在这里配置后就不需要那么麻烦了,直接访问http://localhost:8080/msb就跳转到success.html页面了
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/msb").setViewName("success");
}
}