springboot学习之旅04-web开发02

一.代码示例:

1.1 扩展SpringMVC的映射、拦截器、国际化组件

(注意看注释里说明)

//使用WebMvcConfigurerAdapter可以来扩展SpringMVC的功能
//@EnableWebMvc   //不要接管SpringMVC
@Configuration
public class MyConfigAsLearn extends WebMvcConfigurerAdapter {


    //第一种方式:
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
         super.addViewControllers(registry);
        //浏览器发送 /atguigu 请求来到 success
        registry.addViewController("/atguigu").setViewName("success");
    }
	
	//第二种方式:
   // 所有的WebMvcConfigurerAdapter组件都会一起起作用
    @Bean //将组件注册在容器
    public WebMvcConfigurerAdapter webMvcConfigurerAdapter(){
        WebMvcConfigurerAdapter adapter = new WebMvcConfigurerAdapter() {
            @Override
            public void addViewControllers(ViewControllerRegistry registry) {
                registry.addViewController("/").setViewName("login");
                registry.addViewController("/login.html").setViewName("login");
                registry.addViewController("/main.html").setViewName("dashboard");
            }

           // 注册拦截器 对于index.html 和登录请求不会拦截
            @Override
            public void addInterceptors(InterceptorRegistry registry) {
                super.addInterceptors(registry);
               // 静态资源;  *.css , *.js
               // SpringBoot已经做好了静态资源映射
                registry.addInterceptor(new MyHandlerIntercept()).addPathPatterns("/**") //MyHandlerIntercept类是自己定义的拦截器组件规则
                        .excludePathPatterns("/index.html","/","/user/login");
            }
        };
        return adapter;
    }

	//国际化组件
    @Bean
    public LocaleResolver localeResolver(){
		//自己定义的MyLocaleResolver国际化组件
        return new MyLocaleResolver();
    }

}

1.2 拦截器组件

实现HandlerInterceptor类

public class MyHandlerIntercept implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Object username = request.getSession().getAttribute("username");
        if(username != null){
            return true;
        }else{
            request.setAttribute("msg","未登录请重新登录");
            request.getRequestDispatcher("/login.html").forward(request,response);
            return false;
        }
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {

    }
}

1.3 国际化组件

实现LocaleResolver类

public class MyLocaleResolver implements LocaleResolver{
    @Override
    public Locale resolveLocale(HttpServletRequest httpServletRequest) {
        String i = httpServletRequest.getParameter("i");
        Locale locale = Locale.getDefault();
        if(!StringUtils.isEmpty(i)){
            locale = new Locale(i.split("_")[0],i.split("_")[1]);
        }
        return locale;
    }

    @Override
    public void setLocale(HttpServletRequest httpServletRequest, @Nullable HttpServletResponse httpServletResponse, @Nullable Locale locale) {

    }
}


1.4 国际化资源文件编写

在这里插入图片描述
SpringBoot自动配置好了管理国际化资源文件的组件;

@ConfigurationProperties(prefix = "spring.messages")
public class MessageSourceAutoConfiguration {
    
    /**
	 * Comma-separated list of basenames (essentially a fully-qualified classpath
	 * location), each following the ResourceBundle convention with relaxed support for
	 * slash based locations. If it doesn't contain a package qualifier (such as
	 * "org.mypackage"), it will be resolved from the classpath root.
	 */
	private String basename = "messages";  
    //我们的配置文件可以直接放在类路径下叫messages.properties;
    
