SpringMVC好好学一(核心组件、参数绑定和注解)

SpringMVC好好学一(核心组件、参数绑定和注解)

大纲

  • 1、SpringMVC框架简介

  • 2、SpringMVC核心组件

  • 3、SpringMVC参数绑定

  • 4、SpringMVC的重要注解

1、SpringMVC框架简介

1.1、SpringMVC介绍

        SpringMVC是Spring的一个后续产品,,是Spring的一个子项目。SpringMVC是Spring为表述层开发提供的一套完备的解决方案,目前普遍使用SpringMVC作为javaEE项目表述层的首选方案。 备注:三层架构分为表述层,业务逻辑层,数据访问层,表述层是表示前台页面和后台servlet。

MVC是一种软件架构的思维,将软件按照模型,视图,控制器:
M:Model,模型层,指工程中的JavaBean,作用是处理数据 
V:View,视图层,指工程中的html或者jsp页面,作用是与用户进行交互,展示数据 
C:Controller,控制层,指工程中的Servlet,作用是接收请求和响应浏览器 

MVC工作流程:
1)用户通过视图层发送请求到服务器,在服务器中请求被Controller接收,
2)Controller调用相应的Model层处理请求,处理完毕将结果返回给Controller。
3)Controller再根据请求的结果找到相应的View视图,渲染数据后最终响应给浏览器

1.2、SpringMVC特点

        Spring MVC是Spring Framework的一部分,是基于Java实现MVC的轻量级Web框架。Spring MVC的特点:

- 轻量级,简单易学
- 高效,基于请求响应的MVC框架
- 与Spring兼容性好,无缝结合
- 约定优于配置
- 功能强大:RESTful、数据验证、格式化、本地化、主题等
- 简洁灵活

2、SpringMVC核心组件

  • DispatcherServlet -前端控制器,用于统一接收请求并分发,组织处理请求的流程
  • HandlerMapping -映射请求路径与处理请求的控制器
  • Controller -由开发人员创建的,实际处理请求的控制器
  • ModelAndView -Controllera组件处理完请求后得到的结果,由数据与视图名称组成
  • ViewResolver -视图解析器,可根据视图名称(由ModelAndView:返回)确定需要使用的视图组件

  • DispatcherServlet
DispatcherServlet是Spring MVC的核心控制器,它负责接收HTTP请求并将请求分发给处理器
。DispatcherServlet还负责处理多种类型的请求和响应,如HTTP请求和响应、FlashMap请
求和响应、WebSocket消息等。 

-如果是使用web.xml文件配置项目的Web环境的项目,需要显式的在web.xml配置它,例如映射的请求路径,并确保它是Web容器(例如Tomcat)在启动时就初始化的,并在初始化时会加载Spring环境        

-如果是使用Spring注解来配置Spring MVC环境的项目,则不需要直接配置它,而是通过自定义一个AbstractAnnotationConfigDispatcherServletlnitializer的子类来间接的配置,例如配置它映射的请求路径        

