zoukankan      html  css  js  c++  java
  • 简单了解SpringMVC(五)

    SpringMVC概述

    • 介绍
    1. Spring为展现层提供的基于MVC设计理念的优秀web框架.
      • MVC封装了Servlet
      • M: 模型层, 指项目中实体类JavaBean, 装载并传输数据.
      • V: 视图层.
      • C: 控制层: 代表Servlet.
    2. SpringMVC通过一套MVC注解, 让POJO成为处理请求的控制器, 而无需实现任何接口.
      • POJO: 就是最基本的Java对象.
    3. 支持REST风格的URL请求.
    4. 采用了松散耦合可插拔组件结构, 比其他MVC更具有扩展性和灵活性.
    • SpringMVC是什么
    1. 轻量级, 基于MVC的web层应用框架, 偏前端而不是基于业务逻辑层, Spring框架的一个后续产品.
    • SpringMVC能干什么
    1. 天生与Spring框架集成, 如(IOC, AOP)
    2. 进行更简洁的Web层开发.
    3. 支持灵活的URL到页面控制器的映射.
    4. 非常容易与其他视图技术集成, 如:Velocity, FreeMarker等.
    5. 因为数据模型不存在特定的API里, 二十放在一个Model里(Map数据结构实现), 所以很容易i被其他框架使用.
    6. 非常灵活的数据验证, 格式化和数据绑定机制, 能使用任何对象进行数据绑定, 不用实现特定框架的API
    7. 更简单, 强大的异常处理.
    8. 对静态资源的支持.
    9. 支持灵活的本地化, 主题等解析.
    • SpringMVC怎么用
    1. 将Web层进行了职责解耦, 基于请求 - 响应模型
    2. 常用组件
      • DispatcherServlet: 前端控制器
        • 对客户端发送的请求统一管理的.
      • Controller: 处理器/页面控制器,做的是MVC中的C的事情,但控制逻辑转移到前端控制器了,用于对请求进行处理.
      • HandlerMapping: 请求映射到处理器,找谁来处理, 如果映射成功返回一个HandlerExecutionChain对象(包含一个Handler处理器(页面控制器)对象, 多个HandlerInterceptor拦截器对象).
      • View Resolver: 视图解析器,找谁来处理返回的页面。把逻辑视图解析为具体的View,进行这种策略模式,很容易更换其他视图技术.
        • 如: InternalResourceViewResolver将逻辑视图名映射为JSP视图.
      • LocalResolver: 本地化, 国际化
      • MultipartResolver: 文件上传解析器.
      • HandlerExceptionResolver: 异常处理器.
    • 案例
    1. 创建maven的Web工程, 并加入如下依赖
      <properties>
              <spring.version>5.0.8.RELEASE</spring.version>
      </properties>
      
      <dependencies>
          <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
          </dependency>
      
          <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
          </dependency>
          <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring.version}</version>
          </dependency>
      
          <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
          </dependency>
          <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
          </dependency>
      </dependencies>
    2. 在web.xml中配置SpringMVC的核心(前端)控制器-DispatcherServlet
      • 作用: 加载springMVC的配置文件, 在如下的配置方式下, 核心配置器会自动加载配置文件, 此时的配置文件有默认的位置和名称(和servlet-name)相同. 为WEB-INF/<servlet-name>-servlet.xml
        • 当然, 我们也可以手动设置SpringMVC配置文件的位置.
          <servlet>
                  <servlet-name>springMVC</servlet-name>
                  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
                  <!-- 配置DispatcherServlet的初始化參數:设置文件的路径和文件名称 -->
                  <init-param>
                      <param-name>contextConfigLocation</param-name>
                      <param-value>classpath:springmvc.xml</param-value>
                  </init-param>
                  <load-on-startup>1</load-on-startup>
              </servlet>
              <servlet-mapping>
                  <servlet-name>springMVC</servlet-name>
                  <!-- 路径模型 -->
                  <url-pattern>/</url-pattern>
              </servlet-mapping>
      • 当加载了配置文件, SpringMVC会根据扫描组件找到控制层
            <!--  扫描组件, 将加@Controller注解的类作为SpringMVC的控制层  -->
            <context:component-scan base-package="test"></context:component-scan>
        
            <!--
                配置视图解析器
                作用: 将prefix + 视图名称 + suffix确定最终要跳转的页面
                /view/xxx.jsp 
             -->
            <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
                <property name="prefix" value="/WEB-INF/view/"></property>
                <property name="suffix" value=".jsp"></property>
            </bean>
    3. 创建一个POJO, 在此类上加上@Controller注解, springMVC就会将此类作为控制层加载, 让其处理请求响应.
    4. 在控制层中, 需要在方法上设置@RequestMapping(value="href地址"), springMVC就是通过此注解将请求路径与控制层中的方法进行匹配. 
      • 此时请求路径为localhost:8080/projectName/xxx
        index.jsp
        
        <body>
            <a href="hello?username=admin&password=123456">测试SpringMVC</a>
        </body>
        
        /WEB-INF/view/success.jsp
        
        <body>
            SUCCESS
        </body>
      • handler方法
        @Controller
        public class TestController {
        
            @GetMapping(value = "hello")
            public String hello(String username, String password) {
                System.out.println(username);
                System.out.println(password);
                return "success";
            }
        }

        处理请求的方法会返回一个字符串, 即视图名称, 最终会通过配置文件配置的视图解析器来实现页面跳转

    RequestMapping详解

    • @RequestMapping注解参数
    1. @RequestMapping: 设置请求映射, 把请求和控制层中的方法设置映射关系.
    2. @RequestMapping可以加在方法上, 也可以加在类上.
      • 若类和方法上都有, 应一层一层的访问, 先访问类, 再访问类中的方法.
    3. value属性
      • 当请求路径和@RequestMapping的value属性一致时, 则该注解所标注的方法即为处理请求的方法.
    4. method属性
      • method: 用来设置请求方式, 只有客户端发送请求的方式和method的值一致, 才能处理请求.
      • 请求方式常用4种
        • RequestMethod.GET: 查询
        • RequestMethod.POST: 添加
        • RequestMethod.PUT: 修改
        • RequestMethod.DELETE: 删除
    5. params: 用来设置客户端传到服务器的数据(请求参数), 支持表达式
      • //value这里, 加斜线是访问项目下, 不加则是访问当前目录下
            @PostMapping(value = "/test", params = {"username", "!age"})
            public String testPOST() {
                System.out.println("SUccess: post");
                return "success";
            }
    6. headers: 用来设置请求头信息, 所发送的请求的请求头信息一定要和headers属性中所设置的一致.
      • //此时, 浏览器中request header的language必须以q=0.8,en-us开头, 否则404错误
        @PostMapping(value = "/test", headers = {"Acceept-Language:q=0.8,en-US;"})
    • @RequestMapping支持Ant路径风格
    1. Ant风格资源地址支持3种匹配符
      • @GetMapping(value = "/*/ant??/**/testAnt")  
        
        匹配
        /aa/antBB/CCC/DDD/testAnt
    • SpringMVC支持占位符方式的路径
    1. @PathVariable
      • 带占位符的url是spring3.0新增, 该功能在SpringMVC向REST目标挺进发展过程具有里程碑意义.
      • 通过@PathVariable可以将URL中占位符参数绑定到控制器处理方法的入参中.
      • 格式: @PathVariable("xxx") 类型 参数名
        <a href="testREST/1001/admin">测试</a>
        //以前: <a href="testREST?id=1001&useranme=admin>测试</a>
        

        @GetMapping("/testREST/{id}/{username}") public String testREST(@PathVariable("id")Integer id, @PathVariable("username")String useranme) { System.out.println(id); System.out.println(useranme); return "success"; }

    REST介绍

    • 什么是REST
    1. REST: Representational State Transfer
      • (资源)表观层状态转换, 是目前最流行的互联网软件架构.
      • 资源(Resources): 网络上的一个实体, 或一个具体信息.
        • 可以用一个URL指向它: 每种资源对应一个特定的URI获取这个资源, 访问它的URI就可以, 因此URI即为每一个资源的独一无二的识别符.
      • 表现层(Representation): 把资源具体呈现出的形式, 叫做它的表现层.
        • 比如: 文本以txt格式表现, 也可以用html表现, 甚至二进制表示.
      • 状态转换(State Transfer): 每发出一个请求, 就代表客户端和服务器的一次交互过程.
      • HTTP 协议, 是一个无状态协议, 即所有的状态都保存在服务器端. 因此, 如果客户端想要操作服务器, 必须通过某种手段, 让服务器端发生"状态转化",而这种转化是建立在表现层之上的, 所以就是"表现层状态转化".
        • 具体说, 就是HTTP协议里面, 四个表示操作方式的动词: GET, POST,PUT, DEL它们分别对应四种基本操作: GET用来获取资源, POST用来新建资源, PUT用来更新资源, DELETE用来删除资源.
    2. URL风格
      • 增删改查
    • HiddenHTTPMethodFilter
    1. 浏览器只支持GET与POST请求, 而DELETE, PUT等method并不支持, Spring3.0添加了一个过滤器, 可以将这些请求转换为标准的http方法, 使得支持GET, POST,PUT, DELETE请求.
    2. 由于使用了HiddenHTTPMethodFilter, 所以要在web.xml中配置过滤器
          <filter>
              <filter-name>HiddenHttpMethodFilter</filter-name>
              <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
          </filter>
          <filter-mapping>
              <filter-name>HiddenHttpMethodFilter</filter-name>
              <!-- 过滤所有 -->
              <url-pattern>/*</url-pattern>
          </filter-mapping>
    3. 分析
      • 该类负责解析隐藏的HttpMethod, 用了该Filter后, 可以在页面上POST时指定 _method参数, 该Filter会根据参数指定的值将Request包装为指定的HttpMethod的request. 
    4. 代码
      • rest.jsp
            <!-- 测试Get -->
            <a href="testREST/1001">测试GET</a>
        
            <!-- 测试POST -->
            <form action="testREST" method="post">
                <input type="submit" value="测试POST">
            </form>
        
            <!-- 测试PUT -->
            <form action="testREST" method="post">
                <input type="hidden" name="_method" value="PUT">
                <input type="submit" value="测试PUT">
            </form>
        
            <!-- 测试DELETE -->
            <form action="testREST" method="post">
                <input type="hidden" name="_method" value="DELETE">
                <input type="submit" value="测试DELETE">
            </form>
      • RESTController.java
        @Controller
        public class TestController {
        
            @GetMapping("/testREST/{id}")
            public String getUserById(@PathVariable("id") Integer id) {
                System.out.println(id);
                return "success";
            }
        
            @PostMapping("/testREST")
            public String insertUser() {
        
                return "success";
            }
        
            @PutMapping("/testREST")
            public String updateUser() {
                return "success";
            }
        
            @DeleteMapping("/testREST/{id}")
            public String deleteUserById(@PathVariable("id")Integer id) {
                System.out.println(id);
                return "success";
            }
        }
        • 但直接这么写, PUT和DELETE会报错, 因为发起的请求是个RESTFul风格的请求, 调用了RESTFul风格的PUT方法, 但是controller里testRestPUT返回的success字符串被映射到success.jsp, 因此spring认为这应该是个JSP接口, 且JSP接口仅仅支持GET方法和POST方法. 
      • 解决方法: 
        • @ResponseBody, 在两个负责处理Delete请求和put请求的controller头部添加.
          • 但只能显示出return的值, 无法转发.
                @ResponseBody
                @PutMapping("/testREST")
                public String updateUser() {
                    return "success";
                }
        • 使用Redirect重定向
              @DeleteMapping("/testREST/{id}")
              public String deleteUserById(@PathVariable("id")Integer id) {
                  System.out.println(id);
                  return "redirect:/tosuccess";
              }
          
              @GetMapping("/tosuccess")
              public String toSuccess() {
                  return "success";
              }

    处理请求数据

    • 请求数据
    1. 请求参数, Cookie信息, 请求头信息等.
    2. 在JavaWeb中, HttpServletRequest
      • Request.getParameter(参数名);   Request.getParameterMap(); 
      • Request.getCookies(); Request.getHeader();
    • 请求处理方法签名
    1. SpringMVC通过分析处理方法的签名(方法名+参数列表), Http请求信息绑定到
      处理方法的相应形参中.
    2. SpringMVC对控制器处理方法签名的限制是很宽松的, 几乎可以按喜欢的任何方
      式对方法进行签名.
    3. 可对方法及其参数标注相应注解(@PathVariable, @RequestParam@RequestHeader等)
    4. SpringMVC框架会将Http请求的信息绑定到相应的方法入参中, 并根据方法的返回值类型做出相应的后续处理.
    • @RequestParam注解
    1. 在处理方法入参处使用@RequestParam可以把请求参数传递给请求方法
      • 在请求处理的方法中, 加入相对应的形参, 保证形参参数名和传递数据的参数名保持一致, 就可以自动赋值.
    2. 参数
      • value: 当不满足赋值条件时, 可以使用value属性, 指定映射关系.
      • required: 设置形参是否必须被赋值, 默认为true, 必须赋值, 否则报错. 若设置为false, 则不必赋值.
      • defaultValue: 若形参所获得的值为null, 则设置一个默认值, 用在分页和模糊查询等.
    3. 示例
      • param.jsp
            <form action="param" method="post">
                username: <input type="text" name="name"> <br/>
                password: <input type="password" name="password"> <br/>
            </form>
      • TestController.java
            @PostMapping("/param")
            public String param(@RequestParam(value = "name", required = false, defaultValue = "admin")String username, String password) {
                System.out.println(username);
                System.out.println(password);
                return "success";
            }
    •  @RequestHeader和CookieValue
    1. @RequestHeader
      • 在处理请求的方法上, 获取请求头信息, 用法和@RequestParam一致.
            @PostMapping("/param")
            public String param(@RequestHeader("Accept-Language")String lan) {
                System.out.println(lan);
                return "success";
            }
    2. @CookieValue
      • 在处理请求方法上, 获取cookie信息, 用法和@RequestParam一致.
            @PostMapping("/param")
            public String param(@CookieValue("JSESSIONID")String JESSIONID) {
                System.out.println(JESSIONID);
                return "success";
            }
    •  使用POJO作为参数对象
    1. 可以使用POJO获取客户端数据, 要求实体类对象中的属性名一定要和页面中表单元素的name属性值一致, 且支持级联关系.
    2. 示例
      • Address.java
        @NoArgsConstructor
        @AllArgsConstructor
        @Data
        public class Address {
        
            private String province;
            private String city;
            private String country;
        }
      • param.jsp
            <form action="param" method="post">
                province: <input type="text" name="province"> <br/>
                city: <input type="text" name="city"> <br/>
                country: <input type="text" name="country"/>
                <input type="submit" value="添加">
            </form>
      • TestController.java
            @PostMapping("/param")
            public String param(Address address) {
                System.out.println(address);
                return "success";
            }
    •  使用Servlet原生API作为参数
    1. MVC的Handler方法可以接受九种ServletAPI类型的参数
      • HttpServletRequest
      • HttpServletResponse
      • HttpSession
      • java.security.Principal
      • Locale    
      • InputStream
      • OutputStream
      • Reader
      • Writer
            @Autowired
            private HttpServletRequest request;
        
            @PostMapping("/param")
            public String param() {
                request.getParameter("country");
                return "success";
            }
    2. 记得一定要加servlet依赖
      <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>javax.servlet-api</artifactId>
          <version>3.1.0</version>
          <scope>provided</scope>
      </dependency>

    处理响应数据

    • JavaWeb中
      • request.setAttribute(xxx)
      • request.getRequestDispatcher("地址").forward(req, resp)
    • SpringMVC输出模型数据概述
    1. 两种输出模型数据
      • ModelAndView: 处理方法返回值类型为ModelAndView时, 方法体即可通过该对象添加模型数据.
      • Map或Model, 入参为org.springframework.ui.Model, org.springframework.ui.ModelMap 或 java.uti.Map时, 处理方法返回时, Map中的数据会自动添加到模型中.
    • ModelAndView
    1. 介绍
      • 控制器处理方法的返回值如果为ModelAndView, 则其既包含视图信息, 也包含模型数据信息.
      • 两个重要的成员变量
        • private Object view  视图信息
        • private ModelMap model   模型数据
      • 添加模型数据
        • MoelAndView addObject(String attributeName, Object attributeValue)  往request作用域中放值
        • ModelAndView addAllObject(Map<String, ?> modelMap)
      • 设置视图
        • void setView(View view)  设置视图对象
        • void setViewName(String viewName)  设置视图名称
      • 获取模型数据
        • protected Map<String, Object> getModelInternal()
        • public ModelMap getModelMap()
    2. 示例
      • Controller方法
            @PostMapping("/param")
            public ModelAndView param() {
                ModelAndView mav = new ModelAndView();
                mav.addObject("useranme", "root"); //往request域中放值
                mav.setViewName("success");
                return mav;
            }
      • success.jsp
        <body>
            SUCCESS
        
            ${requestScope.username}
        </body>
    • Map和Model
    1. Map介绍
      • SpringMVC 在内部使用了一个org.springframework.ui.Model接口存储模型数据具体使用步骤.
      • SpringMVC 在调用方法前会创建一个隐含的模型对象作为模型数据的存储容器.
      • 如果方法的入参为 Map 或 Model 类型, SpringMVC会将隐含模型的引用传递给这些入参.
      • 在方法体内, 开发者可以通过这个入参对象访问到模型中的所有数据,也可以向模型中添加新的属性数据.
    2. 代码
          @PostMapping("/param")
          public String param(Map<String, Object> map) {
      
              map.put("username", "admin");
              return "success";
          }
      
          @PostMapping("/param1")
          public String param1(Model model) {
              model.addAttribute("username", "张三");
              return "success";
          }
  • 相关阅读:
    linux 系统中 获取环境变量、 获取环境变量+自定义变量
    即兴写作系统
    php 解决旧系统 查出所有数据分页的类
    面向过程与面向对象编程思想的区别
    c语言入门(一)c语言基础
    清数据库日志
    使用数据集时错误:超时时间已到。在操作完成之前超时时间已过或服务器未响应。
    数据库 可疑 解决方法
    [转].Net线程问题解答
    查询重复记录数
  • 原文地址:https://www.cnblogs.com/binwenhome/p/13037790.html
Copyright © 2011-2022 走看看