栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringWeb全栈

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringWeb全栈

目录

一.Spring入门

1.Why Spring?

Spring的核心

2.Maven

Maven命令

Maven核心概念

依赖管理dependencies

3.初识Spring

二.Spring依赖注入

1.Java注解(Annotation)

2.Spring Bean

总结

3.Spring Resource

4.Spring Bean 生命周期

三.Spring MVC

1.Spring Boot

2.Spring Controller

3.Get Request(一)

4.Get Request(二)

我们注意,创建SpringBoot WEB工程,就去网站https://start.spring.io/可以直接创建,然后解压,通过我们的编译器打开文件夹,就可以了

四.Spring Thymeleaf入门

1.Thymeleaf入门



一.Spring入门

1.Why Spring?

Spring是java语言中必须要掌握的框架,它已经有超过10年的稳定期了,基本上所有采用Java语言的公司都会采用Spring Framework 这个框架基本上是全能的,涵盖了Java的各个领域

Spring的核心

依赖注入(DI)是Spring最核心的技术点

使用Spring大大降低了开发难度和助力团队开发,它更加强调了面向对象。

2.Maven

Maven是一个项目管理和构建自动化工具

Maven提供了一个命令行工具可以把工程打包成Java支持的格式(比如jar),并且支持部署到中央仓库,这样使用者只需要通过工具就可以很快捷的运用其他人写的代码,只需要添加依赖即可

 从这个架构里可以看到借助中央仓库,我们可以把Java代码任意共享给别人,这对于团队协同开发来说是至关重要的,可以说Java工程化发展到现在,Maven起到了决定性作用

Maven使用惯例优于配置的原则,在没有定制之前,所有的项目都有如下的结构

 ${basedir}代表的是Java工程的根路径,在我们这里就是工程的根目录。

一个Maven项目在默认情况下会产生JAR文件,另外,编译后的classes会放在${basedir}/target/class下面,JAR文件会放在${basedir}/target下面

Maven工具的安装就不再赘述

Maven命令

想要使用Maven工具,是要在命令行里输入指令的方式来执行的

简单介绍三条命令

1.mvn clean compile 编译命令,Mavenue自动扫描src/main/java下的代码并且完成编译,执行完成后,会在根目录下生成target/classes目录(存放所有的class)

2.mvn clean package 编译并打包命令,先执行compile命令,在执行jar打包命令,这个结果会把所有的java文件和资源打包成一个jar,jar是java的一个压缩格式,方便我们灵活运用多个代码

3.mvn clean install 执行安装命令,是compile package install的集合,安装到本地的Maven仓库目录里,这个目录是${user_home}/.m2 

Maven核心概念

仓库,依赖管理,POH,插件,生命周期这五个概念都会运行在Maven的配置文件中,即强约定的XML格式文件,它的文件名一定是pom.xml

1.POM(Project Object Model)

一个Java项目所有的配置都放置在POM文件中大概有如下行为:

定义项目的类型,名字

管理依赖关系

定制插件

约定大于一切,请记住这句话

Maven坐标

示例:

com.youkeda.course
app
jar
1.0-SNAPSHOT

这四个标签组成了Maven坐标

Maven属性配置

示例:

 
    1.8
    ${java.version}
    UTF-8
    ${java.version}

依赖管理dependencies

学了Maven坐标后,有了Maven坐标我们可以通过Maven依赖管理来运行别人写的代码了

dependency就是用于指定当前工程依赖于其他代码库的,Maven会自动管理jar依赖

一旦我们在pom.xml里声明了dependency信息,会先去本地用户目录下.m2文件夹内查找对应的文件,如果没有找到那么就会触发从中央仓库下载的行为,下载完就会存放在本地的.m2文件夹内

添加依赖,在中添加依赖,例如在Jave网络编程中我们用到的fastjson这个库


    
        com.alibaba
        fastjson
        1.2.62
    

注意标签只能有一个,而其中的依赖可以有很多个

间接依赖

间接依赖是mvn成功的要素,简单来说就是一个A工程依赖了一个A库,当前B工程依赖了这个A工程,那么B工程也自动依赖了A库

插件体系

插件体系让Maven工具变得高度可定制