    @Bean
	public MessageSource messageSource() {
		ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
		if (StringUtils.hasText(this.basename)) {
            //设置国际化资源文件的基础名(去掉语言国家代码的)
			messageSource.setBasenames(StringUtils.commaDelimitedListToStringArray(
					StringUtils.trimAllWhitespace(this.basename)));
		}
		if (this.encoding != null) {
			messageSource.setDefaultEncoding(this.encoding.name());
		}
		messageSource.setFallbackToSystemLocale(this.fallbackToSystemLocale);
		messageSource.setCacheSeconds(this.cacheSeconds);
		messageSource.setAlwaysUseMessageFormat(this.alwaysUseMessageFormat);
		return messageSource;
	}

1.5 html页面获取国际化的值

<!DOCTYPE html>
<html lang="en"  xmlns:th="http://www.thymeleaf.org">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
	<meta name="description" content="">
	<meta name="author" content="">
	<title>Signin Template for Bootstrap</title>
	<!-- Bootstrap core CSS -->
	<link href="asserts/css/bootstrap.min.css" th:href="@{/webjars/bootstrap/4.4.1/css/bootstrap.css}" rel="stylesheet">
	<!-- Custom styles for this template -->
	<link href="asserts/css/signin.css" th:href="@{/asserts/css/signin.css}" rel="stylesheet">
</head>
<body class="text-center">
<form class="form-signin" action="dashboard.html" th:action="@{/user/login}" method="post">
	<img class="mb-4" th:src="@{/asserts/img/bootstrap-solid.svg}" src="asserts/img/bootstrap-solid.svg" alt="" width="72" height="72">
	<h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">Please sign in</h1>
	<!--判断-->
	<p style="color: red" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p>
	<label class="sr-only" th:text="#{login.username}">Username</label>
	<input type="text"  name="username" class="form-control" placeholder="Username" th:placeholder="#{login.username}" required="" autofocus="">
	<label class="sr-only" th:text="#{login.password}">Password</label>
	<input type="password" name="password" class="form-control" placeholder="Password" th:placeholder="#{login.password}" required="">
	<div class="checkbox mb-3">
		<label>
			<input type="checkbox" value="remember-me"/> [[#{login.remember}]]
		</label>
	</div>
	<button class="btn btn-lg btn-primary btn-block" type="submit" th:text="#{login.sign}">Sign in</button>
	<p class="mt-5 mb-3 text-muted">© 2017-2018</p>
	<a class="btn btn-sm" th:href="@{/login.html(i='zh_CN')}">中文</a>
	<a class="btn btn-sm" th:href="@{/login.html(i='en_US')}">English</a>
</form>
</body>

</html>

效果:根据浏览器语言设置的信息切换了国际化;这边可以设置浏览器的优先语言

在这里插入图片描述

1.5 登录拦截器

拦截器进行登陆检查==

@Controller
public class LoginController {

    @RequestMapping(value = "/user/login",method = RequestMethod.POST)
    @PostMapping("/user/login")
    public String login(@RequestParam("username") String username, @RequestParam("password") String password,
                        Map<Object,Object> map, HttpSession session){
        if(!StringUtils.isEmpty(username) && "123".equals(password)){
            session.setAttribute("username",username);
            return "dashboard";
        }else{
            map.put("msg","用户名密码错误");
            return "login";
        }

    }
}

小知识点:
开发期间模板引擎页面修改以后,要实时生效

1)、禁用模板引擎的缓存

# 禁用缓存
spring.thymeleaf.cache=false 

2)、页面修改完成以后ctrl+f9:重新编译;

登陆错误消息的显示

<p style="color: red" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p>

二、thymeleaf公共页面元素抽取

1、抽取公共片段
<div th:fragment="copy">
&copy; 2011 The Good Thymes Virtual Grocery
</div>

2、引入公共片段
<div th:insert="~{footer :: copy}"></div>
~{templatename::selector}:模板名::选择器
~{templatename::fragmentname}:模板名::片段名

3、默认效果:
insert的公共片段在div标签中
如果使用th:insert等属性进行引入,可以不用写~{}:
行内写法可以加上:[[~{}]];[(~{})];

三种引入公共片段的th属性:

th:insert:将公共片段整个插入到声明引入的元素中

th:replace:将声明引入的元素替换为公共片段

th:include:将被引入的片段的内容包含进这个标签中

三、配置嵌入式Servlet容器

SpringBoot默认使用Tomcat作为嵌入式的Servlet容器

3.1 如何定制和修改Servlet容器的相关配置;

1、修改和server有关的配置(ServerProperties【也是EmbeddedServletContainerCustomizer】);

server.port=8081
server.context-path=/crud

server.tomcat.uri-encoding=UTF-8

//通用的Servlet容器设置
server.xxx
//Tomcat的设置
server.tomcat.xxx

2、编写一个EmbeddedServletContainerCustomizer:嵌入式的Servlet容器的定制器;来修改Servlet容器的配置

@Bean  //一定要将这个定制器加入到容器中 这是1.5版本
public EmbeddedServletContainerCustomizer embeddedServletContainerCustomizer(){
    return new EmbeddedServletContainerCustomizer() {

        //定制嵌入式的Servlet容器相关的规则
        @Override
        public void customize(ConfigurableEmbeddedServletContainer container) {
            container.setPort(8083);
        }
    };
}

现在springboot2已经被WebServerFactoryCustomizer替换

