1、请求处理

路径通配符

/**
     * 路径位置的通配符,多个都能匹配,精确优先
     *      *任意多个
     *      **任意多层
     *      ?任意一个
     *      完全匹配 > ? >* > **
     * @return
     */
    @GetMapping("/hello")
    public String hello(){
        return "hello world spring mvcc";
    }

参数:

        params 请求参数

        headers请求头

        consumes请求内容 

  /**
     * params 匹配参数 必须包含 username
     * headers 匹配请求头 必须包含 Accept
     * @return
     */
    @GetMapping(value = "/hello" ,params = "username", headers = "Accept")
    public String user(){
        return "hello world spring mvcc";
    }
/**
     * consumes 匹配请求头 必须包含 application/json
     * @return
     */
    @GetMapping(value = "/hello" ,consumes = "application/json")
    public String user1(){
        return "hello world spring mvcc";
    }
/**
     * consumes 响应的结果响应头中包含application/json或者application/xml或者text/html
     * @return
     */
    @GetMapping(value = "/hello" ,produces = {"application/json","application/xml","text/html"})
    public String user2(){
        return "hello world spring mvcc";
    }

接受参数

@RequestParam

    @GetMapping(value = "/handle02" ,params = "username", headers = "Accept")
    public String getUser(@RequestParam("username") String userName,
                        @RequestParam String  password,
                        @RequestParam(required = false) String phone){
        System.out.println("username:"+userName);
        System.out.println("password:"+password);
        System.out.println("phone:"+phone);
        return "hello world spring mvcc";
    }
 @GetMapping(value = "/handle04" , headers = "Accept")
    public String getHead(@RequestHeader("keep-alive") String keepAlive, @CookieValue("haha ") String cookie){
        System.out.println("keepAlive:"+keepAlive);
        return "hello world spring mvcc";
    }

请求体中接收json

文件上传

    /**
     * 文件上传
     * @param person
     * @return
     */
    @PostMapping(value = "/handle08" )
    public String getFile(Person person,
                          @RequestParam("lifeImg") MultipartFile[]  files) throws IOException {
        for (MultipartFile file : files) {
            file.getOriginalFilename();
            file.getSize();
            file.getContentType();
            file.getInputStream();
            file.transferTo(new java.io.File("D:/"+file.getOriginalFilename()));
            System.out.println("file:"+file.getOriginalFilename());
            System.out.println("file:"+file.getSize());
        }
        System.out.println("person:"+person);
        return "hello world spring mvcc";
    }

文件有大小要求

spring:
  application:
    name: spring-mvc
  servlet:
    multipart:
      max-file-size: 20

封装请求

/**
     * 获取HttpEntity
     * @param entity
     * @return
     */
    @RequestMapping(value = "/handle09" )
    public String getHttpEntity(HttpEntity<String>  entity){
        String body = entity.getBody();
        HttpHeaders headers = entity.getHeaders();
        System.out.println("body:"+body);
        System.out.println("headers:"+headers);
        return "hello world spring mvcc";
    }

用的不多

请求处理总结

2、响应处理

  @RequestMapping("/resp01")
    public Person resp01(){
        Person person = new Person();
        person.setName("张三");
        return person;
    }

响应回去一个对象;

文件下载

/**
     * 文件下载
     * httpentity 拿到整个请求数据
     * responseentity 拿到整个响应数据(响应头、响应体、状态码)
     *
     * @return
     */
    @RequestMapping("/download")
    public ResponseEntity<InputStreamResource> download() throws IOException {
        FileInputStream fileInputStream = new FileInputStream("D:\\EG.webp");
        byte[] bytes = fileInputStream.readAllBytes();
        // 文件名中文乱码,解决方式:
        String encode = URLEncoder.encode("eg.webp", "utf-8");
        //文件太大会内存溢出
        InputStreamResource inputStreamResource = new InputStreamResource(fileInputStream);

        return ResponseEntity
                .ok()
                //处理方式
                .header("content-disposition","attachment;filename="+encode)
                //内容类型 流
                .contentType(MediaType.APPLICATION_OCTET_STREAM)
                //内容大小
                .contentLength(fileInputStream.available() )
                .body(inputStreamResource);
    }

3、restful api

cors policy 同源策略

/之前的所有东西都得一模一样才能发出去;加注解同意跨域@CrossOrigin

4、返回结果

package com.kr.springbootmvc.common;

import lombok.Data;

@Data
public class Result<T> {
    private Integer code;
    private String message;
    private T data;
    public static<T> Result<T> success(T data){
        Result<T> result = new Result<>();
        result.setCode(200);
        result.setMessage("success");
        result.setData(data);
        return result;
    }

    public static Result success(){
        Result result = new Result<>();
        result.setCode(200);
        result.setMessage("success");
        return result;
    }
    public static<T> Result<T> error(Integer code,String message){
        Result<T> result = new Result<>();
        result.setCode(code);
        result.setMessage(message);
        return result;
    }
    
}

5、MVC配置类

package com.kr.spring05mvcbest.config;