示例


    
        
            org.apache.maven.plugins
            maven-compiler-plugin
            3.8.1
        
    

这里声明了一个maven-compiler-plugin插件用于执行maven compile的,你会发现maven的插件其实也是存放在中央仓库的坐标,也就是一切皆是jar

3.初识Spring

搞定了前置技术,现在来配置创建一个Spring工程,目前来说我们基本使用的是Spring5

Spring5的Maven坐标如下


  org.springframework
  spring-context
  5.2.1.RELEASE



Spring强调面向接口编程,所以大部分情况下Spring代码都会有接口和实现类

二.Spring依赖注入

1.Java注解(Annotation)

看下面代码

@Service
public class MessageServiceImpl implements MessageService{
    public String getMessage() {
         return "Hello World!";
    }
}

@service就是一个注解

Annotation(注解)

Annotation是可以在编译运行阶段读取的,Spring就通过运行阶段动态的获取Annotation,从而完成了很多自定义的行为

2.Spring Bean

loC容器是Spring框架最核心的组件,没有loC就没有Spring框架,在Spring框架中,通过依赖注入实现loC

在Spring的世界中,所有的Java对象都会通过loC容器转变为Bean(Spring对象的一种称呼,以后我们都用Bean来表示Java对象),构成应用程序主干和由Spring loC容器管理的对象称为beans,beans和他们之间的依赖关系反应在容器使用的配置元数据中。基本上所有的Bean都是由接口+实现类来完成的,用户想要获取Bean的实例直接从loC容器获取就可以了,不需要关系实现类

1.Spring目前主流配置元数据的方式是基于Annotation的,所以我们这里也是以Annotation为例

2.Annotation类型的loC容器对应的类是

org.springframework.context.annotation.AnnotationConfigApplicationContext

我们如果想要启动loC容器,需要运行

ApplicationContext context = new AnnotationConfigApplicationContext("fm.douban");

这段代码的含义就是启动loC容器,并且自动加载fm.douban下的Bean(只要引用了Spring注解的类都可以被加载)

3.AnnotationConfigApplicationContext这个类的构造函数有两种:

AnnotationConfigApplicationContext(String basePackages)//根据包名实例化

AnnotationConfigApplicationContext(Class clazz)//根据自定义包扫描行为实例化

4.Spring官方声明为Spring Bean 的注解有以下几种:

org.springframework.stereotype.Service
org.springframework.stereotype.Component
org.springframework.stereotype.Controller
org.springframework.stereotype.Repository

只要在类上引用这类注解,就可以被loC容器加载

@Component注解是通用的Bean注解,其余三个注解都是扩展自Component

@Service代表的是Service Bean

@Controller作用于Web Bean

@Repository作用于持久化相关的Bean

实际上这四个注解都可以被loC容器加载,一般情况下,我们使用@Service,如果是Web服务那就使用@Controller

Spring依赖注入,简单来说就是一种获取其他实例的规范

假设我们现在有一个类SubjectService,那么在任何使用SubjectService的地方,都需要实例化对象

SubjectService subjectService = new SujectServiceImpl();

问题来了:万一SubjectServiceImpl依赖的**Service太多,那么就需要大量编码,new出很多服务实例,而且代码也容易出错

加入注解的作用,就是让Spring系统自动管理各种实例

所谓管理,就是用@Service注解把SubjectServiceImpl和SongServiceImpl等等所有的服务实现,都标记成SpringBean;然后,在任何使用服务的地方,用@Autowired注解标记,告诉Spring这里需要注入实现类的实例

项目启动的过程中,Spring会自动实例化服务实现类,然后自动注入到变量中,不需要开发者大量的写new代码了

@Service和@Autowired是相辅相成的,如果实现类没有加@Service,就意味着没有标记成SpringBean,那么即使加了@Autowired也无法注入实例

而

private SongService songService;

没有加@Autowired,Spring亦无法注入实例

每个Annotation(注解)都有各自特定的功能,Spring检查到代码中有注解,就自动完成特定功能,减少代码量,降低系统复杂度

总结

把实现类上加@Service,然后在其他类中需要实例的时候,写下如下代码就可以

@Autowired
private SongService songService;

3.Spring Resource

文件处理方案Spring Resource