 WebServerFactoryCustomizer<ConfigurableWebServerFactory> webServerFactoryCustomizer = new WebServerFactoryCustomizer<ConfigurableWebServerFactory>() {
            @Override
            public void customize(ConfigurableWebServerFactory factory) {
                factory.setPort(8083);
            }
        };

3.2 注册Servlet三大组件【Servlet、Filter、Listener】

由于SpringBoot默认是以jar包的方式启动嵌入式的Servlet容器来启动SpringBoot的web应用,没有web.xml文件。

注册三大组件用以下方式

1.ServletRegistrationBean

先写一个自定义servlet继承HTTPServlet
在这里插入图片描述

//注册三大组件
@Bean
public ServletRegistrationBean myServlet(){
    ServletRegistrationBean registrationBean = new ServletRegistrationBean(new MyServlet(),"/myServlet");
    return registrationBean;
}



2.FilterRegistrationBean
同理,先写一个自定义filter
在这里插入图片描述

@Bean
public FilterRegistrationBean myFilter(){
    FilterRegistrationBean registrationBean = new FilterRegistrationBean();
    registrationBean.setFilter(new MyFilter());
    registrationBean.setUrlPatterns(Arrays.asList("/hello","/myServlet"));
    return registrationBean;
}

3.ServletListenerRegistrationBean
同理,先写一个自定义监听器
在这里插入图片描述

@Bean
public ServletListenerRegistrationBean myListener(){
    ServletListenerRegistrationBean<MyListener> registrationBean = new ServletListenerRegistrationBean<>(new MyListener());
    return registrationBean;
}

3.3 替换为其他嵌入式Servlet容器

springboot2中 ConfigurableWebServerFactory 有很多子类

WebServerFactoryCustomizer<ConfigurableWebServerFactory> webServerFactoryCustomizer = new WebServerFactoryCustomizer<ConfigurableWebServerFactory>() {
            @Override
            public void customize(ConfigurableWebServerFactory factory) {
                factory.setPort(8083);
            }
        };

在这里插入图片描述

默认支持:

Tomcat(默认使用)

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
   引入web模块默认就是使用嵌入式的Tomcat作为Servlet容器;
</dependency>

如需使用其他容器,则使用如下配置即可

Jetty

<!-- 引入web模块 -->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
   <exclusions>
      <exclusion>
         <artifactId>spring-boot-starter-tomcat</artifactId>
         <groupId>org.springframework.boot</groupId>
      </exclusion>
   </exclusions>
</dependency>

<!--引入其他的Servlet容器-->
<dependency>
   <artifactId>spring-boot-starter-jetty</artifactId>
   <groupId>org.springframework.boot</groupId>
</dependency>

Undertow

<!-- 引入web模块 -->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
   <exclusions>
      <exclusion>
         <artifactId>spring-boot-starter-tomcat</artifactId>
         <groupId>org.springframework.boot</groupId>
      </exclusion>
   </exclusions>
</dependency>

<!--引入其他的Servlet容器-->
<dependency>
   <artifactId>spring-boot-starter-undertow</artifactId>
   <groupId>org.springframework.boot</groupId>
</dependency>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值