web开发
1.传统的接口和Restful风格的区别
传统的api接口:
@RequestMapping("saveUser")
public String saveUser(){
return "保存用户";
}
@RequestMapping("deleteUser")
public String deleteUser(){
return "删除用户";
}
@RequestMapping("getUser")
public String getUser(){
return "查询用户";
}
@RequestMapping("editUser")
public String editUser(){
return "修改用户";
}
restful风格的api接口:
只需要一个请求接口
@RequestMapping(value = "user",method = RequestMethod.POST)
public String saveUser(){
return "保存用户";
}
@RequestMapping(value = "user",method = RequestMethod.DELETE)
public String deleteUser(){
return "删除用户";
}
@RequestMapping(value = "user",method = RequestMethod.GET)
public String getUser(){
return "查询用户";
}
@RequestMapping(value = "user",method = RequestMethod.PUT)
public String editUser(){
return "修改用户";
}
简写方式:@xxxMapping
@PostMapping("user")
public String saveUser(){
return "保存用户";
}
2.基本参数和基本注解
2.1 注解
常见的参数注解 @PathVariable、@RequestHeader、@ModelAttribute、@RequestParam、@RequestAttribute、@MatrixVariable、@CookieValue、@RequestBody
@PathVariable
路径变量
// 请求url: http://localhost:8080/user/2
@GetMapping("user/{id}")
public void getUser(@PathVariable("id")Integer id){
System.out.println("id = " + id);
}
// 获取请求中所有的参数
// 请求url: http://localhost:8080/user/2/tr
@GetMapping("user/{id}/{userName}")
public void getUsers(@PathVariable Map<String, String> pv){
System.out.println("pv = " + pv);
}
@RequestHeader
获取请求头信息
// 获取所有请求头信息
@GetMapping("user")
public void testRequestHeader(@RequestHeader Map<String, String> headers){
System.out.println("headers = " + headers);
}
@RequestParam
获取请求参数
//请求url: http://localhost:8080/user?userName=test 也可以通过map接收所有参数
@GetMapping("user")
public String test(@RequestParam("userName") String userName){
return userName;
}
@CookieValue
获取cookie值
//获取key=cookie_key 的所有cookie信息
@GetMapping("testCookieValue")
public void testCookie(@CookieValue("cookie_key") Cookie cookie){
System.out.println("cookie = " + cookie);
}
@RequestBody
获取请求体
//需要使用post请求 将整个表单提交的key value全部获取
@GetMapping("testRequestBody")
public void postUser(@RequestBody String content){
System.out.println("content = " + content);
}
@RequestAttribute
快速取出请求域中的信息
@GetMapping("/goto")
public String gotoPage(HttpServletRequest request){
request.setAttribute("msg","成功了...");
return "forward:/success";
}
@ResponseBody
@GetMapping("/success")
public String test(@RequestAttribute("msg") String msg,HttpServletRequest request){
Object msg1 = request.getAttribute("msg");
System.out.println("msg1 = " + msg1.toString());
System.out.println("msg = " + msg);
return "ok";
}
@MatrixVariable
矩阵变量
//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;
}
手动开启矩阵变量
// 开启矩阵变量
@Bean
public WebMvcConfigurer webMvcConfigurer(){
return new WebMvcConfigurer() {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
UrlPathHelper helper = new UrlPathHelper();
// 不移除 ;后面的内容
helper.setRemoveSemicolonContent(false);
configurer.setUrlPathHelper(helper);
}
};
}
3.静态资源访问
3.1、静态资源目录
只要静态资源放在类路径下: /static
(or /public
or /resources
or/META-INF/resources)
访问 : 当前项目根路径/ + 静态资源名
原理: 静态映射/**。
请求进来,先去找Controller看能不能处理。不能处理的所有请求又都交给静态资源处理器。静态资源也找不到则响应404页面
改变默认静态资源路径
# 默认无前缀,http://localhost:8080/test/test.css
spring:
mvc:
static-path-pattern: /test/**
# 自定义静态资源包
resources:
static-locations: [classpath:/test/]
3.2、自定义 Favicon
favicon.ico 放在静态资源目录下即可。
spring:
# mvc:
# static-path-pattern: /test/** 这个配置会导致 Favicon 功能失效
4.拦截器
4.1、自定义拦截器
继承HandlerInterceptor
接口
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {
// 请求之前
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 打印日志
log.info("拦截路径{}",request.getRequestURI());
HttpSession session = request.getSession();
Object login = session.getAttribute("login");
if (login != null) {
return true;
}
// 未登录,转发到登录页面
// request.getRequestDispatcher("/login").forward(request,response);
response.sendRedirect("/login"); //重定向
return false;
}
// 请求完成之后
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
// 页面渲染之后
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
4.2、将自定义的拦截器注入ioc
继承WebMvcConfigurer
接口
@Configuration
public class MyWebConfig implements WebMvcConfigurer{
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor())
//拦截所有请求
.addPathPatterns("/**")
//不拦截的请求
.excludePathPatterns("/login","/err");
}
}
5.文件上传
5.1、准备一个表单
<form action="/upload" enctype="multipart/form-data" method="post">
<input type="file" name="image"><br>
<input type="file" name="images" multiple><br>
<input type="text" name="username"><br>
<input type="password" name="password"><br>
<input type="submit" value="提交">
</form>
5.2、准备接口
@PostMapping("/upload")
public String uploadForm(@RequestParam Map<String, String> kvParam,
@RequestPart("image")MultipartFile image,
@RequestPart("images")MultipartFile[] images) throws IOException {
System.out.println("kvParam = " + kvParam);
System.out.println(image.isEmpty());
System.out.println(images.length);
if (!image.isEmpty()) { //不为空
// 保存到 D://images//
image.transferTo(new File("D://image//"));
}
return "上传成功";
}
5.3、配置文件大小
如果上传的文件大小超过1M会报错,需要手动开启配置
spring:
servlet:
multipart:
# 单文件上传大小
max-file-size: 1MB
# 文件上传总大小
max-request-size: 10MB
6.异常处理
6.1、错误处理
- 默认情况下,Spring Boot提供
/error
处理所有错误的映射 - 对于机器客户端,它将生成JSON响应,其中包含错误,HTTP状态和异常消息的详细信息。对于浏览器客户端,响应一个“ whitelabel”错误视图,以HTML格式呈现相同的数据
- 要对其进行自定义,添加
View
解析为error - 要完全替换默认行为,可以实现
ErrorController
并注册该类型的Bean定义,或添加ErrorAttributes类型的组件
以使用现有机制但替换其内容。 - error/下的4xx,5xx页面会被自动解析;
6.2、定制错误处理
-
自定义错误页 error/404.html error/5xx.html;有精确的错误状态码页面就匹配精确,没有就找 4xx.html;如果都没有就触发白页
- resource/error
-
@ControllerAdvice+@ExceptionHandler处理全局异常;底层是 ExceptionHandlerExceptionResolver 支持的
-
@ControllerAdvice public class TestException { @ExceptionHandler({ArithmeticException.class}) @ResponseBody public String HandlesArithmeticException() { return "自定义处理运算异常"; } }
-
-
@ResponseStatus+自定义异常 ;底层是 ResponseStatusExceptionResolver ,把responsestatus注解的信息底层调用 response.sendError(statusCode, resolvedReason);tomcat发送的/error
-
@ResponseStatus(value = HttpStatus.FORBIDDEN,reason = "用户过多拒绝访问") public class UserTooManyException extends RuntimeException { public UserTooManyException(String message) { super(message); } }
-
-
Spring底层的异常,如 参数类型转换异常;DefaultHandlerExceptionResolver 处理框架底层的异常。
-
-
response.sendError(HttpServletResponse.SC_BAD_REQUEST, ex.getMessage());
-
Q.E.D.