文件在电脑的某个位置或则文件在工程目录下,都是可以IO来读写,但是文件如果在工程的src/main/resource目录下,我们在Maven中知道着是Maven工程存放文件的地方,由于Maven在执行package的时候,会把resources目录下的文件一起打包进jar包里(我们之前提到过jar是Java的压缩文件),显然这种情况用File对象是读取不到的,因为文件已经在jar里了。

怎么解决呢?

classpath

在Java内部中,我们一般把文件路径称为classpath,所以读取内部文件就是从classpath内读取,classpath指定的文件不能解析成File对象,但是可以解析成InputStream,我们借助Java IO就可以读取出来了

classpath类似虚拟目录,它的根目录是从/开始代表的是src/main/java或者src/main/resources目录

如何使用classpath读取文件(设resources目录下有一个data.json文件)

//添加依赖

  commons-io
  commons-io
  2.6
public class Test {
  public static void main(String[] args) {
    // 读取 classpath 的内容
    InputStream in = Test.class.getClassLoader().getResourceAsStream("data.json");
    // 使用 commons-io 库读取文本
    try {
      String content = IOUtils.toString(in, "utf-8");
      System.out.println(content);
    } catch (IOException e) {
      // IOUtils.toString 有可能会抛出异常,需要我们捕获一下
      e.printStackTrace();
    }
  }

}

InputStream in = Test.class.getClassLoader().getResourceAsStream("data.json");

这段代码的含义是从Java运行的类加载器(ClassLoader)实例中查找文件,Test.class指的是当前的Test.java编译后的Java class文件。

如果是Maven、Spring工程,文件在resources中这种情况使用classpath方法读取文件,也就是上文代码演示的方法

在Spring当中定义一个

org.springframework.core.io.Resource

类来封装文件,这个类的优势在于可以支持普通File也可以支持classpath文件,并且在Spring中通过

org.springframework.core.io.ResourceLoader

服务提供任意文件的读写,可以在任意的Spring Bean中引入ResourceLoader

@Autowired
private ResourceLoader loader;

演示一下在Spring当中如果读取文件

public interface FileService {
    String getContent(String name);
}

import fm.douban.service.FileService;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.InputStream;

@Service
public class FileServiceImpl implements FileService {

    @Autowired
    private ResourceLoader loader;

    @Override
    public String getContent(String name) {
        try {
            InputStream in = loader.getResource(name).getInputStream();
            return IOUtils.toString(in,"utf-8");
        } catch (IOException e) {
           return null;
        }
    }
}
FileService fileService = context.getBean(FileService.class);
  String content = fileService.getContent("classpath:data/urls.txt");
  System.out.println(content);

此外,最让人眼前一亮的是,Resource还可以加载远程文件,比如说

String content2 = fileService.getContent("https://www.zhihu.com/question/34786516/answer/822686390");
System.out.println(content2);

总结:在Spring Resource当中,把本地文件、classpath文件、远程文件都封装成Resource对象来统一加载

4.Spring Bean 生命周期

 我们在大部分情况下掌握init方法即可,这个init方法名称可以是任意名称,因为我们是通过注解来声明init的,我们以SubjectServiceImpl为例

mport javax.annotation.PostConstruct;

@Service
public class SubjectServiceImpl implements SubjectService {

  @PostConstruct
  public void init(){
      System.out.println("启动啦");
  }

}  

只需要在方法上加@PostConstruct注解,就代表该方法在Spring Bean 启动后会自动执行

@PostConstruct的完整包路径是

javax.annotation.PostConstruct

有了init方法后,之前static代码块的内容就可以移动到init方法里了

总结 Spring生命周期可以让我们更轻松的初始化一些行为以及维护数据,现在只需掌握初始化方法即可

三.Spring MVC

1.Spring Boot

Sping Boot的核心还是Spring

①有了Spring Boot就不需要额外部署Tomcat这类服务器了,Spring Boot默认集成了Tomcat

②SpringBoot自定义了打包格式,通过这个直接把一个JavaWeb工程转化成普通的Java工程,启动一个main方法就可以把Spring工程启动起来,极大的降低了开发难度

③SpringBoot默认集成了你能想到的第三方框架和服务,比如数据库连接、NoSQL,安全等等,开发者也不需要关心复杂的Maven依赖了,开箱即用

