Spring MVC

[复制链接]
发表于 2025-10-9 22:50:44 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
一.哀求

1.创建毗连

① @RestController
@RestController = @Controller + @ResponseBody
@Controller:界说⼀个控制器,Spring 框架启动时加载,把这个对象交给Spring管理,属于Ioc&Di的内容。
@ResponseBody:界说返回的数据格式为⾮视图, 返回⼀个 text/html信息
如今的我们只须要明确必须要加 @RestController 这个注解就可以了,它是我们启动步伐必须要加的。
② @RequestMapping利用
1.@RequestMapping 是 Spring Web MVC 应⽤步伐中最常被⽤到的注解之⼀,它是⽤来注册接⼝的路由映射的,就是来形貌访问路径的,通过这个路径我们就可以访问到这个接口。
2.@RequestMapping 既可修饰类,也可以修饰⽅法,代码案比方下:
  1. @RequestMapping("/user")
  2. @RestController
  3. public class UserController {
  4.     @RequestMapping("/sayHi")
  5.     public String sayHi(){
  6.         return "hello,Spring MVC";
  7.     }
  8. }
复制代码
③ @RequestMapping是GET还是POST哀求
1.我们@RequestMapping默认不写要求是什么哀求的话,两个哀求都是可以的。
2.假如必须要求指定是啥范例的哀求,我们可以根据下面的代码格式写:value是路径,method是哀求方式。
  1. @RestController
  2. public class UserController {
  3.     @RequestMapping(value = "/getRequest",method= RequestMethod.POST)
  4.     public String Hello(){
  5.         return "get request...";
  6.     }
  7. }
复制代码
3.另有@GetMapping,@PostMapping等一些可以写url路径这些和@RequestMapping用法一样知识指定了哀求的方式。
get和post哀求的区别 get哀求没有哀求体(body) get哀求的参数一样寻常是在url背面 post哀求是有body的 可以在body内里传入json格式的哀求参数,纵然设置了Content-Type 对 get 哀求的参数格式也没有影响,get哀求的参数不在body中 
2.哀求

①通报参数
  1. @RequestMapping("/m2")
  2. public Object method2(String name, String password) {
  3.     return "接收到参数name:" + name + ", password:" + password;
  4. }
复制代码
留意:
1.前端通报通报参数的时间记得参数名对应。
2.参数范例发起写成包装类,由于包装类可以不继承参数,假如利用java内置数据范例,没有继承到参数就会报错。
②通报对象
1.假如参数⽐较多时, ⽅法声明就须要有许多形参. 而且后续每次新增⼀个参数, 也须要修改⽅法声明. 我们不妨把这些参数封装为⼀个对象.然后前端通报参数的时间也只须要知道对象内里的属性,然后对属性名举行传参就可以了。
  1. //Person这个类的代码就不写了
  2. @RequestMapping("/m3")
  3. public Object method3(Person p){
  4.     return p.toString();
  5. }
复制代码
留意:Spring 会根据参数名称⾃动绑定到对象的各个属性上, 假如某个属性未通报, 则赋值为null(根本范例则赋值为默认初识值, ⽐如int范例的属性, 会被赋值为0)。
③后端参数重定名
  1. @RequestMapping("/m4")
  2. public Object method_4(@RequestParam("time") String createtime) {
  3.     return "接收到参数createtime:" + createtime;
  4. }
复制代码
上面代码的意思是:前端通报参数的时间用time,后端利用参数的时间利用createtime;此时前端就不能利用createtime举行通报参数了;这时time也变成了必传的参数。
假如要设置成非必须传的可以看以下代码:
  1. @RequestMapping("/m4")
  2. public Object method4(@RequestParam(value = "time", required = false) String
  3. createtime) {
  4.     return "接收到参数createtime:" + createtime;
  5. }
复制代码
④通报数组
  1. @RequestMapping("/m5")
  2. public String method5(String[] arrayParam) {
  3.     return Arrays.toString(arrayParam);
  4. }
复制代码
前端通报参数的时间可以对 arrayParam举行多次赋值。
⑤通报聚集@RequestParam(加了这个spring MVC会主动帮我们分析,这个在苍穹外卖出现过,这里必须好坏json对象)
聚集参数:和数组类似, 同⼀个哀求参数名有为多个, 且须要使⽤ @RequestParam 绑定参数关系。代码格式如下:
  1. @RequestMapping("/m6")
  2. public String method6(@RequestParam List<String> listParam){
  3.     return "size:"+listParam.size() + ",listParam:"+listParam;
  4. }
复制代码
⑥通报json数据
1.吸收JSON对象, 须要使⽤ @RequestBody 注解
  1. @RequestMapping(value = "/m7")
  2. public Object method7(@RequestBody Person person) { //前端发送json对象过来,被Person接受
  3.     return person.toString();
  4. }
复制代码
2.JSON字符串和Java对象互转
   引入依靠:
  1. <dependency>
  2.     <groupId>com.fasterxml.jackson.core</groupId>
  3.     <artifactId>jackson-databind</artifactId>
  4.     <version>2.13.5</version>
  5. </dependency>
