@RestController vs @Controller

@RestController@Controller@ResponseBody 的合体,如果标注在处理器上,则处理器的方法,如果返回一般对象,则返回 JSON 形式的数据给页面,如果返回字符串,则直接将字符串写给页面,二者都不会去查找静态资源 ;

@Controller 当返回值是字符串的时候,会先去找有没有对应的视图,有就返回视图,没有就会报错,找不到对应的视图;

如果返回对象,也是直接报错;因为它只能返回三种返回值,也就是最初学 SpringMvc 时候学的三种:ModelAndViewVoidString

简而言之,@Controller 需要找视图,@RestController 不会去找视图 ;

最后总结下 @Controller 方法的返回值:

当其返回值是 String 的时候,如果直接写视图名字,则会被拼接成视图地址,如果想去静态资源文件夹下面,而非去视图所在的文件夹,则使用 forwardredirect 标注下 :return "redirect:/index.html" ;

只要没有使用 forwardredirect 标注,都被当做是 视图名字 ;

直接写 / xx 全称也可以找到 匹配到 视图下面 ,比如: /xx.html 也会去视图下面找,多层文件夹也一样写 /xx/yy.html;


默认访问首页

前面静态资源的时候,我们说过,Spring Boot 默认对静态资源文件下的 index.html ,做了映射,映射为 / ,这样就变成了默认首页;

如果,我们在 templates 文件夹下面配置首页,需要我们自己设置下,才可以变为默认首页;

引入 thymeleaf 模板以后,Spring Boot的自动配置会对其进行配置,其中就有一个 视图配置:当处理器的方法,返回字符串的时候,会先去寻找 templates 文件夹下面 .html 为后缀的静态资源,看有没有名字匹配的,有就返回视图,没有就返回字符串字面值;(这里需要注意,处理器标注的是 @Controller 注解,而非 @RestController ,至于原因,上面提到了 )

至于其他地方的静态资源,对不起,默认访问不到,因为Spring Boot没对其进行映射 ;

最简单的方法,实在处理器里面写个映射:

 @RequestMapping({"/","/index"})
public String success(){
return "index" ;
}

还可以自己扩展Spring BootWebMvc 配置 ,将首页页面,进行映射,只需要在自定义的配置里面,进行如下操作:


@Bean
public WebMvcConfigurerAdapter webMvcConfigurerAdapter(){
return new WebMvcConfigurerAdapter() {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/index").setViewName("index");
}
} ;
}

千万不要在配置类上,添加 @EnableWebMvc ,那样就不是扩展了,是完全代替了,取代了自动配置 ;


设置项目名

在配置文件中使用

server.servlet.context-path=/项目名

国际化

  1. 编写配置文件

    首先编写配置文件,IDEA 会识别出我们想进行国际化,只要按照下面的方式进行写配置文件;



    然后按照如下方式进行操作:

  2. 配置国际化组件

    Spring Boot 自动配置好了管理国际化的组件,基础名默认是message,基础名就是去掉语言和国家,剩下的前缀。比如 login_en_US,去掉语言 en 和 国家 US ,就剩下 login

    不是 message ,需要设置下基础名,需要写类路径下的完整路径,然后加上自己的基础名 :

    比如我的配置文件,在类路径下面的 i18n 文件夹下面的,基础名叫 login,就写成下面这样:

  3. 获取配置文件的值

    然后在页面中获取配置文件的值,我们使用 thymeleaf 模板,使用 #{login.tip} 这样的格式进行获取值(看仔细点,是 # 而非 $),IDEA 还会有提示的,能直接看到属性的值:



    如果没有标签体,则使用 [[login.tip]] 语法;

    在页面中获取配置文件的值的时候,如果你没有编码的设定,会出现乱码,解决方法,在这个系列的前面博客中已经讲过了,或者自己百度,又或者根本就没有看这些博客呢,你自己又不是博客专家,哈哈,想这么周到干嘛呢;

  4. 根据浏览器语言切换

    经过上面的设置以后,现在切换浏览器的语言选项,界面的文字也会随之变换;

  5. 通过点击链接切换

    切换浏览器语言首选项,页面文字,随之切换的原理,就是有个 Locale 区域信息对象,Spring Mvc 通过 LocaleResolver 获取区域信息对象, 然后只要拿到这个对象,进行设置,即可以了;

    Sping Boot 默认实现配置了一个 Locale 区域信息对象,它的实现很简单,就是从请求头中获取区域信息;

    如果我们没有进行配置区域信息对象,则使用默认的,如果我们配置了,则使用我们配置的;

    因此,我们可以替换默认实现,实现自己的Locale 区域信息对象,从而定义获取区域信息的规则;

    实现自己的区域信息对象代码如下:

        @Bean
    public LocaleResolver localeResolver(){
    return new LocaleResolver() {
    @Override
    public Locale resolveLocale(HttpServletRequest httpServletRequest) {
    String l = httpServletRequest.getParameter("l");
    Locale locale = Locale.getDefault() ;
    if(!StringUtils.isEmpty(l)){
    String[] strings = l.split("_");
    // 调用有2个参数的构造器,第一个参数:语言信息;第二个参数:地区信息
    locale = new Locale(strings[0],strings[1]);
    }
    return locale;
    } @Override
    public void setLocale(HttpServletRequest httpServletRequest, @Nullable HttpServletResponse httpServletResponse, @Nullable Locale locale) { }
    };
    }

    将这段代码,添加到我们的配置类里面,切忌方法名字,只能为 localeResolver ,它是注入到容器中的 idSpring Boot 也是根据这个 id 来判断我们自定义了 区域信息对象 ;