④SpringBoot 提供了标准的属性配置文件,支持应用参数动态配置,让代码运行更加灵活

SpringBoot强调开箱即用

SpringBoot默认集成了Web,所以可以通过网页访问

2.Spring Controller

SpringMVC是JavaWeb的一种实现框架

网页加载过程,在SpringBoot方案里,一个网页请求到了服务器后,首先我们进入的是JavaWeb服务器,然后进入SpringBoot应用,最后匹配到一个SpringController(这其实也是一个Spring Bean),然后路由到具体某一个Bean方法,执行完返回结果输出到客户端

从这个流程中我们可以得知:我们只需要掌握SpringController就可以自己提供Web服务了

SpringController技术有三个核心点:

Bean的配置:Controller注解运用

网络资源的加载:加载网页

网址路由配置:RequestMapping注解运用

1.Controller注解

Spring Controller本身也是一个SpringBean,只是它多提供了Web能力,我们只需要在类上提供一个@Controller注解就可以了

2.加载网页

在Spring Boot应用中,一般把网页存放在src/main/resources/static,在controller中,会自动加载static下的html内容,所以通过SpringBoot建设网站也是非常简单的

import org.springframework.stereotype.Controller;

@Controller
public class HelloControl {

    public String say(){
        return "hello.html";
    }

}

return "hello.html" 返回的是html文件路径,当执行这段代码的时候,SpringBoot实际加载的是src/main/resources/static/hello.html文件

resources文件,我们之前说过这是classpath文件,Spring很强大,自动帮我们做了加载,所以我们只需要写hello.html即可(注意文件路径不要写static)

如果我们的html文件是存放在src/main/resources/static/html/hello.html中

那么return语句应该是 

return "html/hello.html";

3.RequestMapping注解

对于Web服务器来说,必须实现的一个能力就是解析URL,并且提供资源给调用者,这个过程称为路由

SpringMVC完美的支持了路由的能力,并且简化了路由配置,只需要在提供Web访问的方法上添加一个@RequestMapping注解就可以完成配置了

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HelloControl {

    @RequestMapping("/hello")
    public String say(){
        return "html/hello.html";
    }

}

3.Get Request(一)

Http网络中,最常用的两个协议是get和post

平常我们浏览网站,看视频,看图片都是用的get协议,如何用SpringMVC来支持Http服务器get协议,通过get协议我们可以渲染网页

在SpringMVC中,定义一个URL参数也非常重要,只需要我们在方法上面添加对应的参数和参数注解就可以了,话不多说,上代码

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

@Controller
public class SongListControl {

    @RequestMapping("/songlist")
    public String index( @RequestParam("id") String id){
        return "html/songList.html";
    }

}

RequestParam注解的包路径是

org.springframework.web.bind.annotation.RequestParam

由于SpringMVC的注解都是在

org.springframework.web.bind.annotation

包内,所以我们import的时候,直接用

import org.springframework.web.bind.annotation.*;

就可以省去很多的导入

多个参数的写法

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

@Controller
public class SongListControl {

  @RequestMapping("/songlist")
  public String index(@RequestParam("id") String id,  @RequestParam("pageNum") int pageNum){
     return "html/songList.html";
  }
}

如果我们在Request方法里面声明了多个参数,那么URL访问的时候就必须传递该参数

4.Get Request(二)

@GetMapping

我们知道@RequestMapping注解用于解析URL请求路径,这个注解默认是支持所有的Http Method的。放开所有的HttpMethod这样是不安全的,一般我们还会明确指定method,比如get请求

用@GetMapping替换@RequestMapping,他们的包路径是一样的,之前的代码可以改成

import org.springframework.web.bind.annotation.*;


@GetMapping("/songlist")
public String index(@RequestParam("id") String id,@RequestParam("pageNum") int pageNum){
  return "html/songList.html";
}

可以通过来访问

http://xxxx/songlist?id=xxx&pageNum=1

非必要传递参数

@RequestParam(name="pageNum",required = false) int pageNum

当前的参数名称是pageNum required=false表示不是必须的

输出JSON数据

目前来说通用的Web数据格式就是JSON,在Spring当中配置JSON数据非常简单

