Web开发
总览:
1、SpringMVC自动配置概览
SpringBoot中帮我们自动配置了大部分SpringMVC的场景,有时候在项目开发中我们会需要改变SpringBoot默认帮我们配置的场景,所以我们需要自定义化一些场景:
2、简单功能分析
2.1、静态资源访问
2.1.1、静态资源目录
只要静态资源放在类路径下: 名称为 /static (or /public or /resources or /META-INF/resources),就可以直接访问
访问方式 : 当前项目根路径/ + 静态资源名
解释:当前项目根路径就是resources的那个文件夹,等同于localhost:8080/;静态资源名就是那些什么HTML或者CSS或者图片啥的
访问的原理: 静态映射/**。
解释:比如访问localhost:8080/bug.jpg,这个访问的意思就是“访问resources目录下的所有静态资源(/**)”
当浏览器端的访问请求进来,会先去找Controller控制层看能不能处理。不能处理的所有请求又都交给静态资源处理器。静态资源也找不到的话则响应404页面
改变默认的静态资源路径:
解释:如果我们不想在SpringBoot默认的那四个文件夹下放静态资源(比如public,就上面那几个),那么我们可以通过下面的代码自定义防止静态资源的文件夹。注意设置之后,原先默认的四个放置静态资源的文件夹就不管用了,访问其会报404.
spring:
resources:
static-locations: [classpath:/haha/]
2.1.2、静态资源访问前缀
在上面提到了访问静态资源的方式默认是根路径+/**,但是我们在项目开发当中会有成百上千的静态资源,这时候我们肯定会启用一些拦截器功能,拦截器也是对:默认根路径+/**的所有请求进行拦截,那么有些我们希望被用户直接访问的静态资源就也会被拦截器拦截,所以为了防止这种现象产生,我们修改默认的访问静态资源方式,我们指定访问方式的根路径名,如下面代码,我们修改默认的resources为res,那么以后访问静态资源就必须携带上res,如访问bug.jpg将变为:localhost:8080/res/bug.jpg;而我们的拦截器因为没有res路径所以不会对我们希望被用户直接访问的其他静态资源产生拦截影响。
SpringBoot默认是无前缀的,在下面代码中修改:
spring:
mvc:
static-path-pattern: /res/**
则现在访问方式为:localhost:8080/res/bug.jpg
2.1.3、webjar
webjar就是把我们的js文件打包成jar包而已,不是很重要,了解一下就行。
自动映射 /webjars/**
https://www.webjars.org/
例如jQuery文件:
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.5.1</version>
</dependency>
访问地址:http://localhost:8080/webjars/jquery/3.5.1/jquery.js 后面地址要按照依赖里面的包路径
2.2、欢迎页支持
自定义欢迎页可以有以下两种方式,在静态资源路径下定义index.html或者用web层的controller控制器跳转到index.html
1、静态资源路径下 index.html
可以配置静态资源路径
但是不可以配置静态资源的访问前缀。否则导致 index.html不能被默认访问
spring:
# mvc:
# static-path-pattern: /res/** 这个会导致welcome page功能失效
resources:
static-locations: [classpath:/haha/]
2、controller能处理/index
2.3、自定义 Favicon
favicon就是页面上面的那个小图标,我们需要将其换成什么图就将其命名为favicon.ico放入静态资源目录下就行。
favicon.ico 放在静态资源目录下即可
spring:
# mvc:
# static-path-pattern: /res/** 这个会导致 Favicon 功能失效
3、请求参数处理(如何加入PUT和DELETE)
以前我们写请求路径都是动词加名词来表示(如/getUser),这样不舒服,开发中更习惯于使用Rest风格来进行url的编写。即我们先在不管是增加还是删改还是查询,统一都叫:/名词(如/user),而通过访问方式的不同来决定是增删改查的其中哪一种。要完成这个事情,核心是在SpringMVC中配置HiddenHttpMethodFilter。
下面的代码是我们进行测试的代码:
//控制器中有四个方法,请求路径都叫/user,通过后面method方法的不同来访问不
//同的控制器方法
@RequestMapping(value = "/user",method = RequestMethod.GET)
public String getUser(){
return "GET-张三";
}
@RequestMapping(value = "/user",method = RequestMethod.POST)
public String saveUser(){
return "POST-张三";
}
@RequestMapping(value = "/user",method = RequestMethod.PUT)
public String putUser(){
return "PUT-张三";
}
@RequestMapping(value = "/user",method = RequestMethod.DELETE)
public String deleteUser(){
return "DELETE-张三";
}
//这一段是源码当中的东西,测试时不用加上
@Bean
@ConditionalOnMissingBean(HiddenHttpMethodFilter.class)
@ConditionalOnProperty(prefix = "spring.mvc.hiddenmethod.filter", name = "enabled", matchIfMissing = false)
public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {
return new OrderedHiddenHttpMethodFilter();
}
//这是我们自定义的filter,可以把_method改成我们喜欢的
//测试时不用加上
@Bean
public HiddenHttpMethodFilter hiddenHttpMethodFilter(){
HiddenHttpMethodFilter methodFilter = new HiddenHttpMethodFilter();
methodFilter.setMethodParam("_m");
return methodFilter;
}
但是在页面部分中的表单部分,可以看到貌似表单只有两种提交方式POST和GET:
我们先试一下,看写上DELETE和PUT能不能行:
测试结果是除了POST和GET可以,另外两个都不可以。
那我们怎么才能让这两个也能正常使用呢?
我们需要在SpringMVC中配置HiddenHttpMethodFilter才行,但是在SpringBoot源码的查阅中我们可以知道,它已经替我们写上了这个filter的配置:
这样我们要使用PUT和DELETE时,只需要在表单提交中遵从以下的方式就可以写PUT和DELETE了:
<input name="_method" type="hidden" value="DELETE">
但是在源码中,这个filter默认是不会被开启的,我们需要手动在application.properties配置文件中开启它才能使用DELETE和PUT方法:
1、普通参数与基本注解
1.1、注解:
@PathVariable、@RequestHeader、@ModelAttribute、@RequestParam、@MatrixVariable、@CookieValue、@RequestBody
这些注解有些在SpringMVC中看到过的,有些是新的。
测试代码:
@RestController
public class ParameterTestController {
//Rest风格的路由
/*
/car/{id}/owner/{username},{}就是占位符
请求参数就是:id为几的car以及owner叫什么name
如:car/2/owner/zhangsan
说明就是想访问id为2的car以及owner为zhangsan的数据库中的东西
@PathVariable("id")注解就是用来解析url路由中的{}占位符的值的,将它赋值给其后面的参数
也可以直接使用@PathVariable Map<String,String> pv,自动将这个两个值(id和username)封装成一个kv键值对放进Map集合中
*/
// car/2/owner/zhangsan
@GetMapping("/car/{id}/owner/{username}")
public Map<String,Object> getCar(@PathVariable("id") Integer id,
@PathVariable("username") String name,
@PathVariable Map<String,String> pv,
@RequestHeader("User-Agent") String userAgent,
@RequestHeader Map<String,String> header,
@RequestParam("age") Integer age,
@RequestParam("inters") List<String> inters,
@RequestParam Map<String,String> params,
@CookieValue("_ga") String _ga,
@CookieValue("_ga") Cookie cookie){
Map<String,Object> map = new HashMap<>();
// map.put("id",id);
// map.put("name",name);
// map.put("pv",pv);
// map.put("userAgent",userAgent);
// map.put("headers",header);
map.put("age",age);
map.put("inters",inters);
map.put("params",params);
map.put("_ga",_ga);
System.out.println(cookie.getName()+"===>"+cookie.getValue());
return map;
}
@PostMapping("/save")
public Map postMethod(@RequestBody String content){
Map<String,Object> map = new HashMap<>();
map.put("content",content);
return map;
}
//1、语法: 请求路径:/cars/sell;low=34;brand=byd,audi,yd
//2、SpringBoot默认是禁用了矩阵变量的功能
// 手动开启:原理。对于路径的处理。UrlPathHelper进行解析。
// removeSemicolonContent(移除分号内容)支持矩阵变量的
//3、矩阵变量必须有url路径变量才能被解析
@GetMapping("/cars/{path}")
public Map carsSell(@MatrixVariable("low") Integer low,
@MatrixVariable("brand") List<String> brand,
@PathVariable("path") String path){
Map<String,Object> map = new HashMap<>();
map.put("low",low);
map.put("brand",brand);
map.put("path",path);
return map;
}
// /boss/1;age=20/2;age=10
@GetMapping("/boss/{bossId}/{empId}")
public Map boss(@MatrixVariable(value = "age",pathVar = "bossId") Integer bossAge,
@MatrixVariable(value = "age",pathVar = "empId") Integer empAge){
Map<String,Object> map = new HashMap<>();
map.put("bossAge",bossAge);
map.put("empAge",empAge);
return map;
}
}
1.2、Servlet API:
WebRequest、ServletRequest、MultipartRequest、 HttpSession、javax.servlet.http.PushBuilder、Principal、InputStream、Reader、HttpMethod、Locale、TimeZone、ZoneId
这些原生的应该不怎么用,就不了解了解叭。
5、视图解析与模板引擎
指的就是springboot在处理完请求之后想要跳转到某个页面的过程。
视图解析:springboot默认不支持JSP,需要引入第三方模板引擎技术实现页面渲染。
1、视图解析
2、模板引擎-Thymeleaf
1、thymeleaf简介
Thymeleaf is a modern server-side Java template engine for both web and standalone environments, capable of processing HTML, XML, JavaScript, CSS and even plain text.
现代化、服务端Java模板引擎。
2、基本语法
1、表达式
2、字面量
文本值: ‘one text’ , ‘Another one!’ ,…数字: 0 , 34 , 3.0 , 12.3 ,…布尔值: true , false
空值: null
变量: one,two,… 变量不能有空格
3、文本操作
字符串拼接: +
变量替换: |The name is ${name}|
4、数学运算
运算符: + , - , * , / , %
5、布尔运算
运算符: and , or
一元运算: ! , not
6、比较运算
比较: > , < , >= , <= ( gt , lt , ge , le )等式: == , != ( eq , ne )
7、条件运算
If-then: (if) ? (then)
If-then-else: (if) ? (then) : (else)
Default: (value) ?: (defaultvalue)
8、特殊操作
无操作: _
3、设置属性值-th:attr
设置单个值
<form action="subscribe.html" th:attr="action=@{/subscribe}">
<fieldset>
<input type="text" name="email" />
<input type="submit" value="Subscribe!" th:attr="value=#{subscribe.submit}"/>
</fieldset>
</form>
<img src="../../images/gtvglogo.png" th:attr="src=@{/images/gtvglogo.png},title=#{logo},alt=#{logo}" />
<input type="submit" value="Subscribe!" th:value="#{subscribe.submit}"/>
<form action="subscribe.html" th:action="@{/subscribe}">
所有h5兼容的标签写法
https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#setting-value-to-specific-attributes
4、迭代
<tr th:each="prod : ${prods}">
<td th:text="${prod.name}">Onions</td>
<td th:text="${prod.price}">2.41</td>
<td th:text="${prod.inStock}? #{true} : #{false}">yes</td>
</tr>
<tr th:each="prod,iterStat : ${prods}" th:class="${iterStat.odd}? 'odd'">
<td th:text="${prod.name}">Onions</td>
<td th:text="${prod.price}">2.41</td>
<td th:text="${prod.inStock}? #{true} : #{false}">yes</td>
</tr>
5、条件运算
<a href="comments.html"
th:href="@{/product/comments(prodId=${prod.id})}"
th:if="${not #lists.isEmpty(prod.comments)}">view</a>
<div th:switch="${user.role}">
<p th:case="'admin'">User is an administrator</p>
<p th:case="#{roles.manager}">User is a manager</p>
<p th:case="*">User is some other thing</p>
</div>
3、thymeleaf使用
1、引入Starter
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
2、自动配置好了thymeleaf
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(ThymeleafProperties.class)
@ConditionalOnClass({ TemplateMode.class, SpringTemplateEngine.class })
@AutoConfigureAfter({ WebMvcAutoConfiguration.class, WebFluxAutoConfiguration.class })
public class ThymeleafAutoConfiguration { }
自动配好的策略
1、所有thymeleaf的配置值都在 ThymeleafProperties
2、配置好了 SpringTemplateEngine
3、配好了 ThymeleafViewResolver
4、我们只需要直接开发页面
public static final String DEFAULT_PREFIX = "classpath:/templates/";
public static final String DEFAULT_SUFFIX = ".html"; //xxx.html
3、页面开发
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1 th:text="${msg}">哈哈</h1>
<h2>
<a href="www.atguigu.com" th:href="${link}">去百度</a> <br/>
<a href="www.atguigu.com" th:href="@{link}">去百度2</a>
</h2>
</body>
</html>