SpringBoot学习笔记-4:第四章 Spring Boot Web 开发(2)

简介: SpringBoot学习笔记-4:第四章 Spring Boot Web 开发

扩展与全面接管 SpringMVC

1、扩展配置

package com.example.demo.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class CustomVmcConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        // super.addViewControllers(registry);
        // 浏览器的请求 /demo 到视图 /hello
        registry.addViewController("demo").setViewName("hello");
    }
}

2、全面接管

增加 @EnableWebMvc 后,自动配置失效

package com.example.demo.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@EnableWebMvc
@Configuration
public class CustomVmcConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        // super.addViewControllers(registry);
        // 浏览器的请求 /demo 到视图 /hello
        registry.addViewController("demo").setViewName("hello");
    }
}

引入资源

模板资源: https://getbootstrap.net/

模板语法: https://www.thymeleaf.org/

webjars: https://www.webjars.org/

目录设置

resources/

   templates   模板文件

   static      静态文件

首页设置

package com.example.demo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class CustomVmcConfig extends WebMvcConfigurerAdapter {
    // 设置首页位置,默认访问 public/index.html 没有经过模板引擎处理
    @Bean
    public WebMvcConfigurerAdapter CustomVmcConfig() {
        WebMvcConfigurerAdapter adapter = new WebMvcConfigurerAdapter() {
            @Override
            public void addViewControllers(ViewControllerRegistry registry) {
                registry.addViewController("/").setViewName("login");
                registry.addViewController("/index.html").setViewName("login");
            }
        };
        return adapter;
    }
}

国际化

默认根据浏览器语言获取对应国际化信息

1、配置语言文件

resources 资源文件夹下

├── i18n
│   ├── login.properties
│   ├── login_en_US.properties
│   └── login_zh_CN.properties

默认配置 login.properties

login.button=登录~
login.title=登录~
login.username=用户名~
login.password=密码~
login.remember=记住我~

英文配置 login_en_US.properties


login.button=Sign In

login.title=Login

login.username=UserName

login.password=Password

login.remember=Remenber Me


中文配置 login_zh_CN.properties


login.button=登录

login.title=登录

login.username=用户名

login.password=密码

login.remember=记住我


2、配置 application.yml


spring:

 messages:

   basename: i18n.login


3、模板文件中使用


<button th:text="#{login.button}"></button>

1

根据浏览器请求头设置语言


GET http://localhost:8080/

Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7



4、自定义国际化处理器

package com.example.demo.component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.LocaleResolver;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;
/**
 * 区域信息解析器
 * 自定义国际化参数,支持链接上携带区域信息
 */
public class MyLocaleResolver implements LocaleResolver {
    @Override
    public Locale resolveLocale(HttpServletRequest request) {
        String lang = request.getParameter("lang");
        Locale locale = Locale.getDefault();
        if (!StringUtils.isEmpty(lang)) {
            String[] list = lang.split("_");
            if (list.length == 2) {
                locale = new Locale(list[0], list[1]);
            }
        }
        return locale;
    }
    @Override
    public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {
    }
}

启用自定义国际化处理器

package com.example.demo.config;
import com.example.demo.component.MyLocaleResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
/**
 * 配置首页视图
 */
@Configuration
public class CustomVmcConfig extends WebMvcConfigurerAdapter {
    @Bean
    public MyLocaleResolver localeResolver() {
        return new MyLocaleResolver();
    }
}

优先获取查询参数返回语言设置

http://localhost:8080/?lang=zh_CN
http://localhost:8080/?lang=en_US
• 1
• 2

登陆&拦截器

开发期间模板引擎修改要实时生效


禁用模板引擎缓存

重新编译

<!--登录错误消息提示-->

<p

 style="color: red;"

 th:text="${msg}"

 th:if="${not #strings.isEmpty(msg)}"

></p>


拦截器进行登录检查


登录

package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import javax.servlet.http.HttpSession;
import java.util.Map;
@Controller
public class LoginController {
    @PostMapping("/user/login")
    // 等价于 @RequestMapping(value = "/user/login", method = {RequestMethod.POST})
    public String login(@RequestParam("username") String username,
                        @RequestParam("password") String password,
                        Map<String, Object> map,
                        HttpSession session
    ) {
        if (!StringUtils.isEmpty(username) && "123".equals(password)) {
            session.setAttribute("loginUser", username);
            // 登录成功 防止表单重新提交,做一个重定向
            return "redirect:/dashboard.html";
        } else {
            // 登录失败
            map.put("msg", "账号或密码不正确");
            return "login";
        }
    }
}

拦截器

package com.example.demo.component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * 登录检查
 */
public class LoginHandlerInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Object loginUser = request.getSession().getAttribute("loginUser");
        // 未登录,返回登录页面
        if (loginUser == null) {
            request.setAttribute("msg", "没有权限,请先登录");
            request.getRequestDispatcher("/index.html").forward(request, response);
            return false;
        }
        // 已登录,放行
        else {
            return true;
        }
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    }
}

注册拦截器

package com.example.demo.config;
import com.example.demo.component.LoginHandlerInterceptor;
import com.example.demo.component.MyLocaleResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
/**
 * 配置首页视图
 */