@GetMapping("/api/foos")
@ResponseBody
public String getFoos(@RequestParam("id") String id) {
  return "ID: " + id;
}

添加@ResponseBody注解

我们调用URL

https://xxxx/api/foos?id=100
public class User{
  private String id;
  private Stirng name;
  // 省略了 getter、setter
}


public class UserControl{
  //缓存 User 数据
  private static Map users = new HashMap();

  
  @PostConstruct
  public void init(){
    User user = new User();
    user.setId("100");
    user.setName("张三");
    users.put(user.getId(),user);
  }
    
  @GetMapping("/api/user")
  @ResponseBody
  public User getUser(@RequestParam("id") String id) {
    return users.get(id);
  }
}

最后页面返回的是JSON字符串,这也是Spring MVC比较强大和方便的地方,一般我们把这种输出JSON数据的方法称为API

我们注意,创建SpringBoot WEB工程,就去网站https://start.spring.io/可以直接创建,然后解压,通过我们的编译器打开文件夹,就可以了

四.Spring Thymeleaf入门

1.Thymeleaf入门

Thymeleaf是一种模板框架,与Html天然相融合.数据+模板+引擎渲染出真实的页面

那么如何初始化Thymeleaf

添加依赖


  org.springframework.boot
  spring-boot-starter-thymeleaf

数据传递

SpringMVC把页面数据层封装的非常完善,只需要在方法参数中引入一个Model对象,就可以通过Model对象传递数据到页面中了。

首先我们正确导入这个Model类

import org.springframework.ui.Model;
@Controller
public class SongListControl {

  @Autowired
  private SongListService songListService;

  @RequestMapping("/songlist")
  public String index(@RequestParam("id")String id,Model model){

    SongList songList = songListService.get(id);
    //传递歌单对象到模板当中
    //第一个 songList 是模板中使用的变量名
    // 第二个 songList 是当前的对象实例
    model.addAttribute("songList",songList);

    return "songList";
  }
}

SpringMVC中对于模板文件有固定的存放位置,放置在工程src/main/resources/templates

所以上面的return "songList";其实是会去查找src/main/resources/templates/songList.html文件,系统会自动匹配到后缀的,所以不需要写成return "songList.html";

文件内容如下



  
    
    
    
    
  

Thymeleaf模板文件在src/main/resources/templates目录下

下面这这段代码的意思是,让软件能够识别thymeleaf语法

xmlns:th="http://www.thymeleaf.org"
2.Thymeleaf变量 模板变量

th:text这个属性就是Thymeleaf自定义的Html标签属性,th是Thymeleaf的缩写,所以如果你看到了th:开头的标签属性,那么就代表的是Thymeleaf语法

th:text语法的作用就是会动态替换掉html标签的内部内容,这句话啥意思呢?

Hello

这段代码的执行结果就是用msg变量值替换了span标签内的Hello字符串,比如说msg变量值是你好,那么代码的渲染结果是

你好

${msg}这个语法就是表示获取模板中的变量msg

一般情况下,模板的变量都是会存放在模板的上下文中,所以我们如果想要调用变量,就需要先设置到模板上下文中去

model.addAttribute("songList",songList);

就可以完成上下文变量的设置

再举个例子:

import org.springframework.ui.Model;

@Controller
public class DemoControl {

  @RequestMapping("/demo")
  public String index(Model model){
    String str = "你好";
    model.addAttribute("msg",str);
    return "demo";
  }
}

第一个参数设置的就是上下文变量名(可随便定义),第二个参数设置的就是变量值

3.Thymeleaf循环语句

Thymeleaf的for循环也是使用标签属性来完成的,

th:each

就代表循环语句,示例如下:

,显示行数数字,从1开始,记住用法即可

4.Thymeleaf表达式

Thymeleaf表达式对于动态数据的处理很方便,应用于字符串处理和数据转化

字符串处理

字符串拼接示例:

 
数据转化 

Thymeleaf默认继承了大量工具类,可以方便的进行数据转化,一般我们使用最多的是dates

如果想处理LocalDate和LocalDateTime类,可以添加如下依赖


  org.thymeleaf.extras
  thymeleaf-extras-java8time
  3.0.4.RELEASE

这个库会自动添加一个新的工具类temporals

工具类使用的是#{工具类}

