多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

Maven+SpringBoot

Maven+SpringBoot 一Spring定义Spring让Java程序更加快速简单和安全。Spring对于速度、简单性和生产力的关注使其成为世界上最流行的Java框架Spring的两个含义1泛指Spring家族产业2Spring Framework/Spring Core1.1 MavenMaven是一个项目管理工具。基于POM的概念Maven可以通过一小段描述信息来管理项目的构建报告和文档的项目管理工具软件即Maven是一个项目管理工具通过pom.xml文件的配置获取 jar包而不用手动去添加 jar包1.1.1 Maven的功能maven简单方便可以提高我们的开发效率减少开发bugmaven有两个主要的功能项目构建和管理依赖1项目构建maven提供了标准的跨平台的自动化项目构建方式当开发一个项目之后代码需要经过编译测试打包发布等流程每次代码的修改都需要经过这些流程如果代码反复调试修改这个流程就需要反复进行就显得非常麻烦而maven给我们提供了一套简单的命令来完成项目的构建比如maven命令中的package可以完成项目的打包操作打包就是把所有的class文件全部放在一起打成jar包或者war包jar包和war包都是⼀种压缩文件 jar包就是把开发人员已经写好的一些代码进行打包。 打好的jar包就可以引入到其他项目中也可以直接使用这些jar包中的类和属性。另外也可以打成可执行jar包这样的包就可以通过java-jar命令来执行war包可以理解为是⼀个web项⽬里面是项目的所有东西通常用于网站.2依赖管理Maven是⼀个项目管理工具通过pom.xml文件的配置获取jar包而不用手动去添加jar包获取的jar包其实就是依赖pom.xml就是maven的配置文件用以描述项目的各种信息依赖配置依赖指当前项目运行所需要的jar包例如在JDBC中需要手动下载mysql-connector-java的包并且添加到项目中如果使用maven则只需要在pom.xml中引入mysql-connector-java的依赖就可以了dependencies dependency groupIdcom.mysql/groupId artifactIdmysql-connector-j/artifactId version9.5.0/version !--排除依赖-- !-- exclusions-- !-- exclusion-- !-- artifactIdspring-jcl/artifactId-- !-- groupIdorg.springframework/groupId-- !-- /exclusion-- !-- /exclusions-- /dependency /dependencies依赖传递没有使用maven时向项目中添加依赖的jar包需要把所有的jar包都复制到项目⼯程下比如A依赖BB依赖C, 那么A项目引⼊B的同时也需要引⼊C如果我们手动管理这个依赖这个过程就会比较麻烦我们需要知道每个库都依赖哪些库以及这些依赖之间的版本是如何关联的但使用maven的话就可以避免管理所需依赖的关系。我们只需要在pom文件中定义直接依赖就可以了由于maven的依赖具有传递性所以会自动把所依赖的其他jar包也⼀起导入直接依赖在当前项⽬中通过依赖配置建⽴的依赖关系间接依赖被依赖的资源如果依赖其他资源当前项⽬间接依赖其他资源依赖排除随着项目越来越复杂库之间的依赖关系会越来越复杂排除依赖主动断开依赖的资源被排除的资源无需指定版本exclusions exclusion artifactIdspring-jcl/artifactId groupIdorg.springframework/groupId /exclusion /exclusions1.1.2 maven仓库dependency groupIdcom.mysql/groupId artifactIdmysql-connector-j/artifactId version9.5.0/version /dependency这个代码,我们称之为坐标,也就是唯⼀的.在Maven中,根据groupId、artifactId、version的配置,来唯⼀识别⼀个jar包,缺⼀不可.当我们在pom⽂件中配置完依赖之后,点击刷新,Maven会根据坐标的配置,去仓库⾥寻找Jar包,并把他下载下来,添加到项⽬中.这个Jar包下载的地⽅就称为仓库.仓库⽤于存储资源管理各种jar包本地仓库本地仓库自己计算机上的⼀个目录(用来存储jar包) 当项目中引入对应依赖jar包后首先会查找本地仓库中是否有对应的jar包• 如果有则在项目直接引用• 如果没有则去中央仓库中下载对应的jar包到本地仓库中央仓库中央仓库:maven软件中内置⼀个远程仓库地址就是中央仓库服务于整个互联⽹.由Maven团队 维护全球唯⼀.仓库地址https://repo1.maven.org/maven2/可以通过https://mvnrepository.com这个⽹站来查询并下载我们可以把⾃⼰写好的Jar包上传到中央仓库(具备⼀定的要求), 也可以从中央仓库下载Jar包查找Jar的坐标1. 访问https://mvnrepository.com/2. 进⾏查找,⽐如mysql私服私有服务器私服:⼀般由公司团队搭建的私有仓库. 私服属于某个公司,或者某个部⻔, 往往需要⼀定权限.有了私服之后,Maven依赖下载的顺序⼜发⽣了变化当Maven需要下载资源的时候1. 先从本地仓库获取,本地仓库存在,则直接返回2. 如果本地仓库没有,就从私服请求,私服存在该资源,就直接返回3. 如果私服上不存在该资源则从中央仓库下载,中央仓库不存在,就报错了...4. 如果中央仓库中存在,就先缓存在私服上之后再缓存到本地仓库⾥,再为Maven的下载请求提供服务私服是很多⼈在使⽤的,所以只需要第⼀个使⽤者下载⼀次就可以了1.4 SpringBootSpring Boot的诞生是为了简化Spring程序开发的其中SNAPSHOT是不稳定版本可能会发生变化RELEASE版本是稳定版本不能修改只能升级版本三一个简单的项目创建idea创建四Spring Web MVC4.1 什么是Spring Web MVCSpring WebMVC是基于ServletAPI构建的原始Web框架从⼀开始就包含在Spring框架中。它的 正式名称“SpringWebMVC”来⾃其源模块的名称(Spring-webmvc)但它通常被称为Spring MVC.什么是Servlet呢?Servlet 是⼀种实现动态⻚⾯的技术.准确来讲Servlet是⼀套JavaWeb开发的规范或者说是⼀套 Java Web开发的技术标准.只有规范并不能做任何事情必须要有⼈去实现它.所谓实现Servlet规 范就是真正编写代码去实现Servlet规范提到的各种功能包括类、⽅法、属性等. Servlet 规范是开放的除了Sun公司其它公司也可以实现Servlet规范⽬前常⻅的实现了 Servlet 规范的产品包括Tomcat、Weblogic、Jetty、Jboss、WebSphere等它们都被称 为Servlet 容器.Servlet 容器⽤来管理程序员编写的Servlet类.4.1.1 MVC定义MVC是ModelViewController的缩写它是软件工程中的⼀种软件架构设计模式它把软件系统分 为模型、视图和控制器三个基本部分• View(视图)指在应⽤程序中专⻔⽤来与浏览器进⾏交互展⽰数据的资源.• Model(模型)是应⽤程序的主体部分⽤来处理程序中数据逻辑的部分.• Controller控制器可以理解为⼀个分发器⽤来决定对于视图发来的请求需要⽤哪⼀个模型 来处理以及处理完后需要跳回到哪⼀个视图。即⽤来连接视图和模型4.1.2 什么是SpringMVCMVC是⼀种架构设计模式,也是⼀种思想, ⽽SpringMVC是对MVC思想的具体实现.除此之外, Spring MVC还是⼀个Web框架.总结来说SpringMVC是⼀个实现了MVC模式的Web框架.所以,SpringMVC主要关注有两个点:1. MVC2. Web框架SpringMVC 全称是SpringWebMVC4.1.3 应用既然是Web框架那么当用户在浏览器中输入了url之后我们的Spring MVC项目就可以感知到用户的请求并给予响应.学习SpringMVC,重点也就是学习如何通过浏览器和⽤⼾程序进⾏交互主要分以下三个⽅⾯:1. 建⽴连接将⽤⼾浏览器和Java程序连接起来也就是访问⼀个地址能够调⽤到我们的 Spring 程序。2. 请求⽤⼾请求的时候会带⼀些参数在程序中要想办法获取到参数,所以请求这块主要是获取参数的功能.3. 响应执⾏了业务逻辑之后要把程序执⾏的结果返回给⽤⼾,也就是响应项目准备Spring MVC项⽬创建和SpringBoot创建项⽬相同在创建的时候选择SpringWeb就相当于创建了 Spring MVC的项⽬.建立连接在SpringMVC中使用 RequestMapping 来实现URL路由映射也就是浏览器连接程序的作用RequestMapping(/getNum) public Integer getNum(){ return 10; }接下来访问http://127.0.0.1:8080/getNum, 就可以看到程序返回的数据了RequestMapping 是SpringWebMVC应⽤程序中最常被⽤到的注解之⼀它是⽤来注册接⼝的 路由映射的.表⽰服务收到请求时,路径为 /getNum 的请求就会调⽤sayHi这个⽅法的代码路由映射:当⽤⼾访问⼀个URL时,将⽤⼾的请求对应到程序中某个类的某个⽅法的过程就叫路由映射RequestMapping 注解介绍注解添加在类上称之为“类注解”添加在方法上称之为“方法注解”RequestMapping既可以是类注解也可以是方法注解Q : 既然RequestMapping可以达到目的为什么还要加RestControllerA当把RestController去掉的时候会报404因为⼀个项⽬中,会有很多类,每个类可能有很多的⽅法,Spring程序怎么知道要执⾏哪个⽅法呢? Spring会对所有的类进⾏扫描,如果类加了注解RestController,Spring才会去看这个类⾥⾯的⽅法 有没有加 RequestMapping 这个注解RequestMapping使用RequestMapping 既可修饰类也可以修饰⽅法当修饰类和⽅法时访问的地址是类路径⽅ 法路径.RequestMapping标识⼀个类设置映射请求的请求路径的初始信息RequestMapping标识⼀个⽅法设置映射请求请求路径的具体信息RestController RequestMapping(/hello) public class HelloController { RequestMapping(/v2) public Integer getNum(){ return 10; } }访问地址为http://127.0.0.1:8080/hello/v2注意RequestMapping的URL路径最前面加不加 / (斜杠)都可以Spring程序启动时会进行判断,如果前面没有加 / ,Spring会拼接上⼀个 /RequestMapping 的URL路径也可以是多层路径, 最终访问时,依然是类路径⽅法路径RestController RequestMapping(/hello) public class HelloController { RequestMapping(/v2/v3) public Integer getNum(){ return 10; } }注意文件夹有不同的标签之分RequestMapping 是GET还是POST请求GET请求:浏览器发送的请求类型都是get,通过以上案例,可以看出来 RequestMapping ⽀持get请求.POST请求:通过form表单来构造请求:创建test.html, html代码:import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; RestController RequestMapping(/hello) public class HelloController { RequestMapping(/v1) public String hello(){ return test 1; } RequestMapping(v1/v3) public Integer getNum(){ return 10; } }前端代码放在static⽬录下访问⽅式为http://127.0.0.1:8080/test.html从运⾏结果可以看出: RequestMapping 既⽀持Get请求,⼜⽀持Post请求.同理,也⽀持其他的请 求⽅式.指定GET/POST⽅法类型RequestMapping(value /getRequest,method RequestMethod.POST)注解里的数组由此图可得method为数组这个数组和Java定义的数组不太一样。Java定义的数组有{}而注解中的数组如果里面只有一个元素的话是可以省略{}的4.2 Postman的使用1 传递参数Spring会解析收到的参数整理成类Map的结构即key-value其中类型均为string然后会根据后端的参数类型定义转换参数类型1. 普通传参,也就是通过查询字符串来传参2. form-data(完整表⽰为:multipart/form-data)表单提交的数据, 在form标签中加上enctypedmultipart/form-data通常⽤于提交图⽚/⽂件对应Content-Type: multipart/form-data3. x-www-form-urlencodedform表单,对应 Content-Type: application/x-www-from-urlencoded4raw可以上传任意格式的⽂本可以上传text、json、xml、html等4.3 请求访问不同的路径,就是发送不同的请求.在发送请求时,可能会带⼀些参数,所以学习Spring的请求,主要是学习如何传递参数到后端以及后端如何接收.1传递单个参数接收单个参数在Spring MVC中直接用方法中的参数就可以了RestController RequestMapping(/request) public class RequestController { RequestMapping(/r1) public String r1(String name){ return 接收到参数name name; } }注意使用基本类型来接收参数时参数必须传除了Boolean类型否则会报500错误当类型不匹配时会报400错误RequestMapping(/r2) public String r2(int age){ return 接收到参数name age; }通过这个错误日志可知int类型的参数‘age’虽然为可选的但是由于被声明为基本类型而不能转换为空值考虑将其声明为对应基本类型的包装类型对于包装类型如果不传对应参数spring接收到的数据则为null所以对于参数可能为空的数据建议使用包装类型2传递多个参数直接使用方法的参数接收即可RequestMapping(/r3) public String r3(String name,int age){ return 接收到参数age age接收到参数name name; }当有多个参数的时候前后端进行参数匹配时是以参数的名称进行匹配的因此参数的位置不影响后端获取参数的结果3传递对象如果参数比较多方法声明就需要很多形参并且后续每次新增一个参数也需要修改方法声明Spring MVC也可以自动实现对象参数的赋值比如Person对象package com.luoyaoyun.springbootdemo; public class Person { private Integer id; private String name; private int age; private String address; public Integer getId() { return id; } public void setId(Integer id) { this.id id; } public String getName() { return name; } public void setName(String name) { this.name name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age age; } public String getAddress() { return address; } public void setAddress(String address) { this.address address; } Override public String toString() { return Person{ id id , name name \ , age age , address address \ }; } }RequestMapping(/m1) public Object method1(Person p){ return p.toString(); }Spring 会根据参数名称⾃动绑定到对象的各个属性上,如果某个属性未传递,则赋值为null(基本类型则赋值为默认初识值,⽐如int类型的属性,会被赋值为0)4后端参数重命名后端参数映射某些特殊的情况下前端传递的参数key和我们后端接收的key可以不一样比如前端传递了一个time给后端而后端是使用createtime字段来接收的这样就会出现参数接收不到的情况如果出现这种情况我们就可以使用RequestParam来重命名前后端的参数值RequestMapping(/m2) public Object method4(RequestParam(time) String createtime){ return 接收到参数createtime createtime; }可以看到Spring可以正确的把浏览器传递的参数time绑定到后端参数createtime参数上此时如果浏览器使用createtime来进行参数传递就会打印错误信息可以得出结论:1. 使⽤ RequestParam 进⾏参数重命名时, 请求参数只能和RequestParam声明的参数一致才能进⾏参数绑定和赋值.2. 使用RequestParam 进⾏参数重命名时,参数就变成了必传参数.非必传参数设置查看 实现如下 RequestParam 注解的实现细节就可以发现required 的默认值为true,表⽰含义就是该注解修饰的参数默认为必传既然如此,我们可以通过设置 RequestParam 中的requiredfalse 来避免不传递时报错RequestMapping(/r6) public String r6(RequestParam(value wd, required false) String keyword){ return 接收到参数, keyword: keyword; }可以看到,添加requiredfalse之后, time前⾯也加了key,变成了 value time注解属性赋值时,没有指明key的话,默认为value属性.如果需要有多个属性进⾏赋值时,需要写上key5传递数组RequestMapping(/r4) public String r4(String[] arr){ return Arrays.toString(arr); }也有第二种方式6传递集合集合参数和数组类似,同⼀个请求参数名有为多个且需要使用 RequestParam 绑定参数关系默认情况下请求中参数名相同的多个值是封装到数组.如果要封装到集合要使⽤ RequestParam 绑定参数关系RequestMapping(/r5) public String r5(ListString list){ return list.toString(); }如果直接传会报错加上RequestParam就可以正常传参RequestMapping(/r5) public String r5(RequestParam ListString list){ return list.toString(); }但是如果list中是类对象或者别的都不好传参这时候可以传递json数据7传递JSON数据JSONJavaScript Object Notation 【JavaScript 对象表示法】JSON是⼀种轻量级的数据交互格式它基于ECMAScript(欧洲计算机协会制定的js规范)的⼀个子集 采用完全独立于编程语言的文本格式来存储和表示数据简单来说JSON就是⼀种数据格式有自己的格式和语法使用文本表示⼀个对象或数组的信息,因此 JSON本质是字符串. 主要负责在不同的语⾔中数据传递和交换.JSON与Javascript的关系没有关系,只是语法相似,js开发者能更快的上⼿⽽已,但是他的语法本⾝⽐较简单,所以也很好学JSON语法JSON是⼀个字符串其格式非常类似于JavaScript对象字面量的格式{ squadName: Super hero squad, homeTown: Metro City, formed: 2016, secretBase: Super tower, active: true, members: [ { name: Molecule Man, age: 29, secretIdentity: Dan Jukes, powers: [ Radiation resistance, Turning tiny, Radiation \nblast ] }, { name: Madame Uppercut, age: 39, secretIdentity: Jane Wilson, powers: [ Million tonne punch, Damage resistance, Superhuman \nreflexes ] }, { name: Eternal Flame, age: 1000000, secretIdentity: Unknown, powers: [ Immortality, Heat Immunity, Inferno, Teleportation, Interdimensional travel ] } ] }JSON的语法1数据在键值对key/value中2数据由逗号分隔3对象用{}表示4数组用 [] 表示5值可以为对象也可以为数组数组中可以包含多个对象JSON的两种结构1对象大括号{} 保存的对象是一个无序的键值对集合一个对象以左括号{ 开始右括号 } 结束。每个“键”后面跟一个冒号键值对之间使用逗号分隔2数组中括号[] 保存的数组是值value的有序集合一个数组以左中括号 [ 开始右中括号 ] 结束值与值之间使用逗号分隔{name:admin,age:18}, [hello, 3.1415, json], [{name:admin,age:18},{name:root,age:16},{name:\n张三\n,age:20}]JSON字符串和Java对象互转JSON本质上是⼀个字符串通过文本来存储和描述数据Spring MVC框架也集成了JSON的转换⼯具,我们可以直接使⽤,来完成JSON字符串和Java对象的互转public class JacksonTest { public static void main(String[] args) { ObjectMapper objectMapper new ObjectMapper(); Person person new Person(); person.setId(12); person.setAge(18); person.setName(zhangsan); person.setAddress(beijing); //对象转为json字符串 String s objectMapper.writeValueAsString(person); System.out.println(s); //json字符串转为对象 String jsonStr {\address\:\beijing\,\age\:18,\id\:12,\name\:\zhangsan\}; Person person1 objectMapper.readValue(jsonStr, Person.class); System.out.println(person1); } }JSON优点1. 简单易用语法简单易于理解和编写可以快速地进⾏数据交换2. 跨平台⽀持: JSON可以被多种编程语⾔解析和⽣成,可以在不同的平台和语⾔之间进⾏数据交换和 传输3. 轻量级:相较于XML格式,JSON数据格式更加轻量级,传输数据时占⽤带宽较⼩,可以提⾼数据传输 速度4. 易于扩展: JSON的数据结构灵活⽀持嵌套对象和数组等复杂的数据结构便于扩展和使⽤5. 安全性:JSON数据格式是⼀种纯⽂本格式不包含可执⾏代码,不会执⾏恶意代码因此具有较高的安全性传递JSON对象接收JSON对象需要使用RequestBody 注解RequestBody: 请求正文意思是这个注解作用在请求正文的数据绑定请求参数必须在写在请求正文中RequestMapping(/r6) public String r6(RequestBody Person person){ return person.toString(); }8获取URL中参数PathVariablepath variable 路径变量和字⾯表达的意思⼀样这个注解主要作⽤在请求URL路径上的数据绑定默认传递参数写在URL上SpringMVC就可以获取到RequestMapping(/r7/{id}) public String r7(PathVariable Integer id){ return 从url中获取idid; }如果⽅法参数名称和需要绑定的URL中的变量名称⼀致时,可以简写,不⽤给PathVariable的属性赋值,如上述例⼦中的id变量RequestMapping(/r8/{id}/{name}) public String r8(PathVariable(id) Integer userId, PathVariable(name) String userName){ return 从url中获取id:userId ,type: userName; }如果⽅法参数名称和需要绑定的URL中的变量名称不⼀致时,需要PathVariable的属性value赋值, 如上述例⼦中的userName变量.9上传文件RequestPartRequestMapping(/r11) public String r11(RequestPart(file) MultipartFile multipartFile) throws IOException { System.out.println(multipartFile.getOriginalFilename()); //文件上传 File file new File(D:/test/multipartFile.getOriginalFilename()); multipartFile.transferTo(file); return 文件上传成功; }
返回列表