复制代码
    转换的代码:
  1. public class JSONUtils {
  2.     private static ObjectMapper objectMapper = new ObjectMapper();
  3.     public static void main(String[] args) throws JsonProcessingException {
  4.         Person person = new Person();
  5.         person.setId(5);
  6.         person.setName("zhangsan");
  7.         person.setPassword("123456");
  8.         //对象转为JSON字符串
  9.         String jsonStr = objectMapper.writeValueAsString(person);
  10.         System.out.println("JSON字符串为:"+jsonStr);
  11.         //JSON字符串转为对象
  12.         Person p = objectMapper.readValue(jsonStr,Person.class);
  13.         System.out.println("转换的对象id:"+p.getId()+",name:"+p.getName()+",password:"+p.getPassword());
  14.     }
  15. }
复制代码
⑦获取URL中参数@PathVariable
须要利用@PathVariable这个注解
  1. @RequestMapping("/m8/{id}/{name}")
  2. //如果@PathVariable中写了值那么url中就要对应,然后后端还是使用userName
  3. public String method8(@PathVariable Integer id, @PathVariable("name") String
  4. userName){
  5.     return "解析参数id:"+id+",name:"+userName;
  6. }
复制代码
⑧上传文件
  1. @RequestMapping("/m9")
  2. // 这里的@RequestPart相当于重命名,前端传参数的时候用file1后端使用文件的时候用file2
  3. public String getfile(@RequestPart("file1") MultipartFile file2) throws
  4. IOException {
  5.     //获取⽂件名称
  6.     String fileName = file2.getOriginalFilename();
  7.     //⽂件上传到指定路径,就是上传到服务器中指定的路径
  8.     file2.transferTo(new File("D:/temp/" + file2.getOriginalFilename()));
  9.     return "接收到⽂件名称为: "+fileName;
  10. }
复制代码
⑨获取Cookie/Session(逾期了,如今一样寻常利用jwt令牌)紧张是学习一下内里比力长的两个参数
设置和获取cookie:
  1. // 设置Cookie
  2. @GetMapping("/c1")
  3. public Result cookie1(HttpServletResponse response) {
  4.     response.addCookie(new Cookie(name: "login_username", value: "itheima"));
  5.     return Result.success();
  6. }
  7. // 获取Cookie
  8. @GetMapping("/c2")
  9. public Result cookie2(HttpServletRequest request) {
  10.     Cookie[] cookies = request.getCookies(); // 获取所有的Cookie
  11.     for (Cookie cookie : cookies) {
  12.         if (cookie.getName().equals("login_username")) { // 输出name为 login_username 的cookie
  13.             System.out.println("login_username: " + cookie.getValue());
  14.         }
  15.     }
  16.     return Result.success();
  17. }
复制代码
HttpServletRequest: 对象代表客⼾端的哀求,当客⼾端通过HTTP协议访问服务器时,HTTP哀求头中的全部信息都封装在这个对象中,通过这个对象提供的⽅法,可以得到客⼾端哀求的全部信息.
HttpServletResponse:对象代表服务器的相应.,HTTP相应的信息都在这个对象中,⽐如向客⼾端发送的数据,相应头,状态码等。通过这个对象提供的⽅法,可以得到服务器相应的全部内容。
设置和获取session:
  1. // 在session中存储数据
  2. @GetMapping("/s1")
  3. public Result session1(HttpSession session) {
  4.     log.info("HttpSession-s1: {}", session.hashCode());
  5.     session.setAttribute("loginUser", "tom"); // 在session中存储数据
  6.     return Result.success();
  7. }
  8. // 从HttpSession中获取数据
  9. @GetMapping("/s2")
  10. public Result session2(HttpServletRequest request) {
  11.     HttpSession session = request.getSession();
  12.     log.info("HttpSession-s2: {}", session.hashCode());
  13.     Object loginUser = session.getAttribute("loginUser"); // 从session中获取数据
  14.     log.info("loginUser: {}", loginUser);
  15.     return Result.success(loginUser);
  16. }
复制代码
⑩获取Header
获取Header也是从 HttpServletRequest 中获取:
  1. @RequestMapping("/param10")
  2. public String param10(HttpServletRequest request, HttpServletResponse response){
  3.     String userAgent = request.getHeader("User-Agent");
  4.     return name + ":"+userAgent;
  5. }
复制代码
也可以直接给参数添加 @RequestHeader 这个注解,就可以得到哀求头中的数据
二.相应