@Configuration
@SuppressWarnings("all")
public class CustomVmcConfig extends WebMvcConfigurerAdapter {
    // 设置首页位置,默认访问 public/index.html 没有经过模板引擎处理
    @Bean
    public WebMvcConfigurerAdapter CustomVmcConfig() {
        WebMvcConfigurerAdapter adapter = new WebMvcConfigurerAdapter() {
            /**
             * 注册视图控制器
             * @param registry
             */
            @Override
            public void addViewControllers(ViewControllerRegistry registry) {
                registry.addViewController("/").setViewName("login");
                registry.addViewController("/index.html").setViewName("login");
                registry.addViewController("/dashboard.html").setViewName("dashboard");
            }
            /**
             * 注册拦截器
             * @param registry
             */
            @Override
            public void addInterceptors(InterceptorRegistry registry) {
                // super.addInterceptors(registry);
                // 拦截任意路径下的所有请求, 排除请求
                registry.addInterceptor(new LoginHandlerInterceptor())
                        .addPathPatterns("/**")
                        .excludePathPatterns("/index.html", "/", "/user/login", "/static/**");
            }
        };
        return adapter;
    }
}

Restful CRUD

Rest 风格

URI: /资源/资源标识 HTTP 请求方式区分对资源 CRUD

image.png

员工列表-公共页抽取

公共片段抽取

<!-- 1、抽取公共片段 -->
<div th:fragment="copy">content</div>
<!-- 2、引入公共片段 -->
<div th:insert="~{footer::copy}">content</div>
<!-- 3、默认效果 -->
<!-- insert功能片段在div标签中 -->
~{templateName::selector} 模板名::选择器
~{templateName::fragmentName}模板名::片段名


3 种方式引入片段


th:insert 插入

th:replace 替换

th:include 引入片段内容


使用th:insert可以不写~{}

转义[[~{}]]

不转义[(~{})]


引入片段时候传入参数


链接高亮&列表完成


redirect 重定向

forward 转发


日期格式化


spring.mvc.format.date: yyyy-MM-dd


相关文章
|
2月前
|
缓存 安全 Java
《深入理解Spring》过滤器(Filter)——Web请求的第一道防线
Servlet过滤器是Java Web核心组件,可在请求进入容器时进行预处理与响应后处理,适用于日志、认证、安全、跨域等全局性功能,具有比Spring拦截器更早的执行时机和更广的覆盖范围。
|
2月前
|
XML Java 应用服务中间件
【SpringBoot(一)】Spring的认知、容器功能讲解与自动装配原理的入门,带你熟悉Springboot中基本的注解使用
SpringBoot专栏开篇第一章,讲述认识SpringBoot、Bean容器功能的讲解、自动装配原理的入门,还有其他常用的Springboot注解!如果想要了解SpringBoot,那么就进来看看吧!
446 2
|
3月前
|
人工智能 Java 机器人
基于Spring AI Alibaba + Spring Boot + Ollama搭建本地AI对话机器人API
Spring AI Alibaba集成Ollama,基于Java构建本地大模型应用,支持流式对话、knife4j接口可视化,实现高隐私、免API密钥的离线AI服务。
2876 1
基于Spring AI Alibaba + Spring Boot + Ollama搭建本地AI对话机器人API
存储 JSON Java
540 0
|
3月前
|
存储 安全 Java
如何在 Spring Web 应用程序中使用 @SessionScope 和 @RequestScope
Spring框架中的`@SessionScope`和`@RequestScope`注解用于管理Web应用中的状态。`@SessionScope`绑定HTTP会话生命周期,适用于用户特定数据,如购物车;`@RequestScope`限定于单个请求,适合无状态、线程安全的操作,如日志记录。合理选择作用域能提升应用性能与可维护性。
179 1
|
4月前
|
存储 NoSQL Java
探索Spring Boot的函数式Web应用开发
通过这种方式,开发者能以声明式和函数式的编程习惯,构建高效、易测试、并发友好的Web应用,同时也能以较小的学习曲线迅速上手,因为这些概念与Spring Framework其他部分保持一致性。在设计和编码过程中,保持代码的简洁性和高内聚性,有助于维持项目的可管理性,也便于其他开发者阅读和理解。
160 0
|
4月前
|
监控 Java API
Spring Boot 3.2 结合 Spring Cloud 微服务架构实操指南 现代分布式应用系统构建实战教程
Spring Boot 3.2 + Spring Cloud 2023.0 微服务架构实践摘要 本文基于Spring Boot 3.2.5和Spring Cloud 2023.0.1最新稳定版本,演示现代微服务架构的构建过程。主要内容包括: 技术栈选择:采用Spring Cloud Netflix Eureka 4.1.0作为服务注册中心,Resilience4j 2.1.0替代Hystrix实现熔断机制,配合OpenFeign和Gateway等组件。 核心实操步骤: 搭建Eureka注册中心服务 构建商品
820 3
|
5月前
|
前端开发 Java API
Spring Cloud Gateway Server Web MVC报错“Unsupported transfer encoding: chunked”解决
本文解析了Spring Cloud Gateway中出现“Unsupported transfer encoding: chunked”错误的原因,指出该问题源于Feign依赖的HTTP客户端与服务端的`chunked`传输编码不兼容,并提供了具体的解决方案。通过规范Feign客户端接口的返回类型,可有效避免该异常,提升系统兼容性与稳定性。
377 0