登陆 & 拦截

  1. 禁用 thymeleaf 模板引擎的缓存

    在开发期间,我们需要页面被修改以后,再次访问就应该是新的页面,这样就需要禁掉 thymeleaf 的缓存 ;

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

    同时在使用 IDEA 的时候,页面被修改以后,IDEA 需要重新编译下,浏览器才会看到最新的页面,使用 Ctrl + F9 进行编译 ;

  2. 登陆

    处理登陆的处理器:

        @PostMapping("/user/login")
    public String login(@RequestParam("username") String username, @RequestParam("password") String password, Map<String, Object> map, HttpSession session) {
    if (!StringUtils.isEmpty(username) && "123456".equals(password)){
    session.setAttribute("login",username);
    // 重定向到页面,防止表单重复提交
    return "redirect:/main.html";
    }
    map.put("msg","用户名或者密码错误") ;
    return "index";
    }

    上面的处理没涉及到数据库,仅仅演示处理逻辑;

    登录成功以后,这里需要注意,进行页面的跳转,使用的是 重定向 ;如果,重定向的页面,是模板引擎下面的页面,则需要做个映射,因为只有 静态资源文件 下面的文件,才能被浏览器 直接 访问到;

    做个映射,就像之前配置首页一样:

    @Bean
    public WebMvcConfigurerAdapter webMvcConfigurerAdapter(){
    return new WebMvcConfigurerAdapter() {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
    registry.addViewController("/").setViewName("index");
    registry.addViewController("/index").setViewName("index");
    // 配置映射
    registry.addViewController("/main.html").setViewName("success");
    }
    } ;
    }
  3. 拦截

    像上边那样做了映射以后,其实不用登陆,直接访问映射的地址,也能访问到 thymeleaf 下面对应的文件了 ;

    因此,需要做个拦截,自定义拦截器:


    @Component
    public class LoginIntercept implements HandlerInterceptor { @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    HttpSession session = request.getSession();
    if (session.getAttribute("login") == null){
    request.setAttribute("msg","没有权限访问,请登录");
    request.getRequestDispatcher("/index").forward(request,response);
    return false;
    }
    return true;
    }
    }

    然后一定还要进行配置下:


    @Bean
    public WebMvcConfigurerAdapter webMvcConfigurerAdapter() {
    return new WebMvcConfigurerAdapter() {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
    registry.addViewController("/").setViewName("index");
    registry.addViewController("/index").setViewName("index");
    registry.addViewController("/main.html").setViewName("success");
    } // 注册拦截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new LoginIntercept())
    // 拦截哪些资源,所有资源
    .addPathPatterns("/**")
    // 排除哪些资源,其中静态资源: *.css,*.js ,已经由 Spring Boot 自己映射了,
    .excludePathPatterns("/index","/","/user/login");
    }
    };
    }

Restful 风格

以前在学习 Spring Mvc 的时候,老师也讲过一点这个概念,简而言之,就是对 URL 的一些建议要求,URL 仅仅代表对资源的标识,对资源的操作,不再体现在 url 上面

Http 是有四个方法的,分别是 get,post,put,delete ,可能好多人以为只有 post,get 两种方法 ;



可以参照下面的图,看 Restful 风格的 url

(5)Spring Boot web开发 --- Restful CRUD的更多相关文章

  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 Web 开发@Controller @RestController 使用教程

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

  7. 4.Spring Boot web开发

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

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

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

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

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

随机推荐

  1. select和C标签

    <select name="cpcyModel.rwzj" id="cpcyModel_rwzj"> <option value=" ...

  2. 深入理解document.referrer的用法

    前言 在JavaScript中,document对象有很多属性,其中有3个与对网页的请求有关的属性,它们分别是URL.domain和referrer. URL属性包含页面完整的URL,domain属性 ...

  3. JAVA日志工具类

    package com.ming.util; import java.io.File; import java.io.FileWriter; import java.io.IOException; i ...

  4. js实现replaceAll方法

    js本来有replace方法,请看w3school的说明: replace() 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串. 语法: stringObject.rep ...

  5. JVM Java字节码方法表与属性

    方法表 1.methods_count  method_info,前三个字段和field_info一样 2.方法的属性结构 方法中的每个属性都是一个attribut_info结构 JVM定义了部分at ...

  6. 【Java/Json】Java对Json进行建模,分词,递归向下解析构建Json对象树

    伸手党的福音 代码下载:https://files.cnblogs.com/files/xiandedanteng/JsonLexerBuilder20191202.rar 互联网上成型的对Json进 ...

  7. Spring Boot TImer Schedule Quartz

    Spring Boot 2.X(十二):定时任务-云栖社区-阿里云https://yq.aliyun.com/articles/723876?spm=a2c4e.11155472.0.0.2f8b3a ...

  8. Python爬取所有城市的aqi值

    # -*- coding: utf-8 -*- # author:baoshan import requests from bs4 import BeautifulSoup def get_city_ ...

  9. Python3基础 complex 声明复数

             Python : 3.7.3          OS : Ubuntu 18.04.2 LTS         IDE : pycharm-community-2019.1.3    ...

  10. 为什么static成员必须在类外初始化,而不能在类的头文件中初始化

    为什么static成员必须在类外初始化 为什么静态成员不能在类内初始化 在C++中,类的静态成员(static member)必须在类内声明,在类外初始化,像下面这样.   class A { pri ...