-如果是使用Spring Booti框架的Web项目,你甚至可以不需要知道它的存在,默认映射的请求路径是/*,当然,如果认为有必要的话,也可以配置为其它值
  • HandlerMapping
HandlerMapping负责将HTTP请求映射到处理器。它根据请求的URL和其他条件选择一个合适的
处理器,将请求转发给该处理器进行处理。

它是一个接口,Spring MVC框架内置了简单的实现类:

SimpleUrlHandlerMapping,用于映射请求路径与处理请求的控制器,但是,在实际应用
中,并不会直接使用这个实现,而是使用@RequestMapping注解,或进阶的@PostMappin
g、@DeleteMapping、@PutMapping、@GetMapping等注解,直接配置请求路径与处理请求的方法的映射关系
  • HandlerAdapter
HandlerAdapter负责调用处理器并将处理器的处理结果返回给DispatcherServlet。
它支持多种类型的处理器,如Controller、HttpRequestHandler、SimpleControllerHandlerAdapter等
  • ViewResolver
ViewResolver:视图解析器,可根据视图名称确定需要使用的视图组件
ViewResolver负责将处理器的处理结果转换为视图对象。它根据视图名称选择一个合适的视图,
将视图名称解析为视图对象,并将视图对象返回给DispatcherServlet。
Spring MVC 提供了多种 ViewResolver 的实现,如 InternalResourceViewResolver(用于解析 JSP 视图)、
FreeMarkerViewResolver(用于解析 FreeMarker 模板)、ThymeleafViewResolver(用于解析 Thymeleaf 模板)等。
  • ModelAndView
ModelAndView:Controller组件处理完请求后得到的结果,由数据与视图名称组成  
在实际开发中,由于Spring MVC提供了更加便捷的API,通常并不直接使用这种类型作为方法的返回值,当需要转发数据时,
可以在方法的参数列表中添加ModelMap对象用于封装需要转发的数据,并使用String类型的返回值表示视图名称,
如果需要重定向,则返回以redirect:作为前缀的Stringl即可        

主流的开发模式是服务器端向客户端响应正文,完全不需要使用该类型的对象.
  • HandlerExceptionResolver
HandlerExceptionResolver负责处理处理器中抛出的异常。它根据异常的类型选择一个
合适的异常处理器,并将异常处理器的处理结果返回给DispatcherServlet。

3、SpringMVC参数绑定

3.1参数绑定原理

  • 参数绑定

        在客户端向服务端发送请求的过程中,可能有参数,此时我们需要在处理器方法的形参获取此参数。所以就需要对请求参数和方法上的形参进行建立连接。连接的过程中就是数据绑定。

  • 数据绑定的原理

        SpringMVC会把ServletRequest传递给DataBinder,然后把形参上的对象传递给DataBinder,DataBinder调用ConversionServlet进行数据类型转换和格式化,并把数据填充到对象中。然后校验是否合法,合法的话就生成BindingResult,把数据赋值给处理器方法上的形参。

3.1简单参数绑定

  • 常见的默认参数类型
HttpServletRequest:获取请求信息
HttpServletResponse:处理响应信息
HttpSession:获取session中存放的信息
Model/ModelMap:Model是一个接口,ModelMap是一个类,Model的实现类对象和ModelMap
对象都可以设置model数据,model数据会填充到request域。
@RequestMapping("/functionTest")
public ModelAndView functionTest (HttpServletRequest request, HttpServletResponse response, HttpSession session) {
    ModelAndView model = new ModelAndView();
}
  • 简单参数绑定

即简单的java类型数据,如Integer,String,PoJo对象等。

代码示例:

 @RequestMapping("/paramBingForSimplePoJo")
    private String paramBingForSimplePoJo(Address address) {
        System.out.println(address);
        return "成功";
    }

结果示例1:

结果示例2:

3.2 复杂参数类型绑定

  • 数组

数组绑定,用postMan测试需要使用x-www-from-urlencoded , x-www-form-urlencoded 是最常见的 POST 提交数据的编码方式。位于:请求头內的Content-Type字段里:

Content-Type:application/x-www-form-urlencoded

代码示例:

 @RequestMapping("/paramBingForArray")
    private String paramBingForArray(Integer[] ageArray) {
        System.out.println(ageArray);
        return "成功";
    }

结果示例1:

结果示例2:

@RequestMapping("/functionTest")
public ModelAndView functionTest (@RequestParam(value="id", required="true") Long recId) {
    ModelAndView model = new ModelAndView();
}
  • 集合绑定

        需要使用@RequestParam注解,发送方式同 数组 一样。用postMan测试需要使用x-www-from-urlencoded。

代码示例:

@RequestMapping("/paramBingForList")
    private String paramBingForList(@RequestParam("ageList") List<Integer> ageList) {
        System.out.println(ageList);
        return "成功";
    }

结果示例:

  • 复杂POJO对象

代码示例:

/**
 * 功能说明:
 *
 * @author xuzaiya.com
 * @date 2024/3/13
 */
@Data
public class User implements Serializable {
    private List<Integer> idsList;
    private Integer[] idsArray;
    private HashMap<String, String> map;
    private TsCompareDetailLog tsCompareDetailLog;
    private String name;
} 

结果示例1:

结果示例2:

  • 自定义类型转换器

springmvc没有帮我们把字符串转为日期,所以需要自己配置。

