SpringMVC learning code 2

Tue, Mar 16, 2021 3-minute read

This is my learning note about SpringMVC with Code Examples .

SpringMVC 是 Spring 为表述层开发提供的一整套完备的解决方案

注:三层架构分为表述层(或表示层)、业务逻辑层、数据访问层,表述层表示前台页面和后台 servlet

基于原生的 Servlet,通过了功能强大的前端控制器 DispatcherServlet,对请求和响应进行统一处理

SpringMVC 基本概念

@RequestMapping

@RequestMapping value 属性

@Controller
@RequestMapping("/hello")
public class RequestMappingController {

    @RequestMapping("/testRequestMapping")
    public String success() {
        return "success";
    }
}

test requestmapping

404

test requestmapping

@RequestMapping 注解的 value 属性通过请求的请求地址匹配请求映射

@RequestMapping 注解的 value 属性是一个字符串类型的数组,表示该请求映射能够匹配多个请求地址所对应的请求

@RequestMapping 注解的 value 属性必须设置,至少通过请求地址匹配请求映射

@RequestMapping method 属性

  • get
  • post …

@RequestMapping param 属性

@RequestMapping(
        value = {"/testRequestMapping", "/test"}
        ,method = {RequestMethod.GET, RequestMethod.POST}
        ,params = {"username","password!=123456"}
)
public String testRequestMapping(){
    return "success";
}
<a th:href="@{/test(username='admin',password=123456)">测试@RequestMapping的params属性-->/test</a><br>

“param”:要求请求映射所匹配的请求必须携带 param 请求参数

“!param”:要求请求映射所匹配的请求必须不能携带 param 请求参数

“param=value”:要求请求映射所匹配的请求必须携带 param 请求参数且 param=value

“param!=value”:要求请求映射所匹配的请求必须携带 param 请求参数但是 param!=value

@RequestMapping header 属性

@RequestMapping ant 属性

?:表示任意的单个字符

*:表示任意的 0 个或多个字符

**:表示任意的一层或多层目录

注意:在使用**时,只能使用/**/xxx 的方式

@RequestMapping 支持路径中的占位符

重点

原始方式:/deleteUser?id=1

rest 方式:/deleteUser/1

SpringMVC 路径中的占位符常用于 RESTful 风格中,当请求路径中将某些数据通过路径的方式传输到服务器中,就可以在相应的@RequestMapping 注解的 value属性中通过占位符{xxx}表示传输的数据,在通过@PathVariable 注解,将占位符所表示的数据赋值给控制器方法的形参

<a th:href="@{/testRest/1/admin}">测试路径中的占位符-->/testRest</a><br>
@RequestMapping("/testRest/{id}/{username}")
public String testRest(@PathVariable("id") String id, @PathVariable("username") String username){
    System.out.println("id:"+id+",username:"+username);
    return "success";
}
//最终输出的内容为-->id:1,username:admin

SpringMVC 获取请求参数

通过 ServletAPI 获取

image

springmvc

通过控制器方法的形参获取请求参数

MVC 提供的

在控制器方法的形参位置,设置和请求参数同名的形参,当浏览器发送请求,匹配到请求映射时,在 DispatcherServlet 中就会将请求参数赋值给相应的形参

image

springmvc

image

springmvc

@RequestParam

在前端的名字和后端不一样时, 用了这个以后代表里面的参数必须有

image

springmvc

defaultValue:不管 required 属性值为 true 或 false,当 value 所指定的请求参数没有传输或传输的值为"“时,则使用默认值为形参赋值, 在实际中更有用,无需判断空参

 public String testP(@RequestParam(value = "user_name", defaultValue = "haha") String username, String password, String hobby) {

@RequestHeader

  • @RequestHeader 是将请求头信息和控制器方法的形参创建映射关系

  • @RequestHeader 注解一共有三个属性:value、required、defaultValue,用法同@RequestParam

    // public String testP(@RequestParam(value = "user_name", defaultValue = "haha") String username, String password, String hobby,
                        @RequestHeader("Host") String host) {
        System.out.println("Host: " + host); // host:localhost:8080
        return "success";
    }

