
本文为SpringBoot Web开发相关内容介绍,下边将对静态资源管理(包括:静态资源访问,静态资源前缀,webjar,首页支持),请求参数处理(包括:Rest风格,参数注释),数据响应,模板引擎(包括:Thymeleaf模板引擎,基本语法,thymeleaf使用),登录功能 + 拦截器,异常处理等进行详尽介绍~
📌博主主页:小新要变强 的主页
👉Java全栈学习路线可参考:【Java全栈学习路线】最全的Java学习路线及知识清单,Java自学方向指引,内含最全Java全栈学习技术清单~
👉算法刷题路线可参考:算法刷题路线总结与相关资料分享,内含最详尽的算法刷题路线指南及相关资料分享~
👉Java微服务开源项目可参考:企业级Java微服务开源项目(开源框架,用于学习、毕设、公司项目、私活等,减少开发工作,让您只关注业务!)
SpringBoot Web开发

默认情况下,Spring Boot 从类路径中的/static (或/public 或/resources 或/META-INF/resources)目录或 ServletContext的根目录提供静态内容。
访问: 当前项目根路径/ + 静态资源名
原理: 静态映射/**。
请求进来,先去找Controller看能不能处理。不能处理的所有请求又都交给静态资源处理器。静态资源也找不到则响应404页面
我们添加图片到resource下的static里:

请求进来,先去找Controller看能不能处理。不能处理的所有请求又都交给静态资源处理器。静态资源也找不到则响应404页面
可以添加访问静态资源前缘:
spring:
mvc:
static-path-pattern: /res/**
现在访问就是: 当前项目根路径 + /res + 静态资源名
webjar官网:https://www.webjars.org/
webJars是可以让大家以jar包的形式来使用前端的各种框架、组件。例如,引用jquery。
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.6.1</version>
</dependency>

访问路径:当前项目根路径/ + webjars/**

spring:
resources:
static-locations: [classpath:/haha/]
RESTFUL是一种网络应用程序的设计风格和开发方式。
对比:
| 功能 | 传统请求 | Rest风格 |
|---|---|---|
| 获取用户 | /user/getUser (GET请求) | /user (GET请求) |
| 保存用户 | /user/saveUse (POST请求) | /user (POST请求) |
| 修改用户 | /user/editUser (POST请求) | /user (PUT请求) |
| 删除用户 | /user/deleteUser(POST请求) | /user (DELETE请求) |
springboot用法:表单method=post,隐藏域 _method=put。
(1)开启页面表单的Rest功能
spring:
mvc:
hiddenmethod:
filter:
# 开启页面表单的Rest功能
enabled: true
(2)添加页面请求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<script src="/webjars/jquery/3.6.1/jquery.js"></script>
<body>
<h1>首页</h1>
<button id="getUser">获取用户</button>
<button id="saveUser">保存用户</button>
<button id="editUser">修改用户</button>
<button id="deleteUser">删除用户</button>
<p id="msg"></p>
<script>
$("#getUser").on("click",()=>{
$.get("/user",(res)=>{
$("#msg").text(res);
})
});
$("#saveUser").on("click",()=>{
sendAjax(null);
});
$("#editUser").on("click",()=>{
sendAjax('PUT');
});
$("#deleteUser").on("click",()=>{
sendAjax("DELETE");
});
function sendAjax(type){
let data = {'_method':type}
$.post("/user",data,(res)=>{
$("#msg").text(res);
})
}
</script>
</body>
</html>
(3)添加后端接口
// 组合注解,@Controller + RequestBody
@RestController
@RequestMapping("/user")
public class UserController {
// 普通写法
// @RequestMapping(value = "/user",method = RequestMethod.GET)
// 精简写法
@GetMapping
public String getUser(){
return "get user";
}
@PostMapping
public String saveUser(){
return "post user";
}
@PutMapping
public String editUser(){
return "put user";
}
@DeleteMapping
public String deleteUser(){
return "delete user";
}
}
为什么明明请求方式是POST,会跑到别的接口。

如果请求方式是直接发送Put、delete等方式请求,无需Filter。
扩展:_method的值可以自定义,只需要重新实现过滤器方法即可。
//自定义filter
@Bean
public HiddenHttpMethodFilter hiddenHttpMethodFilter(){
HiddenHttpMethodFilter methodFilter = new HiddenHttpMethodFilter();
methodFilter.setMethodParam("_m");
return methodFilter;
}
@PathVariable:从请求路径上获取参数@RequestHeader:从请求头上获取参数@RequestParam:从请求参数上获取参数@CookieValue:从请求Cookie中获取参数@RequestBody:从请求body上获取参数@MatrixVariable:从请求路径上;分割获取变量
请求路径/test;user=jack;age=16,interests=sleep,dream@MatrixVariable("user") String name,@MatrixVariable("age") Integer age,@MatrixVariable("interests") List<String> interests@GetMapping("/{id}")
public String getParam(@PathVariable("id") Integer id,
@RequestHeader("Host") String host,
@RequestParam("name") Integer name,
@CookieValue("_username") String usernmae){
}
@PostMapping
public void postMethod(@RequestBody String content){
}
// 可以传多个值,用对象来接收,存在相同属性时,会自动封装到里面。
@PostMapping
public void postMethod(@RequestBody Student student){
}
数据响应,一般分两个类型:
响应数据的格式可以是json,xml,io流等。
SpringMVC支持返回值:
ModelAndView
Model
View
ResponseEntity
ResponseBodyEmitter
StreamingResponseBody
HttpEntity
HttpHeaders
Callable
DeferredResult
ListenableFuture
CompletionStage
WebAsyncTask
有 @ModelAttribute 且为对象类型的@ResponseBody 注解
SpringBoot默认不支持 JSP,需要引入第三方模板引擎技术实现页面渲染。
前端显示页面,是html页面。我们以前开发,做的是jsp页面,jsp可以动态渲染一些数据在页面上,可以写Java代码。JSP+Servlet+JavaBean,是我们很早之前就不用了,企业也用得少。
现在SpringBoot推荐Thymeleaf模板引擎。
| 表达式名字 | 语法 | 用途 |
|---|---|---|
| 变量取值 | ${…} | 获取请求域、session域、对象等值 |
| 选择变量 | *{…} | 获取上下文对象值 |
| 消息 | #{…} | 获取国际化等值 |
| 链接 | @{…} | 生成链接 |
| 片段表达式 | ~{…} | jsp:include 作用,引入公共页面片段 |
<!-- 常用标签,一般都是 th:XXX -->
<!-- 需要设置头部(非标准HTML5 规范),也可以不设置 -->
<html xmlns:th="http://www.thymeleaf.org">
<!-- 不设置头部的写法(符合HTML5规范) -->
<p data-th-text="${msg}">msg</p>
<!--设置文本-->
<p th:text="${msg}">提醒消息</p>
<!--设置文本-->
<a th:href="@{href}">超链接</a>
<!-- 设置属性值 -->
<input type="text" th:id="${student.id}" />
<!-- 获取session -->
<p th:id="${#session.user}" />
(1)添加thymeleaf依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
(2)创建文件,springboot帮我们配置好了,我们直接开发页面即可

// 接口
@Controller
public class IndexController {
@GetMapping("/thymeleaf")
public String index(Model model) {
model.addAttribute("msg","hello thymeleaf");
model.addAttribute("link","www.baidu.com");
// 返回视图层
return "thymeleaf";
}
}
在templates下新建thymeleaf.html:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<h1 data-th-text="${msg}">提醒消息</h1>
<h2>
<a data-th-href="${link}">超连接</a>
</h2>
</body>
</html>
(3)效果

例子:访问项目,需要登录,如果没有登录就不能访问
🍀(1)添加登录页面:login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LOGIN</title>
<style>
* {
margin: 0;
padding: 0;
}
html {
height: 100%;
}
body {
height: 100%;
}
.container {
height: 100%;
background-image: linear-gradient(to right, #fbc2eb, #a6c1ee);
}
.login-wrapper {
background-color: #fff;
width: 358px;
height: 588px;
border-radius: 15px;
padding: 0 50px;
position: relative;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.header {
font-size: 38px;
font-weight: bold;
text-align: center;
line-height: 200px;
}
.input-item {
display: block;
width: 100%;
margin-bottom: 20px;
border: 0;
padding: 10px;
border-bottom: 1px solid rgb(128, 125, 125);
font-size: 15px;
outline: none;
}
.input-item:placeholder {
text-transform: uppercase;
}
.btn {
border: 0;
font-size: 20px;
text-align: center;
padding: 10px;
width: 100%;
margin-top: 40px;
background-image: linear-gradient(to right, #a6c1ee, #fbc2eb);
color: #fff;
}
.msg {
color:red;
text-align: center;
line-height: 88px;
}
a {
text-decoration-line: none;
color: #abc1ee;
}
</style>
</head>
<body>
<div class="container">
<div class="login-wrapper">
<div class="header">Login</div>
<div class="form-wrapper">
<form data-th-action="@{/login}" method="post">
<input type="text" name="username" placeholder="username" class="input-item" / >
<input type="password" name="password" placeholder="password" class="input-item" />
<input type="submit" class="btn" value="Login" />
</form>
</div>
<div class="msg" data-th-text="${msg}">
Don't have account?
<a href="#">Sign up</a>
</div>
</div>
</div>
</body>
</html>
🍀(2)添加登录接口
@Controller
public class LoginController {
@GetMapping("/")
public String index() {
// 返回视图层
return "/login/login";
}
@PostMapping("/login")
public String login(String username, String password, HttpSession session, Model model) {
if(StringUtils.hasLength(username) && "123456".equals(password)){
//把登陆成功的用户保存起来
session.setAttribute("loginUserName",username);
//登录成功重定向到 thymeleaf ; 重定向防止表单重复提交
return "redirect:/thymeleaf";
}else {
model.addAttribute("msg","账号密码错误");
//回到登录页面
return "/";
}
}
}
🍀(3)添加拦截器
继承HandlerInterceptor 接口
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {
/**
* 目标方法执行之前
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 请求路径 request.getRequestURI();
//登录检查逻辑
HttpSession session = request.getSession();
Object loginUser = session.getAttribute("loginUserName");
if(loginUser != null){
//放行
return true;
}
//拦截住。未登录。跳转到登录页
request.setAttribute("msg","请先登录");
// 跳转
request.getRequestDispatcher("/").forward(request,response);
return false;
}
}
🍀(4)配置拦截器
@Configuration
public class AdminWebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor())
// 所有请求都被拦截包括静态资源
.addPathPatterns("/**")
// 放行的请求
.excludePathPatterns("/","/login","/css/**","/fonts/**","/images/**","/js/**");
}
}
🍀(5)测试

错误处理:
/error处理所有错误的映射

SpringBoot也为我们提供了自定义错误页的功能。
自定义错误页的话可以在静态路径(如/static/)下的error目录。或放在模板目录(如 /templates/)下的error目录,都会被SpringBootz自动解析。
DefaultErrorAttributes:定义错误页面中可以包含哪些数据。


👉Java全栈学习路线可参考:【Java全栈学习路线】最全的Java学习路线及知识清单,Java自学方向指引,内含最全Java全栈学习技术清单~
👉算法刷题路线可参考:算法刷题路线总结与相关资料分享,内含最详尽的算法刷题路线指南及相关资料分享~
我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当
我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm
我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI
这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub
我正在玩HTML5视频并且在ERB中有以下片段:mp4视频从在我的开发环境中运行的服务器很好地流式传输到chrome。然而firefox显示带有海报图像的视频播放器,但带有一个大X。问题似乎是mongrel不确定ogv扩展的mime类型,并且只返回text/plain,如curl所示:$curl-Ihttp://0.0.0.0:3000/pr6.ogvHTTP/1.1200OKConnection:closeDate:Mon,19Apr201012:33:50GMTLast-Modified:Sun,18Apr201012:46:07GMTContent-Type:text/plain
无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD
在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList()Obt
1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,
在VMware16.2.4安装Ubuntu一、安装VMware1.打开VMwareWorkstationPro官网,点击即可进入。2.进入后向下滑动找到Workstation16ProforWindows,点击立即下载。3.下载完成,文件大小615MB,如下图:4.鼠标右击,以管理员身份运行。5.点击下一步6.勾选条款,点击下一步7.先勾选,再点击下一步8.去掉勾选,点击下一步9.点击下一步10.点击安装11.点击许可证12.在百度上搜索VM16许可证,复制填入,然后点击输入即可,亲测有效。13.点击完成14.重启系统,点击是15.双击VMwareWorkstationPro图标,进入虚拟机主
@作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors 1、什么是behaviors 2、behaviors的工作方式 3、创建behavior 4、导入并使用behavior 5、behavior中所有可用的节点 6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors 1、什么是behaviorsbehaviors是小程序中,用于实现