/**
 * 1.自定义日期类型转换器,实现Convert接口(S,R)
 * S-原始类型
 * R-转换后类型
 */
public class DateConverter implements Converter<String, Date> {
    @Override
    public Date convert(String dateStr) {
        Date date=null;
        try {
            date = new SimpleDateFormat("yyyy-MM-dd").parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }
}

4、SpringMVC的重要注解

  • @Controller
@Controller注解将一个普通的Java类标记为处理请求的控制器,在Spring MVC中起到了路由
请求和处理业务逻辑的作用,并注册为Spring容器的Bean。通过扫描或显式配置等方式,
让Spring能够自动检测到这个控制器并进行实例化和管理。
  • @RequestMapping
@RequestMapping注解用于将一个HTTP请求映射到控制器类或处理请求的方法上,
告诉Spring MVC如何匹配和处理请求
  • @GetMapping 、@PostMapping、@PutMapping、@DeleteMapping
// @GetMapping: 
处理get请求,传统的RequestMapping来编写应该是@RequestMapping(value = “/get/{id}”, method = RequestMethod.GET)
新方法可以简写为:
@GetMapping(“/get/{id}”)

// @PostMapping: 
处理post请求,传统的RequestMapping来编写应该是@RequestMapping(value = “/get/{id}”,method = RequestMethod.POST)
新方法可以简写为:
@PostMapping(“/get/{id}”)

// @PutMapping: 和PostMapping作用等同,
都是用来向服务器提交信息。如果是添加信息,倾向于用@PostMapping,如果是更新信息,
倾向于用@PutMapping。两者差别不是很明显。

// @DeleteMapping 
删除URL映射,具体没有再实践中用过,不知道好在什么地方
// @PatchMapping:
PATCH 请求通常用于对资源进行部分更新。
  • @RequestParam
@RequestParam 是 Spring MVC 框架中的一个注解,用于将请求参数绑定到处理请求的方法的参数上。
使用 @RequestParam 注解时,可以在处理请求的方法的参数前添加该注解,
并指定参数名。Spring MVC 在接收到请求时,会自动将请求中对应名称的参数值绑定
到方法参数上

@RequestParam 注解有一些属性可以进一步配置参数的行为,例如设置参数是否是必需的、设置默认值等。

@GetMapping("/search")
public ResponseEntity<List<User>> searchUsers(
        @RequestParam(value = "name", required = true) String name,
        @RequestParam(value = "age", defaultValue = "0") int age) {
    // ...
}

        required = true 表示参数必需,如果请求中没有该参数,则会返回 400 Bad Request 错误;defaultValue = “0” 表示如果请求中没有提供该参数,则将参数默认值设置为 0。

  • @PathVariable
@PathVariable 是 Spring MVC 框架中的一个注解,用于将请求路径中的变量绑定到处理
请求的方法的参数上。

使用 @PathVariable 注解时,可以在处理请求的方法的参数前添加该注解,
并指定路径中的变量名称。Spring MVC 在接收到请求时,会自动从路径中提取对应名称的变量值,
并将其绑定到方法参数上

        @PathVariable 注解还支持一些属性进行进一步的配置,例如设置变量的默认值、正则表达式等。

@GetMapping("/{id}/{username}")
public ResponseEntity<User> getUserByUsername(
        @PathVariable("username") String username,
        @PathVariable(value = "id", defaultValue = "0") Long id) {
    // ...
}
  • @RequestHeader
@RequestMapping("/useRequestHeader")
public String useRequestHeader(@RequestHeader(value="Accept-Language",
required=false)String requestHeader){
    System.out.println(requestHeader);
return "success"; }

作用:用于获取请求消息头。
value:提供消息头名称
required:是否必须有此消息头 
  • @CookieValue

        @CookieValue 是 Spring MVC 框架中的一个注解,用于将请求中指定名称的 Cookie 值绑定到处理请求的方法的参数上。

        使用 @CookieValue 注解时,可以在处理请求的方法的参数前添加该注解,并指定要绑定的 Cookie 名称。Spring MVC 在接收到请求时,会自动从请求的 Cookie 中查找指定名称的 Cookie 值,并将其绑定到方法参数上。

@RestController
@RequestMapping("/users")
public class UserController {