import com.kr.spring05mvcbest.interceptor.MyHandleInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MySpringMvcConfig implements WebMvcConfigurer {
    @Autowired
    MyHandleInterceptor myHandleInterceptor;
    /**
     * 添加拦截器
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(myHandleInterceptor)
                .addPathPatterns("/**");
    }
}

6、拦截器

package com.kr.spring05mvcbest.interceptor;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
@Component // 拦截器组件,必须告诉springmvc拦截那些请求
public class MyHandleInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return HandlerInterceptor.super.preHandle(request, response, handler);
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {}
}

其中,prehandle方法是在请求进入执行,

           posthandle是在controller方法执行之后modelandview返回之前执行;

           aftercompletion是在prehandle方法放回true才执行;

拦截器和过滤器的区别

拦截器是springmvc的接口handlerinterceptor过滤器是servlet定义的;

拦截器和spring无缝整合,过滤器不受spring管理

拦截范围:springmvc能处理的请求拦截,过滤器拦截web所有请求;

在spring中优先拦截器;

7、异常处理

编程式异常处理 try catch throw

声明式异常处理 注解

最终实践

1、首先定义一个异常类

package com.kr.spring05mvcbest.exception;


import lombok.Data;

/**
 * 自定义业务异常类
 */
@Data
public class BizException extends RuntimeException {

    private Integer code;
    private String message;

    public BizException(Integer code, String message){
        super(message);
        this.code = code;
        this.message = message;
    }
    public BizException(BizExceptionEnum bizExceptionEnum){
        super(bizExceptionEnum.getMessage());
        this.code = bizExceptionEnum.getCode();
        this.message = bizExceptionEnum.getMessage();

    }
}

2、定义异常所有枚举情况

package com.kr.spring05mvcbest.exception;

import lombok.Getter;
public enum BizExceptionEnum {
    USER_NOT_EXIST(1001,"用户不存在"),
    USER_PASSWORD_ERROR(1002,"用户密码错误"),
    USER_NOT_LOGIN(1003,"用户未登录"),
    USER_NOT_ADMIN(1004,"用户不是管理员"),
    USER_NOT_EXIST_OR_PASSWORD_ERROR(1005,"用户不存在或密码错误"),
    USER_NOT_EXIST_OR_PASSWORD_ERROR_OR_NOT_LOGIN(1006,"用户不存在或密码错误或未登录");

    @Getter
    private Integer code;
    @Getter
    private String message;
    private BizExceptionEnum(Integer code, String message){
        this.code = code;
        this.message = message;
    }
}

3、定义全局异常处理类

package com.kr.spring05mvcbest.advice;


import com.kr.spring05mvcbest.common.Result;
import com.kr.spring05mvcbest.exception.BizException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(Throwable.class)
    public Result handleException(Throwable e){
        return Result.error(500,e.getMessage());
    }
    @ExceptionHandler(BizException.class)
    public Result handleBizException(BizException e){
        return Result.error(e.getCode(),e.getMessage());
    }
}

4、使用

if (id ==0){
       throw new BizException(BizExceptionEnum.USER_NOT_EXIST);
  }

5、处理流程 

首先抛出BizException异常,然后全局异常处理器拿到异常以后给前端放回;

必须有

1、业务异常类BizException extends RuntimeException

2、异常枚举 BizExceptionEnum

3、全局异常处理 advice\GlobalExceptionHandler

8、数据校验

        JSR303是java专门为Bean数据合法性校验提供的

导入依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

 @PostMapping(value = "/handle07" )
    public Result<HashMap<String, String>> getJson(@RequestBody @Valid Employee  person , BindingResult result){
        if(!result.hasErrors()){
            System.out.println("person:"+person);
//            执行新增然后返回
        }
        HashMap<String, String> map = new HashMap<>();
        for (FieldError fieldError : result.getFieldErrors()) {
            String field = fieldError.getField();
            String defaultMessage = fieldError.getDefaultMessage();
            map.put(field,defaultMessage);
        }
        return Result.error(500,"参数错误",map);
    }
@Data
public class Employee {
    @NotBlank(message = "id不能为空")
    private long id;
    @NotBlank(message = "name不能为空")
    private String name;
    @NotNull(message = "age不能为空")
    @Max(value = 120, message = "年龄不能大于120岁")
    private Integer age;
    @Email(message = "邮箱格式不正确")
    private String email;

    private String gender;
    private String dept;
}

全局异常处理

在全局异常处理类中添加

只需要在controller方法上添加 @Valid注解开启校验

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result handleException(MethodArgumentNotValidException e){
        BindingResult bindingResult = e.getBindingResult();
        Map<String, String> map = new HashMap<>();
        for (FieldError fieldError : bindingResult.getFieldErrors()) {
            String field = fieldError.getField();
            String defaultMessage = fieldError.getDefaultMessage();
            map.put(field,defaultMessage);
        }
        return Result.error(500,"参数错误",map);
    }

9、日期处理

类属性上加注解

 @JsonFormat(pattern = "yyyy-MM-dd")

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