1、关于springMVC

基于Spring框架,主要解决后端服务器接受客户端服务器接受客户提交的请求,并给予响应相关的问题。的框架


目录

1、关于springMVC

基于Spring框架,主要解决后端服务器接受客户端服务器接受客户提交的请求,并给予响应相关的问题。的框架

2、创建Spring MVC项目

3、 配置依赖。

3. 1使用Spring MVC工程接收客户端的请求

小总结:

4、@RequestMapping

5、@ResponseBody注解表示响应正文​​​​​​​​​​​​​​

6、关于请求参数

7. 关于RESTful(了解,不是绝对遵守)

7.1 接受此请求的方法:

题外话:

附:关于POJO

所有用于封装属性的类型都可以统称为POJO。  例如上面的userVO  user DTO

8、关于响应正文的结果类型

使用枚举:           限定类型。

9、统一异常处理

Spring MVC框架提供了统一处理异常的机制,使得特定种类的异常对应一段特定的代码,后续,当编写代码时,无论在任何位置,都可以将异常直接抛出,由统一处理异常的代码进行处理即可!

10. 拦截器(Interceptor)(框架会自动执行 再此只做了解)

使用拦截器————————————————

拦截器和过滤器

注意:SpringMVC底层的逻辑请看B站

注意:关于SpringMVC  你该知道



学过javaweb我们应该知道

MVC 是一种思想,就是一个项目应该包含的内容包含着三部分。

  • model:数据模型——包含(业务逻辑层)(数据访问层)
  • View:视图
  • Controller:控制器

模型:在编程思想上表示 相对比较规定的套路。 数据模型:对数据的处理相对固定。

SpringMVC重点在C ,涉及V ,基本没有M。




2、创建Spring MVC项目

运行在Tomcat上的Maven项目 ###创建过程(IDEA-运行在Tomcat上的Maven Webapp)

创建方式私信获取。

写的项目放在tomcat下的webapps里面,只有需要关的时候才去关,否则就可以一直开着。

conf 中的 可以更改默认端口号




3、 配置依赖。

https://mvnrepository.com/search?q=spring-webmvc

粘贴到pom文件中  ,右上角M刷新


3. 1使用Spring MVC工程接收客户端的请求

——需要一个初始化类启动项目

spring配置类

springmvc配置类

处理层的类

 成功后:地址表示为项目名

控制处理类里面写以下代码,可实现加载此对象进spring时,可在浏览器端访问,得到提交的数据

返回数据。


小总结:

  • 当启动Tomcat时,会自动将项目打包并部署到Tomcat,通过自动打开的浏览器中的URL即可访问主页,在URL中有很长一段是例如 maven_webapp_tomcat_war_exploded 这一段是不可以删除的,其它的各路径必须补充在其之后,例如 /login.do 就必须在此之后
  • 当启动Tomcat时,项目一旦部署成功,就会自动创建并加载AbstractAnnotationConfigDispatcherServletInitializer的子类,即当前项目中自定义的SpringMvcInitialier,无论这个类放在哪个包中,都会自动创建并加载,由于会自动调用这个类中所有方法,所以会将Spring MVC框架处理的请求路径设置为 *.do,并执行在 UserController 中配置的方法对 cn.tedu.springmvc 的组件扫描,进而会创建 UserController 的对象,由于使用了 @RequestMapping("/login.do"),则此时还将此方法与/login.do进行了绑定,以至于后续随时访问/login.do时都会执行此方法
  • 注意:组件扫描必须配置在Spring MVC的配置类中
  • 注意:控制器类上的注解必须是@Controller,不可以是@Component@Service@Repository

1




4、@RequestMapping

@RequestMapping注解的作用就是 配置请求路径和处理请求的方法的映射关系(映射:mapper 就是对应关系。映射就是比较装逼的说法)

使得注解配置的参数就和请求路径一样,方法处理请求。

此注解也可使用在类上 @ RequestMapping(“/user”)

方法上@RequestMapping(“/login.do”)

请求到参数就必须是/user/login.do      类上路径加方法路径

(  这种方法 / 可以不写)

@RequestMapping("/user")
public class UserController {public UserController(){System.out.println("加载了UserController类");}@RequestMapping("/login.do")@ResponseBody  //将返回值响应到客户端public String login(){return "111";//浏览器不支持中文}}

在项目上就推荐类加方法,指定某个URL前缀。方便各模块同功能分开。

@RequestMapping({“/login.do”,“/nihao”})可以配置多个路径。方便调用方法。

 @RequestMapping

请求方式    :

get/post/其他   @RequestMapping(method = RequestMethod.POST)配置多种请求路径用‘{}包起来’    相关请求方式为:GET  HEAD  POST  PUT  PATCH  DELETE  OPTIONS TRACE.

请求头   :

请求方式:

响应头等等:

另外,Spring MVC框架还提供了@RequestMapping的相关注解,例如:

