SpringBoot--Web开发篇:含enjoy模板引擎整合,SpringBoot整合springMVC;及上传文件至七牛云;restFul
SpringBoot的Web开发
官网学习:

进入spring官网 --> projects --> SpringBoot --> LEARN --> Reference Doc. --> Web --> 就能看到上述页面
静态资源映射规则
官方文档

-
总结:
只要是静态资源,放在类路径下:called
/static(or
/publicor/resourcesor/META-INF/resources) -
访问:当前项目根路径/+静态资源名称
-
静态资源访问前缀修改
spring:mvc:static-path-pattern: /dong/** #添加此配置,所有静态资源的访问路径就需要添加一级路径/dong
一般来说,创建好SpringBoot项目之后,resources路径下会有一个static目录,css,js,图片,视频,音频都需要存放在此目录下
enjoy模板引擎
SpringBoot整合enjoy模板引擎步骤:
-
将页面保存在templates目录下
-
添加enjoy的坐标
<dependency><groupId>com.jfinal</groupId><artifactId>enjoy</artifactId><version>5.0.3</version> </dependency> -
开启配置(配置类)
在启动类同级新建config包,包下新建EnjoyConfig类(不需要自己写,JFinal官网有)
import com.jfinal.template.Engine; import com.jfinal.template.ext.spring.JFinalViewResolver; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;@Configuration public class SpringBootConfig {@Bean(name = "jfinalViewResolver")public JFinalViewResolver getJFinalViewResolver() {// 创建用于整合 spring boot 的 ViewResolver 扩展对象JFinalViewResolver jfr = new JFinalViewResolver();// 对 spring boot 进行配置jfr.setSuffix(".html");jfr.setContentType("text/html;charset=UTF-8");jfr.setOrder(0);// 设置在模板中可通过 #(session.value) 访问 session 中的数据jfr.setSessionInView(true);// 获取 engine 对象,对 enjoy 模板引擎进行配置,配置方式与前面章节完全一样Engine engine = JFinalViewResolver.engine;// 热加载配置能对后续配置产生影响,需要放在最前面engine.setDevMode(true);// 使用 ClassPathSourceFactory 从 class path 与 jar 包中加载模板文件engine.setToClassPathSourceFactory();// 在使用 ClassPathSourceFactory 时要使用 setBaseTemplatePath// 代替 jfr.setPrefix("/view/")engine.setBaseTemplatePath("/templates/");// 更多配置与前面章节完全一样// engine.addDirective(...)// engine.addSharedMethod(...);return jfr;} }唯一需要改动的地方:engine.setBaseTemplatePath(“/templates/”);
填写页面目录:/templates/
-
编写代码
Spring MVC请求处理
常用五种请求处理方式注解:
@RequestMapping
可以点击查看源码
-
意义:处理用户的请求,相似于doget与dopost
-
位置:
类上:一级目录
方法:二级目录
例如:user/save
user/delete
student/save
student/delete
-
属性:
-
value = " " ,path= " " :表示请求路径
eg:@RequestMapping(value=“/show”)或@RequestMapping(path=“/show”)
也可以省略:@RequestMapping(“/show”)
-
method=常量:此请求的类型(get,post),若不设置则此请求适配所有的请求方式
eg:@RequestMapping(value=“/show”,method={RequestMethod.POST})
必须用post请求才能请求到此路径
-
params = " ":限制请求参数,例如:params={“msg1”,“msg2”}表示请求路径中必须携带参数名为msg1与msg2的参数
注意:1.超链接默认发送的是get请求
2.所有请求所携带的参数格式均为:key = value
eg:@RequestMapping(value=“/show”,params = {“msg1=aa”,“msg2=bb”})
请求必须携带参数msg1和msg2,且msg1的值必须是aa,msg2的值必须是bb才能访问
-
@DeleteMapping 删除
@PutMapping 修改
@GetMapping 查询
@PostMapping 新增
@Target({ElementType.METHOD, ElementType.TYPE})
METHOD==代表修饰方法,TYPE==代表修饰类
Postman测试工具
在没有页面表单的情况下,Postman可以模拟浏览器请求方式进行测试
Postman官网,下载注册登录即可使用
Spring MVC参数绑定
Spring MVC请求参数绑定机制:
SpringMVC 绑定请求参数的过程是通过把表单提交请求参数,作为控制器中方法参数进行绑定的
-
支持的数据类型:
-
基本类型参数:基本数据类型和String类型
-
POJO类型参数:实体类,以及关联的实体类
-
数组和集合类型参数:包括 List 结构和 Map 结构的集合(包括数组)
-
使用:ServletAPI 对象作为方法参数
HttpServletRequest、HttpServletResponse、HttpSession、java.security.Principal、Locale、InputStream、OutputStream、Reader、Writer
-
-
使用要求:
- 发送请求中携带数据的key与方法参数的name必须一致
- 数据类型合法
总结:
- 参数从页面传递过来时,名字必须和接收的参数相同
- 参数的数据类型必须合法
- 不同类型的数据演示如下
演示,步骤:
-
创建SpringBoot项目,并导入enjoy坐标
-
添加配置类
-
templates目录下的页面
one.html
<!DOCTYPE html> <html lang="cn" xmlns:th="http://www.thymeleaf.org"> <head><title>Title</title> </head> <body><h1>springMVC控制器方法参数作用:接受用户请求中的数据</h1><hr/><h3>基本类型和 String 类型作为参数</h3><a href="/one/show1?msg1=9527">发送请求1</a><a href="/one/show2?msg1=jdk&msg2=9527">发送请求2</a><h3>POJO 类型作为参数</h3><a href="/one/show3?eid=1&ename=郭凡&esex=小奶狗">发送请求3</a><form action="/one/show4" method="post">员工编号:<input type="text" name="eid" ><br/>员工姓名:<input type="text" name="ename" ><br/>员工性别:<input type="text" name="esex" ><br/>部门编号:<input type="text" name="dept.did" ><br/>部门名称:<input type="text" name="dept.dname" ><br/><input type="submit" value="发送请求4"/></form><form action="/one/map" method="post">员工编号:<input type="text" name="eids"><br/>员工姓名:<input type="text" name="enames"><br/>员工性别:<input type="text" name="esexs"><br/><input type="submit" value="发送请求4(map)"/></form><h3>POJO 类中包含集合类型参数</h3><form action="/one/show5" method="post">部门编号:<input type="text" name="did" ><br/>部门名称:<input type="text" name="dname" ><br/>员工编号1:<input type="text" name="mylist[0].eid" ><br/>员工姓名1:<input type="text" name="mylist[0].ename" ><br/>员工性别1:<input type="text" name="mylist[0].esex" ><br/>员工编号2:<input type="text" name="mylist[1].eid" ><br/>员工姓名2:<input type="text" name="mylist[1].ename" ><br/>员工性别2:<input type="text" name="mylist[1].esex" ><br/>员工编号3:<input type="text" name="myMap['one'].eid" ><br/>员工姓名3:<input type="text" name="myMap['one'].ename" ><br/>员工性别3:<input type="text" name="myMap['one'].esex" ><br/>员工编号4:<input type="text" name="myMap['two'].eid" ><br/>员工姓名4:<input type="text" name="myMap['two'].ename" ><br/>员工性别4:<input type="text" name="myMap['two'].esex" ><br/><input type="submit" value="发送请求5"/></form><a href="/one/show6?nums=123&nums=456&nums=789">发送请求6</a><h3>使用 ServletAPI 对象作为方法参数</h3><a href="/one/show7">发送请求7</a></body> </html>success.html 访问成功页面
<!DOCTYPE html> <head><meta charset="UTF-8"><title>Title</title> </head> <body><h1>spring成功页面</h1> </body> </html> -
创建POJO类:
Emp
public class Emp implements Serializable {private int eid;private String ename;private String esex;/*依赖对象Dep*/private Dep dept;//get、set、toString()方法 }Dep
public class Dep {private int did;private String dname;//集合类型的参数private List<Emp> mylist;private Map<String,Emp> myMap;//get、set、toString()方法 } -
控制器
@Controller @RequestMapping("one") public class UserController {@RequestMapping(path = "/show")public String show(){return "one";}// 一个参数,页面传过来参也得是msg1,且数据合法@RequestMapping(path = "/show1")public String show1(int msg1){System.out.println("show1-->msg1的参为:"+msg1);return "success";}// 两个参,页面要传递msg1,msg2@RequestMapping(path = "/show2")public String show2(String msg1,int msg2){System.out.println("show2-->msg1==="+msg1+"msg2==="+msg2);return "success";}// 页面传递时参数必须按照Emp实体类中属性的顺序进行传递@RequestMapping(path = "/show3")public String show3(Emp emp){System.out.println("show3-->对象参数emp:"+emp.toString());return "success";}// 对象中嵌套了一个对象,被嵌套的对象也需要按实体类中顺序传递@PostMapping(path = "/show4")public String show4(Emp emp){System.out.println("show4-->对象参数嵌套emp"+emp.toString());return "success";}// map接收数据必须要加@RequestParam注解@PostMapping(path = "/map")public String map(@RequestParam Map map){System.out.println(map);return "success";}// Dep实体类中有List和Map类型的数据类型,用Dep类型接收@RequestMapping("/show5")public String show5(Dep dept){System.out.println("show5-->dept==="+dept);return "success";}// 接收数组类型,页面传参:nums=1&nums=2$nums=3,多用于复选框@RequestMapping("/show6")public String show6(int[] nums){System.out.println("show6-->int[] 数组:"+ Arrays.toString(nums));return "success";}// 请求和响应的接收@RequestMapping("/show7")public String show7(HttpServletRequest request, HttpServletResponse response){System.out.println(request);System.out.println(response);request.getParameter("msg1");HttpSession session = request.getSession();System.out.println(session);session.setAttribute("","");try {response.sendRedirect("重定向");} catch (IOException e) {e.printStackTrace();}ServletContext servletContext = session.getServletContext();return "success";}} -
启动项目,浏览器访问localhost:8080/one/show,点击按钮超链接控制台即可打印传参
Spring MVC常用注释
@RequestParam
-
作用:
把请求中指定名称的参数给控制器中的形参赋值。
如果页面标签名称和方法参数名称不一致,可以使用此注解实现
-
属性:
name属性:设置参数名称
defaultValue属性:设置默认值
required属性:设置是否为必传
-
@RequestParam(“名称必须与页面标签或者url地址key名称一致”)
@RequestMapping("/show1")
public String show1(@RequestParam(name="msg1") String msg){System.out.println("=====接受到用户发送数据为:"+msg+"=======");return "success";
}
获取请求中的参数msg1赋值给msg
@RequestMapping("/show2")
public String show2(@RequestParam("msg1") String msg, @RequestParam("msg2") int num){System.out.println("=====接受到用户发送数据为:"+msg+"=======");System.out.println("=====接受到用户发送数据为:"+num+"=======");return "success";
}
获取请求中的参数msg1赋值给msg,参数msg2赋值给num
@RequestMapping("/show3")
public String show4(@RequestParam(name = "uname",defaultValue = "暂无用户") String name){System.out.println("账号:"+name);return "success";
}
获取请求中的参数uname赋值给name,若uname为null,name则为:暂无用户
@RequestMapping("/show3")
public String show4(@RequestParam(name = "uname",required = false) String name){System.out.println("账号:"+name);return "success";
}
获取请求中的参数uname赋值给name,required=fales,uname是非必传参数
@RequestBody
-
作用:
用于获取"请求体"内容。直接使用得到是 key=value&key=value…
结构的数据,并可以转换为对象
-
属性:
required:是否必须有请求体。默认值是:true。
-
@RequestBody一般用于前后端分离,@RequestBody可以将json ----> javaBean
注意:前端不能使用GET方式提交数据,GET方式无请求体
/*从请求获取到JSON格式*/
@RequestMapping("/show4")public String show4(@RequestBody Emp emp){System.out.println("=========="+emp+"==========");return "success";
}
Postman模拟请求:

控制器获取请求中的Json格式将Json转换为Emp实体类
@PathVaribale
-
作用:
用于绑定 url 中的占位符。例如:请求 url 中 /delete/{id},这个{id}就是 url 占位符。url 支持占位符是 spring3.0 之后加入的。是 springmvc 支持 rest 风格 URL 的一个重要标志
-
属性:
value:用于指定url中占位符的名称
required:是否必须提供占位符。
-
Restful:
是一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件
主要用于客户端和服务器交互类的软件,基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存机制等。
eg:localhost:8080/one/show/{uname}/{pwd}
Restful风格的请求是使用“url+请求方式”表示一次请求目的的,HTTP 协议里面四个表示操作方式的动词如下:
- GET:用于获取资源
- POST:用于新建资源
- PUT:用于更新资源
- DELETE:用于删除资源
例如:
/users/1 GET : 得到 id = 1 的 user
/users/1 DELETE: 删除 id = 1 的 user
/users/1/新名/新性 PUT: 更新 id = 1 的 user
/users/新名/新性 POST: 新增 user
@PostMapping("/show5/{uname}/{pwd}")
public String show5(@PathVariable("uname") String msg1, @PathVariable("pwd") String msg2){System.out.println(msg1);System.out.println(msg2);return "success";
}
url:localhost/one/show5/tom/123456,请求url中携带数据占位符{uname}位置的值为tom,占位符{pwd}位置的值为123456,将uname值赋给msg1,pwd值赋给msg2
@PostMapping("/show6/{uname}/{pwd}")
public String show6(@PathVariable String uname, @PathVariable String pwd){System.out.println(uname);System.out.println(pwd);return "success";
}
url:localhost/one/show5/tom/123456,当方法中的参数和占位符的名称相同时,只需要写注解@PathVariable,不需要再写value
@RequestHeader
-
作用:
用于获取请求消息头。
-
属性:
value:提供消息头名称
required:是否必须有此消息头
-
只获取头信息中的Accept-Language对应的数据
@RequestMapping("/show1")
public String show1(@RequestHeader(value = "msg1")String msg){System.out.println(msg);return "test";
}

获取Headers中的信息:msg1赋值给msg
@CookieValue
-
作用:
用于把指定 cookie 名称的值传入控制器方法参数
-
属性:
value:指定 cookie 的名称
required:是否必须有此 cookie
@RequestMapping("/show2")
public String show2(@CookieValue(value = "JSESSIONID",required = false)String jsessionid){System.out.println(jsessionid);return "test";
}
浏览器中请求url:localhost:8080/show2,获取Cookie中的JSESSIONID赋值给jseesionid
第一次访问时,jsessionid为null
第二次访问起,jsessionid有值
Spring MVC数据传递
String
返回值为页面名称
@RequestMapping("/show1")
public String show1(){System.out.println("=========show1=========");return "success_String";
}
充当视图的逻辑名称,默认页面跳转为请求转发方式
redirect:show1
@RequestMapping("/show2")
public String show2(){System.out.println("=========show2=========");return "redirect:show1";
}
redirect:重定向到show1
forward:show1
@RequestMapping("/show3")
public String show3(){System.out.println("=========show3=========");return "forward:show1";
}
forward:转发到show1
session存储参数
@RequestMapping("/show4")
public String show4(HttpServletRequest request){System.out.println("=========show4=========");//1.查询数据库(模拟)Emp emp = new Emp(1,"张毅老师","男");//2.获取sessionrequest.getSession().setAttribute("emp",emp);return "success_String";
}
Json
返回值为Json字符串,主要用于前后端分离
@ResponseBody
-
作用:
对象====>json
-
位置:
- 类
- 方法
@RequestMapping("/show1")
@ResponseBody
public List<Emp> show1(){//1模拟数据库Emp emp1 = new Emp(1,"张三","男");Emp emp2 = new Emp(2,"李四","男");Emp emp3 = new Emp(3,"王五","男");List<Emp> list = new ArrayList<>();list.add(emp1);list.add(emp2);list.add(emp3);return list;
}
页面显示一个json格式的字符串
@RequestBody
-
作用:
json====>对象
-
位置:
方法参数
@RequestMapping("/show2")
@ResponseBody
public String show2(){return "helloWorld";
}
页面显示字符串“helloworld”
@RestController=@Controller + @ResponseBody
若添加了@RestController注解的类,类不需要写@Controller、返回Json的方法也不需要写@ResponseBody
Spring MVC上传文件
上传文件可以存储在本地物理磁盘,但存储磁盘占用内存,成本高,开销大,不建议
还可以上传到云服务器进行存储,采用技术为:七牛云
七牛云
七牛云官网
-
注册账号,完成实名制
-
点击左侧三个横杠,对象存储Kodo,创建一个仓库

-
填写信息

存储空间名称:按要求起名字
存储区域:选择地理位置近的
访问控制:选择公开
上传文件至七牛云
-
创建SpringBoot Web项目
-
pom文件导坐标
除web启动器和test启动器外,还需要导入enjoy、七牛云、上传文件的坐标
<!--enjoy--> <dependency><groupId>com.jfinal</groupId><artifactId>enjoy</artifactId><version>5.0.3</version> </dependency><!--七牛云所需坐标--> <dependency><groupId>com.qiniu</groupId><artifactId>qiniu-java-sdk</artifactId><version>7.2.25</version> </dependency> <dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId><version>3.14.2</version><scope>compile</scope> </dependency> <dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.8.5</version><scope>compile</scope> </dependency> <dependency><groupId>com.qiniu</groupId><artifactId>happy-dns-java</artifactId><version>0.1.6</version><scope>test</scope> </dependency><!--文件上传--> <dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.6</version> </dependency><dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.3.3</version> </dependency> -
添加enjoy模板配置类,此处省略
-
页面,存放在resources下的templates目录
index.html
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>文件上传</title> </head> <body>文件上传:<ol><li>坐标</li><li>制作页面-form表单编码</li><li>通过*****接受文件</li></ol><hr/><form action="fileupload" method="post" enctype="multipart/form-data">用户名:<input name="uname"/><br/>图片:<input name="upic" type="file"/><br/><input type="submit" value="上传"/></form> </body> </html>success.html
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>文件上传</title> </head> <body><h1>成功页面</h1><div><img src="http://s3e0wu5bp.hb-bkt.clouddn.com/#(session.picname)"></div> </body> </html>img标签的src拼接路径是七牛云空间的外链域名+文件名

-
控制器
@Controller public class OneController {//进入测试页面@RequestMapping("/show")public String show(){return "index";}//文件上传@RequestMapping("/fileupload")public String fileupload(String uname, MultipartFile upic, HttpServletRequest request){System.out.println("用户名:"+uname);System.out.println(upic);System.out.println(upic.getOriginalFilename());System.out.println(upic.getName());//方式1.将文件upic以流的方式写入当前服务器磁盘(应用服务器)//方式2.文件服务器(七牛云)//构造一个带指定 Region 对象的配置类Configuration cfg = new Configuration(Region.autoRegion());//...其他参数参考类注释UploadManager uploadManager = new UploadManager(cfg);//...生成上传凭证,然后准备上传String accessKey = "iUMJ8ouFFclMTRnz6Us-aZzbP1qoYa4W2-LQL4pk";String secretKey = "YeSnxdjbjs2DSGuKNIXqH2uva-HGwWcqGdVpWAJi";String bucket = "programmerdong";//默认不指定key的情况下,以文件内容的hash值作为文件名String key = null;String name = null;try {byte[] uploadBytes = upic.getBytes();Auth auth = Auth.create(accessKey, secretKey);String upToken = auth.uploadToken(bucket);try {Response response = uploadManager.put(uploadBytes, key, upToken);//解析上传成功的结果DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);System.out.println(putRet.key);//获取文件名System.out.println(putRet.hash);//获取文件hash值name = putRet.key;} catch (QiniuException ex) {Response r = ex.response;System.err.println(r.toString());try {System.err.println(r.bodyString());} catch (QiniuException ex2) {//ignore}}} catch (Exception ex) {//ignore}request.getSession().setAttribute("picname",name);return "success";} }-
accessKey:七牛云控制台密钥管理,AK
-
secretKey:七牛云控制台密钥管理,SK

-
bucket:自己起的仓库名
-
上传文件的代码不需要自己写,七牛云官方文档中拷贝过来稍作修改即可
右上角导航:文档 -->开发者中心 -->下拉到最后 -->对象存储快速入口 -->SDk下载–>选择语言查看文档
-
注册Servlet三大组件
三大组件:Servlet、Filter、Listener
方式一注解
pom.xml坐标
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies>
-
@WebServlet:注入Servlet
@WebServlet("/myservlet") public class MyServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("进入servlet");resp.getWriter().println("<h1>Hello Servlet</h1>");}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doGet(req, resp);} } -
@WebFilter:注入Filter
@WebFilter(urlPatterns = {"/*"}) public class MyFilter implements Filter {public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {System.out.println("============请求过滤");request.setCharacterEncoding("utf-8");//分水岭chain.doFilter(request, response);response.setCharacterEncoding("utf-8");System.out.println("============响应过滤");} } -
@WebListener:注入Listener
@WebListener public class MyListener implements ServletContextListener {@Overridepublic void contextInitialized(ServletContextEvent sce) {System.out.println("ServletContext创建");}@Overridepublic void contextDestroyed(ServletContextEvent sce) {System.out.println("ServletContext销毁");} } -
程序主启动器还需要添加注解@ServletComponentScan
@SpringBootApplication @ServletComponentScan public class SpringbootWeb06Application {public static void main(String[] args) {SpringApplication.run(SpringbootWeb06Application.class, args);} }
测试:浏览器访问结果
方式二配置类
pom.xml文件与方式一相同,存在springboot web环境就可以
配置类的方式不需要再写各自的注解:
-
ServletRegistrationBean:注册自定义Servlet
-
FilterRegistrationBean:注册自定义Filter
-
ServletListenerRegistrationBean:注册自定义Listener
-
配置类:
@Configuration public class MyConfig {//注册Servlet//替换:@WebServlet(urlPatterns = "/myServlet")@Beanpublic ServletRegistrationBean doServlet() {ServletRegistrationBean<MyServlet> bean = new ServletRegistrationBean<MyServlet>();bean.setServlet(new MyServlet());bean.setUrlMappings(Arrays.asList("/servlet"));bean.setLoadOnStartup(1);return bean;}//注册Filter@Beanpublic FilterRegistrationBean doFilter(){FilterRegistrationBean filter = new FilterRegistrationBean();filter.setFilter(new MyFilter());filter.addUrlPatterns("/*");return filter;}//注册Listener@Beanpublic ServletListenerRegistrationBean doListener(){//关闭监听器切记不要直接点击红色按钮,太暴力,点击控制台左侧existServletListenerRegistrationBean listener = new ServletListenerRegistrationBean();listener.setListener(new MyListener());return listener;} } -
Servlet、Filter、Listener和方式一中相同,注解去掉
-
程序的主启动器不需要再添加格外注解
-
测试结果与方式一相同
切换为其他嵌入式Servlet容器
SpringBoot 默认针对Servlet容器提供以下支持:
- Tomcat(默认使用)
- Jetty :支持长连接项目(如:聊天页面)[ˈdʒeti]
- Undertow : 不支持 JSP , 但是并发性能高,是高性能非阻塞的容器[ˈʌndətəʊ]
-
默认Tomcat容器
<!--在spring-boot-starter-web启动器中默认引入了tomcat容器--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId><version>2.1.0.RELEASE</version><scope>compile</scope> </dependency> -
切换Jetty容器
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><!-- 排除tomcat容器 --><exclusions><exclusion><artifactId>spring-boot-starter-tomcat</artifactId><groupId>org.springframework.boot</groupId></exclusion></exclusions> </dependency> <!--引入其他的Servlet容器--> <dependency><artifactId>spring-boot-starter-jetty</artifactId><groupId>org.springframework.boot</groupId> </dependency>切换Jetty容器首先需要将tomcat移除,在引入其他容器
-
使用外置Servlet容器omcat9.x
嵌入式Servlet容器:运行启动类就可启动,或将项目打成可执行的 jar 包
优点:简单、快捷;
缺点:默认不支持JSP、优化定制比较复杂使用定制器,
还需要知道每个功能的底层原理
外置Servlet容器:配置 Tomcat, 将项目部署到Tomcat中运行
restFul
REST 指的是一组架构约束条件和原则,rest原则有部分组成: URL定位资源,HTTP动词操作(GET,POST, PUT,DELETE) 描述操作。
满足这些约束条件和原则的应用程序或设计就是 RESTful。
设计RESTful风格的API:
-
在RESTful风格的架构中, 每个网址代表一种资源,所以网址中不能有动词,只能有名词。而且所用的名词往往与数据库的表名对应
-
HTTP动词设计: GET (获取资源) POST (新建资源) PUT (更新资源,客户端提供改变后的完整资源)DELETE (删除资源)
请求方式 含义
GET /zoos 列出所有动物园
POST /zoos 新建一个动物园
GET /zoos/ID 获取某个指定动物园的信息
在spring-boot-starter-web 启动器中默认引入了tomcat容器
PUT /zoos/ID 更新某个指定动物园的信息(提供该动物园的全部信息)
DELETE /zoos/ID 删除某个动物园
GET /zoos/lD/animals 列出某个指定动物园的所有动物
DELETE /zoos/lD/animals/ID 删除某个指定动物园的指定动物
相关文章:
SpringBoot--Web开发篇:含enjoy模板引擎整合,SpringBoot整合springMVC;及上传文件至七牛云;restFul
SpringBoot的Web开发 官网学习: 进入spring官网 --> projects --> SpringBoot --> LEARN --> Reference Doc. --> Web --> 就能看到上述页面 静态资源映射规则 官方文档 总结: 只要是静态资源,放在类路径下࿱…...
线上JAVA应用平稳运行一段时间后出现JVM崩溃问题 | 京东云技术团队
一、问题是怎么发现的 系统是一个定时任务系统,需要定时执行业务代码,业务代码主要是访问MYSQL数据库和缓存进行操作,该开始启动,系统日志一切正常,但是运行一段时间到凌晨后,系统就自动崩溃了,…...
进口跨境商城源码:高效、安全、可扩展的电商平台解决方案
电子商务的兴起为跨境贸易提供了前所未有的机会和挑战。在这个全球化的时代,跨境电商平台成为许多企业进军国际市场的首选。然而,搭建一个高效、安全、可扩展的进口跨境商城并非易事。 1. 解决方案概述 我们推出的 "进口跨境商城源码" 提供了一…...
GEE数据集——2019、2020、2021、2022和2023年全球固定宽带和移动(蜂窝)网络性能Shapefile 格式数据集
全球固定宽带和移动(蜂窝)网络性能 全球固定宽带和移动(蜂窝)网络性能,分配给缩放级别 16 网络墨卡托图块(赤道处约 610.8 米 x 610.8 米)。数据以 Shapefile 格式和 Apache Parquet 格式提供&…...
什么是防火墙?详解三种常见的防火墙及各自的优缺点
目录 防火墙的定义 防火墙的功能 防火墙的特性 防火墙的必要性 防火墙的优点 防火墙的局限性 防火墙的分类 分组过滤防火墙 优点: 缺点: 应用代理防火墙 优点 缺点 状态检测防火墙 优点 缺点 防火墙的定义 防火墙的本义原是指古代人们…...
动态规划算法实现0-1背包问题Java语言实现
问题介绍: 动态规划算法: 动态规划(Dynamic Programming)是一种解决多阶段决策问题的优化算法。它通过将问题分解为一系列子问题,并利用子问题的解来构建更大规模问题的解,从而实现对整个问题的求解。 动态…...
linux查看系统版本
linux主机 hostnamectl -- 可以查看 “系统架构”,“发行版本”和“内核版本”等信息 uname -a -- 查看内核版本 cat /proc/version -- 查看当前操作系统版本信息 cat /etc/issue ,lsb_release -a(ubuntu)-- 查看…...
pg14-sql基础(四)-多表联查
多表联查 内联查询 SELECT e.department_id, e.first_name, d.department_name FROM employees e INNER JOIN departments d -- JOIN departments d ON e.department_id d.department_id;左外联查询 SELECT e.department_id, e.first_name, d.department_name FROM employees…...
el-date-picker 日期时间选择器 限时时间范围 精确到时分秒
官方的disabledDate属性:设置禁用状态,参数为当前日期,要求返回 Boolean,它只能禁用日期,对于时间并不能直接禁用,总结以下两个方法解决禁用时间: 1.通过watch去监听源数据: 1.1 组…...
轮廓线dp:GYM103446C
https://vjudge.net/contest/591700#problem/H 考虑轮廓线dp,当我们枚举到蓝色格子的时候,我们记录红色格子的状态 每个格子有4种状态 0有向下1需要向上2不用管3需向右 每次枚举的时候,我们需要考虑这个格子的三种状态: 10不放…...
羊驼免疫制备纳米抗体
纳米抗体(nanobodies,Nbs)是由比利时科学家Hamers等人在骆驼血液内首次发现的一种新型抗体,与传统抗体相比,这种抗体不存在轻链,只有重链抗体(HcAb)和两个常规的CH2和CH3区组成&…...
【AI好好玩02】利用Lama Cleaner本地实现AIGC试玩:擦除对象、替换对象、更换风格等等
目录 一、安装二、擦除功能1. LaMa模型实操实例一:去除路人实操实例二:去水印实操实例三:老照片修复 2. LDM模型3. ZITS模型4. MAT模型5. FcF模型6. Manga模型 三、替换对象功能1. sd1.52. sd23. anything44. realisticVision1.45. 四个模型的…...
SQL FULL OUTER JOIN 关键字(完整外部连接)||SQL自连接 Self JOIN
SQL FULL OUTER JOIN 关键字 当左(表1)或右(表2)表记录匹配时,FULL OUTER JOIN关键字将返回所有记录。 注意: FULL OUTER JOIN可能会返回非常大的结果集! SQL FULL OUTER JOIN 语法 SELECT …...
专科医院污水处理设备构造解析及工艺流程
诸城市鑫淼环保小编带大家了解一下专科医院污水处理设备构造解析及工艺流程 主要组成部分: 1.预处理单元 处理流程的起点是预处理单元,用于去除废水中的大颗粒物质和固体废物。这一阶段通常包括隔栅和筛网,以确保进一步处理的污水清洁。 2.生…...
【RabbitMQ】RabbitMQ 消息的可靠性 —— 生产者和消费者消息的确认,消息的持久化以及消费失败的重试机制
文章目录 前言:消息的可靠性问题一、生产者消息的确认1.1 生产者确认机制1.2 实现生产者消息的确认1.3 验证生产者消息的确认 二、消息的持久化2.1 演示消息的丢失2.2 声明持久化的交换机和队列2.3 发送持久化的消息 三、消费者消息的确认3.1 配置消费者消息确认3.2…...
百万套行泊一体量产定点,中国市场「开启」智驾高低速集成
进入2023年,席卷中国市场的行泊一体概念方案进入定点、量产交付的第一波高峰期。这套方案,以高性价比、硬件复用、高低速智驾集成的模式,备受市场青睐。 本周,纵目科技宣布,Amphiman3000行泊一体产品获得长安汽车旗下…...
Gopro hero5运动相机格式化后恢复案例
Gopro运动相机以稳定著称,旗下的Hero系列销售全球。下面我们来看一个Hero5格式化后拍了少量素材的恢复案例。 故障存储:64G MicroSD卡 Exfat文件系统 故障现象: 64G的卡没备份数据时做了格式化操作又拍了一条,发现数据没有备份,客户自行使…...
Microsoft Dynamics 365 CE 扩展定制 - 6. 增强代码
在本章中,我们将介绍以下内容: 使用三层模式重构插件用QueryExpressions替换LINQ数据访问层记录自定义项中的错误将插件转换为自定义工作流活动单元测试插件业务逻辑使用内存上下文对插件进行单元测试端到端集成测试插件分析插件构建通用读取审核插件利用CRM Online实现跨来源…...
基于libopenh264 codec的svc分层流实现方案
OpenH264 http://www.openh264.org/ 是标准的H.264 encoder/decoder. ffmpeg已经集成libopenh264,但不支持svc特性。 openh264 encoder支持svc特性: 1. 时域4层:Temporal scalability up to 4 layers in a dyadic hierarchy 2. 空域4层&#…...
为机器学习算法准备数据(Machine Learning 研习之八)
本文还是同样建立在前两篇的基础之上的! 属性组合实验 希望前面的部分能让您了解探索数据并获得洞察力的几种方法。您发现了一些数据怪癖,您可能希望在将数据提供给机器学习算法之前对其进行清理,并且发现了属性之间有趣的相关性,…...
网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...
盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...
【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...
【Java学习笔记】BigInteger 和 BigDecimal 类
BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点:传参类型必须是类对象 一、BigInteger 1. 作用:适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
安卓基础(Java 和 Gradle 版本)
1. 设置项目的 JDK 版本 方法1:通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分,设置 Gradle JDK 方法2:通过 Settings File → Settings... (或 CtrlAltS)…...
【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅
目录 前言 操作系统与驱动程序 是什么,为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中,我们在使用电子设备时,我们所输入执行的每一条指令最终大多都会作用到硬件上,比如下载一款软件最终会下载到硬盘上&am…...