    @GetMapping("/info")
    public ResponseEntity<UserInfo> getUserInfo(@CookieValue("sessionToken") String sessionToken) {
        // 根据 sessionToken 获取用户信息
        UserInfo userInfo = userService.getUserInfoBySessionToken(sessionToken);

        if (userInfo == null) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
        }

        return ResponseEntity.ok(userInfo);
    }
}
  • @RequestBody

        @RequestBody 是 Spring MVC 框架中的一个注解,用于将请求体中的数据绑定到处理请求的方法的参数上。

        使用 @RequestBody 注解时,可以在处理请求的方法的参数前添加该注解。 Spring MVC 在接收到请求时,会自动将请求体中的数据按照指定的数据类型转换,并将其绑定到方法参数上。

代码示例:

@RequestMapping("/paramBingForRequestBody")
  private String paramBingForRequestBody(@RequestBody Address address) {
     System.out.println(address);
     return "成功";
}

结果示例1:

结果示例2:

        @RequestBody Address address ,  表示从请求体中获取 JSON 格式的数据并转换为 Address对象,然后将其赋值给 address参数,通过这种方式,在处理请求的方法中可以直接使用请求体中的数据进行相应的操作和逻辑处理.

        @RequestBody 注解还支持一些属性进行进一步的配置,例如设置请求体的媒体类型、是否必需等.

@RequestMapping(value = "/paramBingForRequestBody", consumes = MediaType.APPLICATION_JSON_VALUE)
    private String paramBingForRequestBody(@RequestBody Address address) {
        System.out.println(address);
        return "成功";
    } 

consumes = MediaType.APPLICATION_JSON_VALUE 表示只接受 JSON 格式的请求体。

  • ResponseBody

        @ResponseBody 是 Spring MVC 框架中的一个注解,用于将处理请求的方法的返回值直接作为响应体的内容返回给客户端。

        使用 @ResponseBody 注解时,可以在处理请求的方法上添加该注解。 Spring MVC 在调用方法后,会将方法的返回值转换为指定的数据格式(如 JSON、XML等),然后将其作为响应体返回给客户端。         @ResponseBody 是 Spring MVC 框架中的一个注解,用于将处理请求的方法的返回值直接作为响应体的内容返回给客户端。