①返回静态页面(只有这个用@Controller,背面的②③都是利用 @RestController,④⑤和方法的返回内容不相干了而是设置http协议内里返回的内容)
我们须要把之前用的 @RestController 换成 @Controller 由于 @RestController = @Controller + @ResponseBody 。@ResponseBody界说返回的数据格式为⾮视图, 返回⼀个 text/html信息,以是我们须要返回页面就用@Controller。
@ResponseBody 既是类注解, ⼜是⽅法注解
假如作⽤在类上,表⽰该类的全部⽅法,返回的都是数据,假如作⽤在⽅法上,表⽰该⽅法返回的是数据。假如⼀个类的⽅法⾥,既有返回数据的,⼜有返回⻚⾯的,就把 @ResponseBody 注解添加到对应的⽅法上即可。
②返回HTML片断
假如返回的好坏对象大概非聚集,返回的格式为text/html。
③返回json
假如后端返回的是对象大概聚集,spring会把返回者转换成json对象。但是假如不是也可以强行转换成json对象。
  1. @RequestMapping(value = "/publish",produces = "application/json") // 添加了这个可把返回的对象强行转换成json格式的
  2.     public String publish(@RequestBody MessageInfo messageInfo) {
  3.         if(!StringUtils.hasLength(messageInfo.getMessage())
  4.         || !StringUtils.hasLength(messageInfo.getTo())
  5.         || !StringUtils.hasLength(messageInfo.getFrom()) ){
  6.             return "{"ok" : 0}";
  7.         }
  8.         messageInfoList.add(messageInfo);
  9.         return "{"ok" : 1}";
  10.     }
复制代码
④设置状态码
  1. @RequestMapping(value = "/setStatus")
  2. @ResponseBody
  3. public String setStatus(HttpServletResponse response) {
  4.     response.setStatus(401); //设置状态码
  5.     return "设置状态码成功";
  6. }
复制代码
⑤设置其他Header 
在原生的@RequestMapping已经存在了许多的Header了,但是是我们偶然以为不都我们可以本身设置Header(此中我用过的参数有:value(URL路径),method(哀求的范例),produces(返回的内容范例))。
设置其他Header的话,须要使⽤Spring MVC的内置对象HttpServletResponse 提供的⽅法来进⾏设置。
  1. @RequestMapping(value = "/setHeader")
  2. @ResponseBody
  3. public String setHeader(HttpServletResponse response) {
  4.     response.setHeader("MyHeader","MyHeaderValue");
  5.     return "设置Header成功";
  6. }
复制代码
void setHeader(String name, String value) 设置⼀个带有给定的名称和值的 header。假如 name 已经存在,则覆盖旧的值。
三.拦截器

1.界说拦截器
① 实现HandlerInterceptor接⼝,并重写其全部⽅法
  1. @Slf4j
  2. @Component  // 交给spring的ioc容器管理
  3. public class LoginInterceptor implements HandlerInterceptor {
  4.     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  5.         log.info("LoginInterceptor ⽬标⽅法执⾏前执⾏..");
  6.         return true;  // 这里写逻辑,返回true放行,返回false拦截
  7.     }
  8.     public void postHandle(HttpServletRequest request, HttpServletResponseresponse, Object handler, ModelAndView modelAndView) throws Exception {
  9.         log.info("LoginInterceptor ⽬标⽅法执⾏后执⾏");
  10.     }
  11.     public void afterCompletion(HttpServletRequest request,HttpServletResponse response,    Object handler, Exception ex) throws Exception {
  12.         log.info("LoginInterceptor 视图渲染完毕后执⾏,最后执⾏");
  13.     }
  14. }
复制代码
留意:preHandle 方法返回 true 放行,返回false 拦截。
2.注册设置拦截器
① 实现WebMvcConfigurer接⼝,并重写addInterceptors⽅法:
        addPathPatterns:添加拦截的路径
        excludePathPatterns:扫除要拦截的路径
  1. @Configuration  // 交给spring的ioc容器管理
  2. public class WebConfig implements WebMvcConfigurer {
  3.     //⾃定义的拦截器对象
  4.     @Autowired
  5.     private LoginInterceptor loginInterceptor;
  6.     public void addInterceptors(InterceptorRegistry registry) {
  7.         //注册⾃定义拦截器对象
  8.         registry.addInterceptor(loginInterceptor)
  9.                 .addPathPatterns("/**");//设置拦截器拦截的请求路径( /** 表⽰拦截所有请求)
  10.                 .excludePathPatterns("/user/login");  // 设置拦截器不拦截的路径
  11.     }
  12. }
复制代码

四.全局非常处置处罚

统⼀非常处置处罚使⽤的是 @ControllerAdvice + @ExceptionHandler 来实现的,@ControllerAdvice 表⽰控制器关照类, @ExceptionHandler 好坏常处置处罚器,两个联合表⽰当出现非常的时间执⾏某个关照,也就是执⾏某个⽅法事故。
  1. @ResponseBody
  2. @ControllerAdvice
  3. public class ErrorAdvice {
  4.     @ExceptionHandler(Exception.class)  // 这个是接受异常的类型
  5.     public Object handler(Exception e) {
  6.         return Result.fail(e.getMessage());
  7.     }
  8.     @ExceptionHandler(NullPointerException.class)
  9.     public Object handler(Exception e) {
  10.         return Result.fail("发⽣NullPointerException:"+e.getMessage());
  11.     }
  12.     @ExceptionHandler(IndexOutOfBoundsException.class)
  13.     public Object handler(Exception e) {
  14.         return Result.fail("发⽣ArithmeticException:"+e.getMessage());
  15.     }
  16. }
复制代码
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表