SpringBoot-Web

作者: 小杨小杨神采飞杨 | 来源:发表于2020-05-01 19:51 被阅读0次
    1. 静态资源处理

    1、外部静态资源
    观察springboot中web项目的自动配置类可以发现,springboot中引入外部的静态资源,都是到这个路径下寻找

    addResourceHandlers
    springboot将项目会打成一个jar包,以前引入外部静态资源会将静态资源放在WEB-INF文件夹下,这种方式在打成一个jar包的情况下肯定是不生效的,springboot提供的方式就是,将我们需要引入的外部资源封装成特殊的jar包,在maven中引入后,会在如图所示的路径下创建资源,特殊的jar在这里获取,例如我们导入jquery的依赖
    jquery
    就可以发现项目路径下有了对应的资源,与自动配置类中寻找的路径一致
    webjars
    此时使用http://localhost:8080/webjars/jquery/3.5.0/jquery.js就可以访问
    访问结果
    总结:所有 /webjars/** ,都去 classpath:/META-INF/resources/webjars/ 找资源

    2、自定义的静态资源
    "/**" 访问当前项目的任何资源,都去(静态资源的文件夹)找映射

    "classpath:/META-INF/resources/", 
    "classpath:/resources/",
    "classpath:/static/", 
    "classpath:/public/" 
    "/":当前项目的根路径
    

    当前项目的任何静态资源,都放在这三个文件夹中

    目录结构

    3、首页
    将首页命名为index.html放在静态资源路径下即可
    欢迎页; 静态资源文件夹下的所有index.html页面;被"/**"映射

    4、图标
    将想要设置的图标命名为favicon.ico放在静态资源路径下即可
    所有的 **/favicon.ico 都是在静态资源文件下找

    1. 模板引擎


      模板引擎

      JSP就是一个模板引擎,拥有和html页面一样的html代码,但是有高级的功能获取数据,springboot默认推荐的thymeleaf更强大,语法更简单

    1、引入thymeleaf
    在pom文件中引入依赖即可

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-thymeleaf</artifactId>
            </dependency>
    

    2、调整版本
    springboot管理依赖的版本号,但是默认使用的thymeleaf版本为2.x,功能不够强大,需要将版本修改到最新的3.x
    在github搜索thymeleaf


    最新版本

    需要注意,与thymeleaf配套使用的layout在2.0版本之后才支持thymeleaf3,所以需要将版本更新到2.0之后


    提示
    在properties标签中修改即可,覆盖掉springboot默认的版本
    properties
    <thymeleaf.version>3.0.11.RELEASE</thymeleaf.version>
    <!-- 布局功能的支持程序  thymeleaf3主程序  layout2以上版本 -->
    <!-- thymeleaf2   layout1-->
    <thymeleaf-layout-dialect.version>2.4.1</thymeleaf-layout-dialect.version>
    

    以后要修改别的依赖的版本,触类旁通即可
    3、使用


    代码

    可见,无需配置,将html页面放在templates文件夹下就可以了


    编写controller,跳转到success页面
    测试结果
    4、语法
    首先导入thymeleaf的名称空间,导入后会有提示
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    

    然后使用语法!!
    1、功能标签

    功能标签
    注意:thymeleaf使用th:html属性进行属性设置,会覆盖原本标签的属性,但是并不用删除原本的属性,更便于前后端合作
    共享数据
    使用thymeleaf替换数据
    并没有删除原来的数据
    测试结果
    2、表达式语法
    Simple expressions:(表达式语法)
        Variable Expressions: ${...}:获取变量值;OGNL;
                1)、获取对象的属性、调用方法
                2)、使用内置的基本对象:${session.foo}
                3)、内置的一些工具对象:
    
        Selection Variable Expressions: *{...}:选择表达式:和${}在功能上是一样;
        
        Message Expressions: #{...}:获取国际化内容
    
        Link URL Expressions: @{...}:定义URL;
                @{/order/process(execId=${execId},execType='FAST')}
    
        Fragment Expressions: ~{...}:片段引用表达式
                <div th:insert="~{commons :: main}">...</div>
                
    Literals(字面量)
        Text literals: 'one text' , 'Another one!' ,…
        Number literals: 0 , 34 , 3.0 , 12.3 ,…
        Boolean literals: true , false
        Null literal: null
        Literal tokens: one , sometext , main ,…
    Text operations:(文本操作)
        String concatenation: +
        Literal substitutions: |The name is ${name}|
    Arithmetic operations:(数学运算)
        Binary operators: + , - , * , / , %
        Minus sign (unary operator): -
    Boolean operations:(布尔运算)
        Binary operators: and , or
        Boolean negation (unary operator): ! , not
    Comparisons and equality:(比较运算)
        Comparators: > , < , >= , <= ( gt , lt , ge , le )
        Equality operators: == , != ( eq , ne )
    Conditional operators:条件运算(三元运算符)
        If-then: (if) ? (then)
        If-then-else: (if) ? (then) : (else)
        Default: (value) ?: (defaultvalue)
    Special tokens:
        No-Operation: _ 
    

    简单使用:
    修改controller


    controller

    修改页面

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>success</title>
    </head>
    <body>
    <h1>success</h1>
    <div th:text="${msg}"></div> <!--取出msg中的数据,转义字符不生效-->
    <div th:utext="${msg}"></div> <!--取出msg中的数据,转义字符生效-->
    <hr/>
    <!--遍历users,将每一个元素命名为user传给test进行数据显示,each每次遍历会新建一个h1标签-->
    <h1 th:text="${user}" th:each="user:${users}"></h1>
    <h1>
        <!--行内表示法-->
        <span th:each="user:${users}">[[${user}]] </span>
    </h1>
    </body>
    </html>
    

    测试


    测试结果
    1. 扩展Spring-MVC
      soringboot自动配置了大部分springmvc的功能,但是我们依旧可以自定义一些功能,只要创建一个配置类,按照springboot的要求进行配置,springboot会自动将我们的配置类加入springboot的配置中
      首先创建配置类,实现WebMvcConfigurer接口
    @Configuration
    public class myMvcConfig implements WebMvcConfigurer {
        @Override
        public void addViewControllers(ViewControllerRegistry registry) {
            registry.addViewController("/test").setViewName("success");
        }
    }
    

    然后重写不同的方法配置不同的功能,测试中用到的功能是添加一条跳转规则,当浏览器访问test时,会跳转到success页面,如果只需要跳转页面不需要共享数据,没有必要特地在controller中配置一个方法,直接在此处添加会更加方便

    测试结果
    1. 国际化
      随着浏览器的语言变化页面显示语言,或手动切换后,切换显示语言
      1、在resources文件夹下创建国际化资源文件


      国际化资源文件
      配置

      配置好国际化资源之后,将需要国际化的标签text属性改成#{国际化资源名称}就可以开启国际化功能,根据浏览器语言切换不通的显示语言


      设置
      可以通过设置语言环境解析器LocaleResolver,实现手动点击按钮切换语言的效果
      有这样两个a标签
      a标签
      当点击a标签时,会发送带有两个language属性的请求,我们需要手动配置语言环境解析器,从request域中获取这个属性
    public class myLocalResolver implements LocaleResolver {
    //通过实现LocaleResolver让这个类编程一个自定义语言环境解析器类
    
        @Override
        public Locale resolveLocale(HttpServletRequest request) {
            //获取request域中的language属性值
            String language = request.getParameter("language");
            /*获取语言环境解析器对象,默认使用的就是springboot配置好的语言环境解析器,
              会根据浏览器的语言设置实现国际化*/
            Locale locale = Locale.getDefault();
            //当获取到的language属性值不为空时,表示我们手动切换了语言
            if(!StringUtils.isEmpty(language)){
                //将获取到了language属性值按_切开成两个字符串
                String[] sp = language.split("_");
                //使用Locale的构造器创建新的Locale对象
                //参数一是语言信息,参数二是国家信息
                locale = new Locale(sp[0],sp[1]);
            }
            //如果没有获取到language属性,就使用springboot默认的语言环境解析器
            //如果获取到language属性,就使用自定义的语言环境解析器
            return locale;
        }
    
        @Override
        public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {
    
        }
    }
    

    最后将自定义的语言环境解析器配置到springmvc的扩展类中

        @Bean("localeResolver") //一定要注册到容器中
        public LocaleResolver myRes() {
            return new myLocalResolver();
        }
    

    springboot在我们自己配置了语言环境解析器的情况下,只要我们将它注册到了容器中,就会使用我们配置的解析器

    1. 拦截器
      登录后,才可以访问主页面或进行crud操作,若不登录,则访问任何页面都会跳转到登录页面
      首先配置springmvc的扩展类,使得访问/index.html或/都会跳转到登录页面
        @Override
        public void addViewControllers(ViewControllerRegistry registry) {
            //通过重写addViewControllers来添加新的跳转规则
            registry.addViewController("/").setViewName("index");
            //addViewController表示当接收指定请求时
            registry.addViewController("/index.html").setViewName("index");
            //setViewName表示跳转的页面,会被springboot拼接成完整路径
            //此处为了配合重定向,设置了访问/dashboard.html跳转到dashboard页面
            registry.addViewController("/dashboard.html").setViewName("dashboard");
        }
    

    配置登录功能的controller类,从页面获取username和password属性

    @PostMapping("/login")
        public String login(@RequestParam("username") String username,
                            @RequestParam("password") String password,
                            Model model,
                            HttpSession session) {
            //模拟用户名密码验证
            if(!username.isEmpty() && "123123".equals(password)){
                //当登录成功,在session域中共享用户信息,当做是否登录的判断依据
                session.setAttribute("loginUser",username);
                //为了防止登录成功后,刷新页面重复提交数据造成服务器负担
                //使用重定向转发跳转页面,重定向到dashboard.html页面
                //在springmvc扩展类中添加跳转规则
                return "redirect:dashboard.html";
            }else{
                //若登录不成功在reques域中共享错误信息
                model.addAttribute("error","用户名或密码错误");
                //重新转发到登录页面
                return "index";
            }
    
        }
    

    这样就有一个问题,因为配置了重定向,若直接访问dashboard.html,则可以跳过登录,直接访问内部数据,进行操作,这样显然是不行的,此时需要配置拦截器,判断session域中是否有我们共享的用户名数据,若没有,强制跳转到登录页面并共享错误信息,若有则放行

    public class myHandlerInterceptor implements HandlerInterceptor{
    //实现HandlerInterceptor表示这是一个自定义的拦截器类
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            //从session域中获取我们共享的用户信息
            Object user = request.getSession().getAttribute("loginUser");
            //当用户信息不存在时,表示还没有进行登录操作
            if(user == null){
                //在request域中共享错误信息
                request.setAttribute("error","请先进行登录操作");
                //转发到登录页面,因为配置了跳转规则,访问/就会跳转到登录页面
                request.getRequestDispatcher("/").forward(request,response);
                //返回false表示拦截信息,不放行
                return false;
            }else{
                //当session域中存在用户信息时,表示已经登录,直接放行
                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 {
    
        }
    }
    

    最后需要在springmvc扩展类中,定义拦截范围

        @Override
        public void addInterceptors(InterceptorRegistry registry) {
        //通过重写addInterceptors方法设置拦截器的拦截范围
            //addInterceptor表示添加新的拦截器,参数为拦截器类,此处传入我们自定义的拦截器
            //addPathPatterns用于设置拦截范围,参数为拦截范围,此处设置全部资源拦截
            //excludePathPatterns用于设置不拦截的资源,此处将访问登录页面的请求以及静态资源排除
            registry.addInterceptor(new myHandlerInterceptor()).addPathPatterns("/**").
                    excludePathPatterns("/","/index.html","/login","/webjars/**","/asserts/**");
        }
    

    设置之后,springboot就会使用我们自定义的拦截器,拦截器会根据我们的设置进行拦截,当跳过登录操作访问时,会强制跳转到登录页面,注意:session域中的数据在一次会话中都是存在的,所以登陆成功后在浏览器重启或服务器重启之前,用户数据都会存在

    相关文章

      网友评论

        本文标题:SpringBoot-Web

        本文链接:https://www.haomeiwen.com/subject/belqghtx.html