  • @GetMapping
  • @PostMapping
  • @PutMapping
  • @DeleteMapping
  • 等等

加上请求方式:  没有是要正确的正确就会发送错误405

/*请求方式*/
@RequestMapping(value = "/user",method = RequestMethod.POST)
@GetMappering




5、@ResponseBody注解表示响应正文

配置了注解,将方法的返回值直接响应到客户端去。

没有配置注解,处理方法将返回一个视图组件(后端自己写个网页),这就没有实现前后端分离

可以在需要正文的方法上添加@ResponseBody注解,由于开发模式一般相对统一,所以,一般会将@ResponseBody添加在控制器类上,表示此控制器类中所有处理请求的方法都将响应正文!

@ResponseBody用在类上 就是可以得到 将类中所有方法 的返回值发送的效果。

@RestController  集合了——@ResponseBody 和 @Controller 两个注解


关于响应正文,Spring MVC内置了一系列的转换器(Converter),用于将方法的返回值转换为响应到客户端的数据(并根据HTTP协议补充了必要的数据),并且,Spring MVC会根据方法的返回值不同,自动选取某个转换器,例如,当方法的返回值是String时,会自动使用StringHttpMessageConverter这个转换器,这个转换器的特点就是直接将方法返回的字符串作为响应的正文,并且,其默认的响应文档的字符集是ISO-8859-1,所以在默认情况并不支持非ASCII字符(例如中文)。

在实际应用中,不会使用String作为处理请求的方法的返回值类型,主要是因为普通的字符串不足以清楚的表现多项数据,如果自行组织成JSON或其它某种格式的字符串成本太高!

通常,建议向客户端响应JSON格式的字符串,应该在项目中添加jackson-databind的依赖项:

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.12.3</version>
</dependency>

https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind/2.12.3

以上jackson-databind依赖项中也有一个转换器,当Spring MVC调用的处理请求的方法的返回值是Spring MVC没有匹配的默认转换器时,会自动使用jackson-databind的转换器,而jackson-databind转换器就会解析方法的返回值,并将其处理为JSON格式的字符串,在响应头中将Content-Type设置为application/json

jackson-databind  能返回一个Json格式。方法返回值是自己自定义的类的类型。

注意:在Spring MVC项目中,还需要在Spring MVC的配置类(SpringMvcConfig)上添加@EnableWebMvc注解(增强模式),否则响应时将导致出现HTTP的406错误。

/*SpringMvc配置类*/
@EnableWebMvc
@Configuration
@ComponentScan("cn.tedu.springmvc")/*使用springmvc时,必须配置在此配置扫描。*/
public class SpringMvcConfig implements WebMvcConfigurer {
}

6、关于请求参数

在Spring MVC中,当需要接收客户端的请求参数时,只需要将各参数直接声明为处理请求的方法的参数即可,例如:

// http://localhost:8080/springmvc01_war_exploded/user/reg.do?username=root&password=123456&age=25
@RequestMapping("/reg.do")
public String reg(String username, String password, Integer age) {System.out.println("username = " + username+ ", password = " + password+ ", age = " + age);return "OK";
}

需要注意:

  • 如果客户端提交的请求中参数和方法参数不一致(根本没有匹配名称的参数),则以上获取到的值将是null
  • 如果客户端仅提交了参数名称,却没有值,则以上获取到的值将是""(长度为0的字符串)
  • 如果客户端提交了匹配名称的参数,并且值是有效的,则可以获取到值
  • 以上名称应该是由服务器端决定的,客户端需要根据以上名称来提交请求参数(后端觉决定的,因为有各种客户端:手机,电脑,平板)
  • 声明参数时,可以按需将参数声明成期望的类型,例如以上将age声明为Integer类型
    • 注意:声明成String以外的类型时,应该考虑是否可以成功转换类型(例如age 提交ABC  Integer不能接受)
    • 基本类型尽量用包装类,包装类可以接受NULL值(基本类型会给0,不知道时0岁还是没设置。)

当有必要的情况下,可以在以上各参数的声明之前添加@RequestParam注解,(表示参数必不必须提交)

其作用主要有:

  • 配置value属性:客户端将按照此配置的提交请求参数,而不再是根据方法的参数名称来提交请求参数
  • 配置required属性:是否要求客户端必须提交此请求参数,默认为true,如果不提交,则出现400错误,当设置为false时,如果不提交,则服务器端将此参数值视为null
  • 配置defaultValue属性:配置此请求参数的默认值,当客户端没有提交此请求参数时,视为此值                  假设没有提交参数,上面默认一个值为HAHAHA(应用:当页面多个时,默认提交的值为1,就是展示第一页的值)