我们一般使用dates/temporals用于处理日期类型到字符串的转化

5.Thymeleaf条件语句

动态页面必然会遇到if/else的情况,Thymeleaf也支持if/else能力,同样也是以th:开头的属性,if表达式的值是ture的情况下就会执行渲染

男
  • 男 女
  •  model.addAttribute("users",users);

    五.Spring Template 进阶 1.Thymeleaf表单

    我们来制作一个简易的图书管理系统

    package com.bookstore.control;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.*;
    
    @Controller
    public class BookControl {
      // 当页面访问 http://localhost:8080/book/add.html 时
      // 渲染 addBook.html 模板
      @GetMapping("/book/add.html")
      public String addBookHtml(Model model){
        return "addBook";
      }
    }
    
    
    package com.bookstore.control;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.*;
    
    import java.util.*;
    
    import com.bookstore.model.*;
    
    @Controller
    public class BookControl {
      //缓存所有书籍数据
      private static List books = new ArrayList<>();
    
      @GetMapping("/book/add.html")
      public String addBookHtml(Model model){
        return "addBook";
      }
    
      @PostMapping("/book/save")
      public String saveBook(Book book){
        books.add(book);
        return "saveBookSuccess";
      }
    
    }

    PostMapping和@GetMapping不同点在于PostMapping只接收http method为post请求的数据

    新增templates/saveBookSuccess.html文件

    
    
    
    
      
      
      
      添加书籍
    
    
    
      添加书籍成功
    
    
    

    一般情况下,我们把html表单的method设置为post。这样可以保证数据传输安全,SpringMVC就需要接收post请求

    如下

    
    
    
    
      
      
      
      添加书籍
    
    
    
      添加书籍
      
    2.Spring Validation(一)

    在实际的工作过程中对于数据的保存是离不开数据验证的,比如name必须输入等校验规则,Spring对于数据验证的支持也非常好,我们可以借助Spring Validation来处理表单数据的验证

    Validation注解

    JSR380定义了一些注解用于数据校验,这些注解可以直接设置在Bean属性上

    @AssertTrue 是否为true

    @Size 约定字符串长度

    @Min 字符串的最小长度

    @Max 字符串的最大长度

    @Email 是否是邮箱格式

    @NotEmpty 不允许为null或者为空,可以用于判断字符串、集合(常用)

    package com.bookstore.model;
    
    import javax.validation.constraints.*;
    
    public class User {
    
        @NotEmpty(message = "名称不能为 null")
        private String name;
    
        @Min(value = 18, message = "你的年龄必须大于等于18岁")
        @Max(value = 150, message = "你的年龄必须小于等于150岁")
        private int age;
    
        @NotEmpty(message = "邮箱必须输入")
        @Email(message = "邮箱不正确")
        private String email;
     
        // standard setters and getters 
    }

    校验是可以累加的,如上面的@Min和@Max,系统会按照顺序校验,任何一条触发就会抛处校验错误到上下文中

    创建一个表单页 user/addUser.html模板文件,用于管理员添加用户

    
    
    
    
      
      
      
      添加用户
    
    
    
      添加用户
      
    import javax.validation.Valid;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.*;
    import org.springframework.validation.BindingResult;
    import com.bookstore.model.*;
    
    @Controller
    public class UserControl {
    
      @GetMapping("/user/add.html")
      public String addUser() {
        return "user/addUser";
      }
    
     @PostMapping("/user/save")
        public String saveUser(@Valid User user, BindingResult errors) {
            if (errors.hasErrors()) {
                // 如果校验不通过,返回用户编辑页面
                return "user/addUser";
            }
            // 校验通过,返回成功页面
            return "user/addUserSuccess";
        }
    
    }

    @Valid完整包路径是javax.validation.Valid;

    BindingResult类路径是org.springframework.validation.BindingResult

    
    
    
    
      
      
      
      添加用户
    
    
    
      添加用户成功
    
    
    

    转载请注明:文章转载自 www.mshxw.com
    本文地址:https://www.mshxw.com/it/1032372.html
    我们一直用心在做
    关于我们 文章归档 网站地图 联系我们

    版权所有 (c)2021-2022 MSHXW.COM

    ICP备案号:晋ICP备2021003244-6号