@CookieValue

  • @CookieValue 是将 cookie 数据和控制器方法的形参创建映射关系

  • @CookieValue 注解一共有三个属性:value、required、defaultValue,用法同@RequestParam

image

springmvc

通过 POJO 获取请求参数

<form th:action="@{/testpojo}" method="post">
    用户名:<input type="text" name="username"><br>
    密码:<input type="password" name="password"><br>
    性别:<input type="radio" name="sex" value="男"><input type="radio" name="sex" value="女"><br>
    年龄:<input type="text" name="age"><br>
    邮箱:<input type="text" name="email"><br>
    <input type="submit">
</form>
image

springmvc

解决获取请求参数的乱码问题

tomcat 的 server.xml 的端口 解决 get 参数乱码问题

Post 参数乱码问题

服务器 3 大组件: 监听器,过滤器, servlet

服务启动时执行时间比 ervlet 早

解决获取请求参数的乱码问题,可以使用 SpringMVC 提供的编码过滤器 CharacterEncodingFilter,但是必须在 web.xml 中进行注册

<!--配置springMVC的编码过滤器-->
<filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
        <param-name>forceResponseEncoding</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

SpringMVC 中处理编码的过滤器一定要配置到其他过滤器之前,否则无效

域对象共享数据

增删改查 request 域不需要放进 session 里面,因为每次都需要重新获取,才能获得最新数据

创建 springMVC 框架

    1. 配置 web.xml
  • 1.1 配置编码过滤器 : CharacterEncodingFilter
  • 1.2 前端控制器 : DispatcherServlet
image

springmvc

    1. 创建组件: controller 包下面的 TestController 文件, 加 @Controller 注解
    1. springMVC 文件
  • 3.1 扫描组件

  • 3.2 配置视图解析器

    1. 根据视图解析器下前缀后缀文件下创立: templates 和首页: index.html
    1. 在 TestController 文件写一个方法 index(), 返回 “index”, @RequestMapping("/")
    1. 配置 tomcat

使用 ServletAPI 向 request 域对象共享数据

原生比较少用

@RequestMapping("/testServletAPI")
public String testServletAPI(HttpServletRequest request){
    request.setAttribute("testScope", "hello,servletAPI");
    return "success";
}
image

springmvc

使用 ModelAndView 向 request 域对象共享数据

mvc 提供的 api

@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView(){
    /**
     * ModelAndView有Model和View的功能
     * Model主要用于向请求域共享数据
     * View主要用于设置视图,实现页面跳转
     */
    ModelAndView mav = new ModelAndView();
    //向请求域共享数据
    mav.addObject("testScope", "hello,ModelAndView");
    //设置视图,实现页面跳转
    mav.setViewName("success");
    return mav;
}

使用 Model 向 request 域对象共享数据

@RequestMapping("/testModel")
public String testModel(Model model){
    model.addAttribute("testScope", "hello,Model");
    return "success";
}

使用 map 向 request 域对象共享数据

@RequestMapping("/testMap")
public String testMap(Map<String, Object> map){
    map.put("testScope", "hello,Map");
    return "success";
}

使用 ModelMap 向 request 域对象共享数据

@RequestMapping("/testModelMap")
public String testModelMap(ModelMap modelMap){
    modelMap.addAttribute("testScope", "hello,ModelMap");
    return "success";
}

Model、ModelMap、Map 的关系

Model、ModelMap、Map 类型的参数其实本质上都是 BindingAwareModelMap 类型的

public interface Model{}
public class ModelMap extends LinkedHashMap<String, Object> {}
public class ExtendedModelMap extends ModelMap implements Model {}
public class BindingAwareModelMap extends ExtendedModelMap {}

向 session 域共享数据,建议就是使用这个原始 api

@RequestMapping("/testSession")
public String testSession(HttpSession session){
    session.setAttribute("testSessionScope", "hello,session");
    return "success";
}

向 application 域共享数据

@RequestMapping("/testApplication")
public String testApplication(HttpSession session){
	ServletContext application = session.getServletContext();
    application.setAttribute("testApplicationScope", "hello,application");
    return "success";
}

感谢尚硅谷 springmvc1

springmvc3

springmvc4

springmvc5

spring1

javaweb