        另外,如果需要客户端提交的请求参数较多,可以将这些参数封装为自定义的数据类型,并将自定义的数据类型作为处理方法的参数即可,例如:

多的时候用封装:方面以后的每一步,加数据,删数据...

装:将东西放在一起。   封:private  ,别人看不见。

package cn.tedu.springmvc.dto;public class UserRegDTO {private String username;private String password;private Integer age;// 生成Setters & Getters// 生成toString()}
// http://localhost:8080/springmvc01_war_exploded/user/reg.do?username=root&password=123456&age=25
@RequestMapping("/reg.do")
public String reg(UserRegDTO userRegDTO) {System.out.println(userRegDTO);return "OK";
}

再加属性时就不用更改方法的参数

注意点:不要在封装的类型参数前面。使用Spring Boot Validation。

另外,你也可以将多个请求参数区分开来,一部分直接声明为处理请求的方法的参数,另一部分封装起来。

7. 关于RESTful(了解,不是绝对遵守)

百科资料:RESTFUL是一种网络应用程序的设计风格和开发方式,基于HTTP,可以使用XML格式定义或JSON格式定义。RESTFUL适用于移动互联网厂商作为业务接口的场景,实现第三方OTT调用移动网络资源的功能,动作类型为新增、变更、删除、查询所调用资源

返回的是XML或Json格式。动作类型  请求类型。

RESTful的设计风格的典型表现就是:将某些唯一的请求参数的值放在URL中,使之成为URL的一部分,例如https://www.zhihu.com/question/28557115这个URL的最后一部分`28557115` 应该就是这篇贴子的id值,而不是使用例如?id=28557115这样的方式放在URL参数中。

注意:RESTful只是一种设计风格,并不是一种规定,也没有明确的或统一的执行方式!

如果没有明确的要求,以处理用户数据为例,可以将URL设计为:

/users:查看用户列表
/users/9527:查询id=9527的用户的数据
/users/9527/delete:删除id=9527的用户的数据

RESTful     CSDN:名字/唯一字符/文章标号

正常风格

7.1 接受此请求的方法:

在RESTful风格的URL中,大多是包含了某些请求参数的值,在使用Spring MVC框架时,当需要设计这类URL时,可以使用{名称}进行占位,并在处理请求的方法的参数列表中,使用@PathVariable注解请求参数,即可将占位符的实际值注入到请求参数中!

// http://localhost:8080/springmvc01_war_exploded/user/3/info.do   //类的接受路径为/user ..
@GetMapping("/{id}/info.do")
public UserVO info(@PathVariable Long id) {System.out.println("即将查询 id = " + id + " 的用户的信息……");UserVO userVO = new UserVO();userVO.setUsername("chengheng");userVO.setPassword("1234567890");userVO.setEmail("chengheng@qq.com");return userVO;
}

提示:在以上代码中,URL中使用的占位符是{id},则方法的参数名称也应该是id,就可以直接匹配上!如果无法保证这2处的名称一致,则需要在@PathVariable注解中配置占位符中的名称,例如:

@GetMapping("/{userId}/info.do")
public UserVO info(@PathVariable("userId") Long id) {// ...
}

在使用{}格式的占位符时,还可以结合正则表达式进行匹配,其基本语法是:

{占位符名称:正则表达式}

400是没接收先判断,404接受了判断,找资源。

当设计成以上URL时,仅当占位符位置的是纯数字的URL才会被匹配上,如果不是纯数字的刚出现404错误页面。

并且,以上模式的多种不冲突的正则表达式是可以同时存在的,例如:

以下方法重载了。所以可以接受不同的值。

@GetMapping("/{id:[0-9]+}/info.do")
public UserVO info(@PathVariable Long id) {System.out.println("即将查询 id = " + id + " 的用户的信息……");// ...
}@GetMapping("/{username:[a-zA-Z]+}/info.do")
public UserVO info(@PathVariable String username) {System.out.println("即将查询 用户名 = " + username + " 的用户的信息……");// ...
}

两个有交集的正则表达式,会导则500错误。

Ambiguos

甚至,还可以存在不使用正则表达式(不知道是匹配正则还是正常的输入。),但是URL格式几乎一样的配置:  这时需要写一个标记路径为list  的方法,会优先匹配。

// http://localhost:8080/springmvc01_war_exploded/user/list/info.do
@GetMapping("/list/info.do")
public UserVO list() {System.out.println("即将查询 用户的列表 的信息……");// ...
}@GetMapping("/{username:[a-zA-Z]+}/info.do")
public UserVO info(@PathVariable String username) {System.out.println("即将查询 用户名 = " + username + " 的用户的信息……");// ...
}

题外话:

Firefox 可以展示json数据,Chrome 需要安装Json View插件

附:关于POJO

所有用于封装属性的类型都可以统称为POJO。  例如上面的userVO  user DTO

常见的POJO后缀有:BO、DO、VO、DTO等,不同的后缀表示不同的意义,例如:VO = Value Object / View Object  页面展示 ,DTO = Data Transfer Object  用户信息 ……

VO表示给客户端数据,DTO表示向客户端拿。

在一个项目中,哪些情景下使用哪种后缀并没有统一的规定,通常是各项目内部决定。

注意:在为封装属性的类进行命名时,以上BO、DO、VO、DTO等这些后缀的每一个字母都应该是大写的!

使用不同的DTO。登录注册,更改密码

8、关于响应正文的结果类型

当响应正文返回值为自定义的数据类型时,则Spring  MVC会调用jackson-databind依赖的转换器,就可以将结果装换为JSON格式的字符串!

通常在项目开发中,会定义一个“通用”的数据类型?(包含多个表单提交参数的)。无论哪个控制器处理都会返回一个此类型。

好处:————统一。(我的Spring Boot项目中的User  Product...)

在返回类中  定义一个包含对象数据的属性。

public class XXX <T>{  //类名一般JsonResultprivate Integer state;//状态代码 例如 1表示成功   2密码错误等等private String username;private String password;private String nick;private String message;   //返回文本信息,客户端直接用,不用再自定义。//如果定义一个对象属性定义泛型。      private T  data;  //响应给客户端的数据。
}
/*
泛型和object的区别   泛型定死了   object都可以放任意数据。
*/生成get set  生成get set  生成get set

控制器

@GetMapper("/{id:[0-9]+}/info.do")
public JsonResult<UserVO> info (@PathVariable Long id){UserVO userVO=new UserVO()userVO .setUsername("nihao");userVO .setpassword("nihao");userVO .setNick("nihao");JsonResult<UserVO> js=new  JsonResult();    JsonResult.setData(userVO);JsonResult.setstata(20000)   //自己定义一些数字有意义。参考响应代码。  每个数字开头有一定内容。1字开头   2字开头表示   3字开头表示一类。(20000表示某类问题 自己定义)return js;}

当不关心使用的泛型是什么时,例如:删除、登录、等 不用返回数据时。

泛型指定为  Void

@GetMapper("/reg.do")
public JsonResult<Void> reg (UserDTO userDTO){JsonResult<Void> js=new  JsonResult();    //自己定义一些数字有意义。参考响应代码。  每个数字开头有一定内容。1字开头   2字开头表示   3字开头表示一类。(20000表示某类问题 自己定义)JsonResult.setstata(20000)  return js;}

state 代码语义的问题:20000到底表示什么。

阿里开发手册准则规定:

 所以在JsonResult  中加静态变量,但是需要写很多, 二、set方法仍然可以添加 数字,可以不使用变量。(因为只定义了属性,并没有改变方法。)

public class XXX <T>{  //类名一般JsonResultpublic static final Integer OK=20000private Integer state;//状态代码 例如 1表示成功   2密码错误等等private String username;private String password;private String nick;private String message;   //返回文本信息,客户端直接用,不用再自定义。//如果定义一个对象属性定义泛型。      private T  data;  //响应给客户端的数据。
}
/*
泛型和object的区别   泛型定死了   object都可以放任意数据。
*/生成get set  生成get set  生成get set

使用枚举:           限定类型。

可以规定的能列出来的,能够穷举的。

ok(20000)报错类似方法,需要加上State的方法,类似构造方法

控制器中

还是无法阻止输入数字!!!      所以将设置state值的方法私有化,使用重载只允许输入State。

public enum State{OK(20000),ERR_PASSWORD(40040);Integer value;State(Integer s){this.value=s;}Integer getValue(){return value;}}public void setState(State state){this.state=state.getValue();//前面使用构造方法注入了一个Integer,getValue得到值}

控制器中更改:.ok   Void表示无,着里表示无对象  不需要传对象数据。

简化代码:重写构造方法。构造方法就是为了属性赋值存在的,另外规定必须加上某个值

public JsonResult (State state){this.state=state.getValue();}

控制器中

再简化:  需要将上面构造方法私有化  保证只能调用方法得到对象  不能自己new。。

public static JsonResult<Void> ok(){JsonResult<Void> jsonResult=new JsonResult<>();jsonResult.state=State.OK.getValue();return jsonResult;}//静态方法用到了泛型  需要加泛型。类中有泛型使用,就得使用泛型。
public static<T> JsonResult<Void> ok(T data){JsonResult<Void> jsonResult=new JsonResult<>();jsonResult.state=State.OK.getValue();jsonResult.data=data;return jsonResult;}

简化上面代码:

//高度重合的方法,无参调用有参。
public static JsonResult<Void> ok(){return jsonResult.ok(null);}//静态方法使用有泛型  需要加泛型。静态方法独立于类    类加了泛型  静态方法需要加泛型
public static<T> JsonResult<Void> ok(T data){JsonResult<Void> jsonResult=new JsonResult<>();jsonResult.state=State.OK.getValue();jsonResult.data=data;return jsonResult;}

控制器:返回值为ok方法的返回值。          (有个坏处:只能使用ok、状态的值)

再加上表示失败的静态方法

public static JsonResult<Void> fail(State state, String message) {JsonResult<Void> jsonResult = new JsonResult<>();jsonResult.state = state.getValue();jsonResult.message = message;return jsonResult;}

控制器中:登录案例:后端写入信息可以规定不同客户端得到相同内容,不用前端做处理。

返回值为一个装着状态和信息的JsonResult对象。

// 测试路径http://localhost:8080/springmvc01_war_exploded/user/login.do?username=root&password=123456@RequestMapping("/login.do")public JsonResult<Void> login(String username, String password) {username.toString();System.out.println("username = " + username + ", password = " + password);// 假设 admin / 888888 是正确的 用户名 / 密码// 判断用户名if ("admin".equals(username)) {// 用户名正常,判断密码if ("888888".equals(password)) {// 密码也正确,登录成功return JsonResult.ok();} else {// 密码错误String message = "登录失败,密码错误!";return JsonResult.fail(ERR_PASSWORD, message);}} else {// 用户名不存在String message = "登录失败,用户名不存在!";return JsonResult.fail(ERR_USERNAME, message);}}

还是无法阻止setState输入数字!!!!!!!!!!无法避免的,已经做了规范只能输入枚举的State  ,如果写代码的工作人员 恶意传入  建议开除

9、统一异常处理

Java学习篇——异常处理机制_张小白学Java的博客-CSDN博客

try catch 才叫处理异常

throw 叫抛出异常。
npe  NPE空指针异常简写。

出现某个异常时,一起处理不用写多个try catch。

Spring MVC框架提供了统一处理异常的机制,使得特定种类的异常对应一段特定的代码,后续,当编写代码时,无论在任何位置,都可以将异常直接抛出,由统一处理异常的代码进行处理即可!

关于统一处理异常,需要自定义方法对异常进行处理,关于此方法:

  • 注解:需要添加@ExceptionHandler注解
  • 访问权限:应该是公有的,因为框架自己调用。
  • 返回值类型:可参考处理请求的方法的返回值类型
  • 方法名称:自定义
  • 参数列表:必须包含1个异常类型的参数,并且可按需添加HttpServletRequestHttpServletResponse等少量特定的类型的参数,不可以随意添加参数

    例如:  (写在某个类中只能作用于当前类

    @GetMapper(“/npe.do”)
    public String npe(String name){name.toString()   //前端客户端没有传参数时将发生空指针异常。return "ok";
    }@ExceptionHandler
    public String handleException(NullPointerException e) {return "Error, NullPointerException!";
    }

    需要注意:以上处理异常的代码,只能作用于当前控制器类中各个处理请求的方法,对其它控制器类的中代码并不产生任何影响,也就无法处理其它控制类中处理请求时出现的异常!


    (关于继承: 不继承注解,不继承静态,不继承构造方法)
    1、初级做法:继承父类的处理方法。

    public class BaseController{@ExceptionHandLerpublic String HandleException(nullpointerException e){return “Error NullPointerException”}
    }其他控制器继承此类

    2、为保证更合理的处理异常,应该:

  • 将处理异常的代码放在专门的类中
  • 在此类上添加@ControllerAdvice注解
    • 由于目前主流的响应方式都是“响应正文”的,则可以将@ControllerAdvice替换为@RestControllerAdvice
  • 所以,可以创建GlobalExceptionHandler类,代码如下:
    表示@ResponseBody        @ControlleAdvice合并
    加了@RestControllerAdvice 控制器的类都会使用类中此方法。

    @RestControllerAdvice
    public class GlobalExceptionHandler {@ExceptionHandlerpublic String handleException(NullPointerException e) {return "Error, NullPointerException!";}}

    具体的实现大致如下:真实更复杂:  当控制器类对象调用 npe 方法  时出现异常

  • try住   catch  得到异常类型   处理时调用 GlobaLExceptionHandler的处理方法。

    try {userController.npe();
    } catch (NullPointerException e) {globalExceptionHandler.handleException(e);
    }

    关于以上处理的方法的参数中的异常类型,将对应Spring MVC框架能够统一处理的异常类型,例如将其声明为Throwable时,所有异常都可被此方法进行处理!但是,在处理过程中,应该判断当前异常对象所归属的类型  返回之前写if判断,以针对不同类型的异常进行不同的处理!


    处理方法可以写多个

    @RestControllerAdvice
    public class GlobalExceptionHandler {@ExceptionHandlerpublic String handleException(NullPointerException e) {return "Error, NullPointerException!";}@ExceptionHandlerpublic String handleNullPointerException(NullPointerException e) {return "Error, NullPointerException!";}@ExceptionHandlerpublic String handleNumberFormatException(NumberFormatException e) {return "Error, NumberFormatException!";}@ExceptionHandlerpublic String handleThrowable(Throwable e) {e.printStackTrace();  //打印日志方便查看是什么错误return "Error, Throwable!";
    }}

    并且,如果某个异常能够被多个方法处理(异常类型符合多个处理异常的方法的参数类型),则优先执行最能精准匹配的处理异常的方法,例如,当出现NullPointerException时,将执行handleNullPointerException()而不会执行handleThrowable()
    在开发实践中,通常都会有handleThrowable()方法,以避免某个异常没有被处理而导致500错误!


  • 关于@ExceptionHandler注解,可用于表示被注解的方法是用于统一处理异常的,而且,可用于配置被注解的方法能够处理的异常的类型,其效力的优先级高于在方法的参数上指定异常类型。

    @ExceptionHandler注解源代码:  注释说明,如果没有标记是哪种异常,则使用方法参数的异常类型,标记了接受时使用注解的异常类型,数组表示可写多个异常的class类型。

  • 一个:@ExceptionHandler(ClassCastException.class)

  • 两个以及多个:@ExceptionHandler({ClassCastException.class,NullPointerException.class})


  • 在开发实践中,建议为每一个@ExceptionHandler配置注解参数,在注解参数中指定需要处理异常的类型,而处理异常的方法的参数直接使用Throwable即可。

  • @ExceptionHandler({NullPointerException.class,ClassCastException.class
    })
    public String handleNullPointerException(Throwable e) {return "Error, NullPointerException or ClassCastException!";
    }@ExceptionHandler(NumberFormatException.class)
    public String handleNumberFormatException(Throwable e) {return "Error, NumberFormatException!";
    }@ExceptionHandler(Throwable.class)
    public String handleThrowable(Throwable e) {return "Error, Throwable!";
    }


10. 拦截器(Interceptor)(框架会自动执行 再此只做了解)

  • 拦截器
  • 在Spring MVC框架中,(优势)拦截器是可以运行在所有控制器处理请求之前和之后的一种组件,并且,如果拦截器运行在控制器处理请求之前,还可以选择对当前请求进行阻止或放行。
  • 注意:拦截器的目的并不是“拦截下来后阻止运行”,更多的是“拦截下来后执行某些代码”,其优势在于可作用于若干种不同请求的处理过程,即写一个拦截器,就可以在很多种请求的处理过程中被执行。(类似火车站过安检.......符合的通过 ..........而不是都不通过)
  • 只要是若干种不同的请求过程中都需要执行同样的或高度相似的代码,都可以使用拦截器解决,典型的例如验证用户是否已经登录等等。每次查看信息,更改密码, 查看订单等都需要验证是否登录。
  • 接口中可以直接实现的方法,不只有抽象方法。
  • 直接实现方法时为了方便  不用的方法不用重写。    (早期都是 写一个类直接实现 接口 方法  在使用时继承这个类 任意重写类的方法。)
  • public interface WebMvcConfigurer {@Nullabledefault Validator getValidator() {return null;}@Nullabledefault MessageCodesResolver getMessageCodesResolver() {return null;}
    }
    
  • 使用拦截器————————————————

  • 当需要使用拦截器时,首先,需要自定义类,实现HandlerInterceptor接口,
  • 实现接口后   Alt+insert ——》》implements methods
    例如:
  • 实现时  不知道方法干嘛用的   打印方法名。了解什么时候出现,做什么的。
  • 当需要使用拦截器时,首先,需要自定义类,实现HandlerInterceptor接口,例如:实现接口后   Alt+insert ——》》implements methodspublic class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("LoginInterceptor.preHandle()");return false;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("LoginInterceptor.postHandle()");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("LoginInterceptor.afterCompletion()");}
    }
  • 每个拦截器都必须注册才会被启用,注册过程通过重写WebMvcConfigure接口中的addInterceptors()方法即可(增加拦截器),例如:
  • 再次就是在配置类SpringMvcConfig重写。   Alt +insert。
  • 参数:拦截器注册工具。
  • addInterceptor 添加拦截器
  • addPathPatterns拦截器的方法  添加拦截路径。 可0 个 ,可多个    ctrl+p  快速看参数列表。
  • 多个可写list集合
  • 在编写路径值时,可以使用*作为通配符,例如配置为/user/*,则可以匹配/user/login.do/user/reg.do等所有直接在/user下的路径,(直接路径下)但不能匹配/user/1/info.do
  • 如果需要匹配若干层级,必须使用2个连续的星号,例如配置为/user/**
  • 一旦使用通配符,就有可能导致匹配的范围过大,例如配置为/user/**时,还可以匹配到/user/reg.do(注册)和/user/login.do(登录),如果此拦截器是用于“验证用户是否登录”的,则不应该对这2个路径进行处理,那么,配置拦截器时,还可以在链式语法中调用excludePathPattern()方法,以添加“排除路径”(例外)。
@Configuration // 此注解不是必须的
@EnableWebMvc
@ComponentScan("cn.tedu.springmvc") // 必须配置在当前配置类,不可配置在Spring的配置类
public class SpringMvcConfig implements WebMvcConfigurer {//List<String> list =new ArrayList();//list.add(路径“/user/login.do”);@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/user/login.do");}//排除不拦截的路径//registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/user/**").excludePathPatterns("/user/reg.do", "/user/login.do");}

当我们输入  ....../user/login.do   进行访问时,在浏览器窗口中将看到一片空白,在Tomcat控制台可以看到preHandle()方法已经执行。

当把拦截器中preHandle()方法的返回值改为true时,在Tomcat控制台可以看到依次执行了preHandle() > 控制器中处理请求的方法 > postHandle() > afterCompletion()

  preHandle()方法的返回值为true时,表示“放行”,为false时,表示“阻止  检查”。

pre处理请求之前

post处理请求之后

after  发送响应之后。

拦截器和过滤器

java组件     spring组件

过滤器刚刚收到请求

拦截器收到请求过一会


注意:SpringMVC底层的逻辑请看B站


注意:关于SpringMVC  你该知道

关于Spring MVC框架,你应该:

  • 理解Spring MVC框架的作用

    • 接收请求,响应结果,处理异常……
  • 掌握创建基于Maven的运行在Tomcat的Webapp
  • 认识基础的依赖项
    • spring-webmvcjavax.servlet-apijackson-databind
  • 掌握配置Spring MVC的运行环境(使得控制器能接收到请求)
  • 掌握以下注解的使用:
    • @Controller / @RestController
    • @ResponseBody
    • @RequestMapping / @GetMapping / @PostMapping ...
    • @RequestParam / @PathVariable
    • @ExceptionHandler / @ControllerAdvice / @RestControllerAdvice
    • @EnableWebMvc
  • 掌握接收请求参数的方式
    • 将请求参数直接声明在处理请求的方法的参数列表中
    • 将若干个请求参数进行封装,并将封装的类型声明在处理请求的方法的参数列表中
    • 如果是URL中的路径,则需要使用@PathVariable
  • 掌握响应JSON格式的正文的做法
    • 处理请求的方法必须添加@ResponseBody,或当前控制器类添加@ResponseBody,或当前控制器类添加@RestController
    • 在Spring MVC配置类上添加@EnableWebMvc
    • 在项目的pom.xml中添加了jackson-databind
    • 处理请求的方法返回自定义的数据类型
  • 掌握响应JSON格式的正文时,统一的响应类型的类的设计JsonResult  信息类。
  • 了解RESTful风格     (信息作为url的一部分)
  • 掌握统一处理异常      @RestControllerAdvice         @ExceptionHandler
  • 掌握拦截器的创建与配置

2开头(请求成功)表示成功处理了请求的状态代码。

200  (成功)  服务器已成功处理了请求。通常,这表示服务器提供了请求的网页。

201  (已创建)  请求成功并且服务器创建了新的资源。

202  (已接受)  服务器已接受请求,但尚未处理。

203  (非授权信息)  服务器已成功处理了请求,但返回的信息可能来自另一来源。

204  (无内容)  服务器成功处理了请求,但没有返回任何内容。

205  (重置内容)服务器成功处理了请求,但没有返回任何内容。

206  (部分内容) 服务器成功处理了部分GET请求。

3开头( 请求被重定向)表示要完成请求,需要进一一步操作。 通常,这些状态代码用来重定向。

300  (多种选择)  针对请求,服务器可执行多种操作。服务器可根据请求者(user agent)选择-项操作, 或提供操作列表供请求者选择。

301  (永久移动)  请求的网页已永久移动到新位置。服务器返回此响应(对GET或HEAD请求的响应)时,会自动将请求者转到新位置。

302  (临时移动)  服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。

303  (查看其他位置)请求者应当对不同的位置使用单独的GET请求来检索响应时,服务器返回此代码。

304  (未修改) 自从上次请求后,请求的网页未修改过。服务器返回此响应时,不会返回网页内容。

305  (使用代理)请求者只能使用代理访问请求的网页。如果服务器返回此响应,还表示请求者应使用代理。

307  (临时重定向)  服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。

4开头( 请求错误)这些状态代码表示请求可能出错,妨碍了服务器的处理。、(客户端)

400  (错误请求)服务器不理解请求的语法。

401  (未授权)请求要求身份验证。对于需要登录的网页,服务器可能返回此响应。

403  (禁止)服务器拒绝请求。

404  (未找到)服务器找不到请求的网页。

405  (方法禁用)禁用请求中指定的方法。

406  (不接受)无法使用请求的内容特性响应请求的网页。

407  (需要代理授权)此状态代码与401 (未授权)类似,但指定请求者应当授权使用代理。

408  (请求超时)  服务器等候请求时发生超时。

409  (冲突)  服务器在完成请求时发生冲突。服务器必须在响应中包含有关冲突的信息。

410  (已删除)  如果请求的资源已永久删除,服务器就会返回此响应。

411  (需要有效长度)服务器不接受不含有效内容长度标头字段的请求。

412 (未满足前提条件)服务器未满足请求者在请求中设置的其中一个前提条件。

413  (请求实体过大)服务器无法处理请求,因为请求实体过大,超出服务器的处理能力。

414  (请求的URI过长)请求的URI(通常为网址)过长,服务器无法处理。

415  (不支持的媒体类型)请求的格式不受请求页面的支持。

416  (请求范围不符合要求)如果页面无法提供请求的范围,则服务器会返回此状态代码。

417  (未满足期望值)服务器未满足"期望"请求标头字段的要求。

5开头(服务器错误)这些状态代码表示服务器在尝试处理请求时发生内部错误。这些错误可能是 服务器本身的错误,而不是请求出错。     (服务端)

500  (服务器内部错误)  服务器遇到错误,无法完成请求。

501  (尚未实施)服务器不具备完成请求的功能。例如,服务器无法识别请求方法时可能会返回此代码。

502  (错误网关)服务器作为网关或代理,从上游服务器收到无效响应。

503  (服务不可用)服务器目前无法使用( 由于超载或停机维护)。通常,这只是暂时状态。

504  (网关超时)  服务器作为网关或代理,但是没有及时从上游服务器收到请求。

505  (HTTP版本不受支持)服务器不支持请求中所用的HTTP协议版本。

Java中级篇——Spring MVC 是什么(附加响应状态代码列举)相关推荐

  1. Java框架篇---spring aop两种配置方式

    Java框架篇---spring aop两种配置方式 第一种:注解配置AOP 注解配置AOP(使用 AspectJ 类库实现的),大致分为三步:  1. 使用注解@Aspect来定义一个切面,在切面中 ...

  2. Spring MVC集成slf4j-logback - 我想跟代码谈谈 - 博客频道 - CSDN.NET

    Spring MVC集成slf4j-logback - 我想跟代码谈谈 - 博客频道 - CSDN.NET

  3. Java web学习——Spring MVC项目实例,三层架构通过JDBC链接SQLServer2012

    Spring MVC架构原理?原理篇 1.新建项目 File-New-Other,选择Dynamic web project 项目建好后的目录结构如下: 2.导入jar包 导入spring mvc框架 ...

  4. Java Web(11) Spring MVC 返回Json

    2019独角兽企业重金招聘Python工程师标准>>> 1. 首先是对Spring mvc 进行xml配置 <?xml version="1.0" enco ...

  5. 如何用Java类配置Spring MVC(不通过web.xml和XML方式)

    DispatcherServlet是Spring MVC的核心,按照传统方式, 需要把它配置到web.xml中. 我个人比较不喜欢XML配置方式, XML看起来太累, 冗长繁琐. 还好借助于Servl ...

  6. java地址映射关系,Spring MVC——基础(简介,使用,地址映射)

    "大佬们"嘴中的SSH,SSM框架,我这种小白终于解除到第二个S了,关于Spring MVC框架,根据最近的学习发现,还是有很多不足和需要加强巩固的地方,所以,通过总结博客的方式将 ...

  7. [Java] Maven 建立 Spring MVC 工程

    GIT: https://github.com/yangyxd/Maven.SpringMVC.Web 1. 建立 WebApp 工程 下一步: 下一步: 选择 maven-archetype-web ...

  8. Java面试题--spring mvc

    什么是Spring MVC ?简单介绍下你对springMVC的理解? Spring MVC是一个基于MVC架构的用来简化web应用程序开发的应用开发框架,它是Spring的一个模块,无需中间整合层来 ...

  9. java 设置 cors,Spring MVC配置CORS

    Spring Framework 从4.2开始支持配置CORS. Spring MVC支持CORS的范围包括:方法级别配置CORS 全局配置CORS 方法级别配置CORS 使用注解@CrossOrgi ...

最新文章

  1. 机器学习与高维信息检索 - Note 3 - 逻辑回归(Logistic Regression)及相关实例
  2. TCP建立连接三次握手及其断开过程
  3. 【渝粤教育】国家开放大学2018年秋季 0505-22T护理学基础 参考试题
  4. Java基本语法(14)--for循环结构
  5. sublime text 2快捷键总结
  6. 解决Could not load file or assembly CefSharp.Core.dll的问题
  7. shell脚本中定义路径变量出现的BUG
  8. python函数参数为文件名_从零开始第5步:Python 函数和模块
  9. java 6个逆向工程软件
  10. 使用hydra离线破解windows密码
  11. 8.0强行转换后变成了7_南方Cass软件坐标转换方法!
  12. python爬虫学习爬取股票数据
  13. c语言wakeup函数,关于RTC时钟RTC_Set_WakeUp(u32 wksel,u16 cnt)函数的疑惑
  14. cloudreve 开源私有网盘(带离线下载)
  15. Vegas怎么制作古装墨迹笔刷开场效果
  16. 生产环境Centos LNMP编译安装nginx-1.6 MySQL-5.6 php-5.5
  17. 桌面音乐频谱linux,X Music Spectrum(音乐频谱桌面特效)
  18. OPC及OPC服务器的设计与实现
  19. JAVA常见基础问题
  20. “传统文化传承人暨未来经济人才研修班”首期在山东省成功举办

热门文章

  1. 树莓派3.5寸屏幕驱动安装
  2. 第八届山东省大学生网络安全技能大赛部分Writeup
  3. 安卓用于组件传递参数的对象是_[南开大学]18秋学期(1709、1803、1809)《手机应用软件设计与实现》在线作业 ......
  4. 三国霸王大陆服务器维护,霸王大陆BUG一览各位小心注意玩儿霸王时候的操作
  5. python入门教程jupyter_jupyter notebook快速入门及使用详解
  6. 通过Python的fitz库提取pdf中的图片
  7. 智慧水务综合管理平台、智慧水务信息化、供水信息化管理—山西河曲县应用案例
  8. 51单片机IO口介绍
  9. Canal监听阿里云RDS Mysql踩坑
  10. 小程序入门案例某大妈sign