@RequestMapping(value = "/paramBingForResponseBody", consumes = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
private Address paramBingForResponseBody(@RequestBody Address address) {
    System.out.println(address);
    return address;
}

        使用 @ResponseBody 注解还可以实现其他类型的数据格式转换,例如返回 XML 格式的数据,通过设置 produces = MediaType.APPLICATION_XML_VALUE,表示返回 XML 格式的数据.

@RequestMapping(value = "/paramBingForResponseBody", produces  = MediaType.APPLICATION_XML_VALUE)
@ResponseBody
private Address paramBingForResponseBody(@RequestBody Address address) {
    System.out.println(address);
    return address;
}

        总之,@ResponseBody 注解用于将处理请求的方法的返回值直接作为响应体返回给客户端。可以通过该注解指定返回数据格式,如 JSON、XML等。

  • @SessionAttribute

        @SessionAttribute 是 Spring MVC 框架中的一个注解,用于将模型属性(Model Attribute)存储到会话(Session)中,并在后续请求中可以直接访问和使用。使用 @SessionAttribute 注解时,可以在处理请求的方法的参数或类级别上添加该注解。

  • 当使用在方法参数上时,它将从会话中获取相应的属性值;

  • 当使用在类级别上时,它将对整个类的所有处理请求的方法生效

        需要注意的是,当使用 @SessionAttribute 注解时,要确保在会话结束后及时清理会话属性,以避免可能的内存泄漏和数据一致性问题。

        总之,@SessionAttribute 注解用于将模型属性存储到会话中,并在后续请求中可以直接访问和使用。通过在方法参数或类级别上添加该注解,可以轻松实现会话级别的属性共享。

  • ControllerAdvice

        @ControllerAdvice 是 Spring MVC 框架中的一个注解,用于定义全局控制器增强(Controller Advice)。它允许开发者在多个控制器中共享相同的行为或异常处理逻辑,并将这些通用逻辑集中到一个类中.

        使用 @ControllerAdvice 注解时,需要创建一个带有 @ControllerAdvice 注解的类,并在该类中定义通用的控制器增强逻辑。这些逻辑可以包括以下方面:

        异常处理:通过在方法上添加 @ExceptionHandler 注解定义通用的异常处理方法,处理特定类型的异常或一般性的异常。         数据绑定:通过在方法上添加 @InitBinder 注解自定义数据绑定逻辑,例如格式化日期、类型转换等。         模型属性:通过在方法上添加 @ModelAttribute 注解定义通用的模型属性方法,将模型属性添加到每个请求的模型中

@ControllerAdvice
public class GlobalControllerAdvice {

    @ExceptionHandler(Exception.class)
    public ModelAndView handleException(Exception ex) {
        // 处理并返回异常视图
        ModelAndView modelAndView = new ModelAndView("error");
        modelAndView.addObject("errorMessage", "Sorry, something went wrong.");
        return modelAndView;
    }

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        // 自定义数据绑定逻辑
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        binder.registerCustomEditor(Date.class, new CustomDateEditor(sdf, true));
    }

    @ModelAttribute
    public void addCommonAttributes(Model model) {
        // 添加通用的模型属性
        model.addAttribute("appName", "MyApp");
    }
}

        @ControllerAdvice 注解表示这个类是一个全局控制器增强类。

        在 handleException() 方法上使用 @ExceptionHandler(Exception.class) 注解,当发生任何类型的异常时,都会调用该方法进行处理,并返回相应的错误视图。

        通过 @InitBinder 注解定义了一个自定义数据绑定逻辑,并注册到默认的数据绑定器中。这里使用了一个 CustomDateEditor 将日期字符串转换为 Date 类型。

        在 addCommonAttributes() 方法上使用 @ModelAttribute 注解,该方法会在每个请求之前被调用,并将指定的模型属性添加到每个请求的模型中。

  • @ModelAttribute

        当使用 @ModelAttribute 注解时,可以在方法参数、方法返回值或方法上添加该注解。它的作用如下:

方法参数上的 @ModelAttribute 注解:

  • (1) 当用于处理请求的方法中的方法参数上时,它表示从模型中获取对应名称的属性,并将其绑定到被注解的方法参数上。如果模型中不存在对应名称的属性,则会创建一个新的对象,并绑定到方法参数上。 例如,在处理表单提交时,可以使用 @ModelAttribute 注解将表单数据绑定到方法参数上,以便进一步处理。 方法返回值上的 @ModelAttribute 注解:

  • (2) 当用于处理请求的方法中的方法返回值上时,它表示将方法返回的对象添加到模型中。默认情况下,以对象的类名首字母小写作为属性的名称,也可以通过指定 name 属性来自定义属性的名称。 方法上的 @ModelAttribute 注解:

  • (3) 当用于处理请求的方法上时,它表示该方法用于在处理请求之前向模型中添加属性。例如,在每个请求之前需要将一些共享的属性添加到模型中时,可以在一个专门的方法上添加 @ModelAttribute 注解,然后该方法的返回值会自动添加到模型中。

@Controller
@RequestMapping("/user")
public class UserController {

    @GetMapping("/{id}")
    public String getUser(@PathVariable("id") int id, @ModelAttribute("user") User user) {
        // 根据用户ID查询用户信息,并将结果绑定到方法参数中的 User 对象上
        return "user/profile";
    }

    @PostMapping("/edit")
    public String updateUser(@ModelAttribute("user") User user) {
        // 更新用户信息
        return "redirect:/user/" + user.getId();
    }

    @ModelAttribute("user")
    public User setupUser() {
        // 在处理请求之前向模型中添加名为 "user" 的属性
        return new User();
    }
}
end
  • 作者:旭仔(联系作者)
  • 发表时间:2024-03-17 10:42
  • 版权声明:自由转载-非商用-非衍生-保持署名
  • 转载声明:如果是转载栈主转载的文章,请附上原文链接
  • 公众号转载:请在文末添加作者公众号二维码(公众号二维码见右边,欢迎关注)
  • 评论