• springmvc


    1.resp目标的pathVirialbe注解

    springmvc发送rest请求

    web.xml文件

        <!-- 
        配置 org.springframework.web.filter.HiddenHttpMethodFilter: 可以把 POST 请求转为 DELETE 或 POST 请求 
        -->
        <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>
        /**
         * Rest 风格的 URL. 以 CRUD 为例: 新增: /order POST 修改: /order/1 PUT update?id=1 获取:
         * /order/1 GET get?id=1 删除: /order/1 DELETE delete?id=1
         * 
         * 如何发送 PUT 请求和 DELETE 请求呢 ? 1. 需要配置 HiddenHttpMethodFilter 2. 需要发送 POST 请求
         * 3. 需要在发送 POST 请求时携带一个 name="_method" 的隐藏域, 值为 DELETE 或 PUT
         * 
         * 在 SpringMVC 的目标方法中如何得到 id 呢? 使用 @PathVariable 注解
         * 
         */
        @RequestMapping(value = "/testRest/{id}", method = RequestMethod.PUT)
        public String testRestPut(@PathVariable Integer id) {
            System.out.println("testRest Put: " + id);
            return SUCCESS;
        }
    
        @RequestMapping(value = "/testRest/{id}", method = RequestMethod.DELETE)
        public String testRestDelete(@PathVariable Integer id) {
            System.out.println("testRest Delete: " + id);
            return SUCCESS;
        }
    
        @RequestMapping(value = "/testRest", method = RequestMethod.POST)
        public String testRest() {
            System.out.println("testRest POST");
            return SUCCESS;
        }
    
        @RequestMapping(value = "/testRest/{id}", method = RequestMethod.GET)
        public String testRest(@PathVariable Integer id) {
            System.out.println("testRest GET: " + id);
            return SUCCESS;
        }
    View Code

    二.请求参数

    1)请求参数

        /**
         * @RequestParam 来映射请求参数. value 值即请求参数的参数名 required 该参数是否必须. 默认为 true
         *               defaultValue 请求参数的默认值
         */
        @RequestMapping(value = "/testRequestParam")
        public String testRequestParam(
                @RequestParam(value = "username") String un,
                @RequestParam(value = "age", required = false, defaultValue = "0") int age) {
            System.out.println("testRequestParam, username: " + un + ", age: "
                    + age);
            return SUCCESS;
        }
    View Code

    2)请求头

        /**
         * 了解: 映射请求头信息 用法同 @RequestParam
         */
        @RequestMapping("/testRequestHeader")
        public String testRequestHeader(
                @RequestHeader(value = "Accept-Language") String al) {
            System.out.println("testRequestHeader, Accept-Language: " + al);
            return SUCCESS;
        }
    View Code

    3)cookieValue

        /**
         * 了解:
         * 
         * @CookieValue: 映射一个 Cookie 值. 属性同 @RequestParam
         */
        @RequestMapping("/testCookieValue")
        public String testCookieValue(@CookieValue("JSESSIONID") String sessionId) {
            System.out.println("testCookieValue: sessionId: " + sessionId);
            return SUCCESS;
        }
    View Code

    三.POJO java对象作为请求参数

    前端传参:

        <form action="springmvc/testPojo" method="post">
            username: <input type="text" name="username"/>
            <br>
            password: <input type="password" name="password"/>
            <br>
            email: <input type="text" name="email"/>
            <br>
            age: <input type="text" name="age"/>
            <br>
            city: <input type="text" name="address.city"/>
            <br>
            province: <input type="text" name="address.province"/>
            <br>
            <input type="submit" value="Submit"/>
        </form>
    View Code

    后端接收

    四.处理模型数据

        /**
         * 目标方法的返回值可以是 ModelAndView 类型。 
         * 其中可以包含视图和模型信息
         * SpringMVC 会把 ModelAndView 的 model 中数据放入到 request 域对象中. 
         * @return
         */
        @RequestMapping("/testModelAndView")
        public ModelAndView testModelAndView(){
            String viewName = SUCCESS;
            ModelAndView modelAndView = new ModelAndView(viewName);
            
            //添加模型数据到 ModelAndView 中.
            modelAndView.addObject("time", new Date());
            
            return modelAndView;
        }
    View Code

    五.使用原生api

    源码示例:

    结论:

        /**
         * 可以使用 Serlvet 原生的 API 作为目标方法的参数 具体支持以下类型
         * 
         * HttpServletRequest 
         * HttpServletResponse 
         * HttpSession
         * java.security.Principal 
         * Locale InputStream 
         * OutputStream 
         * Reader 
         * Writer
         * @throws IOException 
         */
        @RequestMapping("/testServletAPI")
        public void testServletAPI(HttpServletRequest request,
                HttpServletResponse response, Writer out) throws IOException {
            System.out.println("testServletAPI, " + request + ", " + response);
            out.write("hello springmvc");
    //        return SUCCESS;
        }
    View Code

    六.处理模型数据

    通常将模型数据放到请求域中.

     

        /**
         * @SessionAttributes 除了可以通过属性名指定需要放到会话中的属性外(实际上使用的是 value 属性值),
         * 还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中(实际上使用的是 types 属性值)
         * 
         * 注意: 该注解只能放在类的上面. 而不能修饰放方法. 
         */
        @RequestMapping("/testSessionAttributes")
        public String testSessionAttributes(Map<String, Object> map){
            User user = new User("Tom", "123456", "tom@atguigu.com", 15);
            map.put("user", user);
            map.put("school", "atguigu");
            return SUCCESS;
        }
    View Code

    七:数据绑定流程

    数据从web页面到进入handler中,比如birth字段,需要遇到如下问题:

     1.数据类型转换

     2.数据类型格式化

     3.数据校验

     数据绑定流程如下:

     源码分析如下: 

     1.在某个javabean的set属性打断点,就可以查看到如下代码:

     

    数据类型转换的类

     自定义类型转换器

     initBinder使用:

     javaBean校验

     

     

     springMVC返回json

    springmvc返回json需要@ResponseBody注解,以及JACKSONjar包.

    	@ResponseBody
    	@RequestMapping("/testJson")
    	public Collection<Employee> testJson(){
    		return employeeDao.getAll();
    	}  

    如下截图所示:

     HTTPMessageConverter负责转换成json响应数据:

     

    原理:

     https://blog.csdn.net/ff906317011/article/details/78552426

    文件上传

    spring拦截器各方法执行顺序

    package com.atguigu.springmvc.interceptors;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    
    public class FirstInterceptor implements HandlerInterceptor{
    
        /**
         * 该方法在目标方法之前被调用.
         * 若返回值为 true, 则继续调用后续的拦截器和目标方法. 
         * 若返回值为 false, 则不会再调用后续的拦截器和目标方法. 
         * 
         * 可以考虑做权限. 日志, 事务等. 
         */
        @Override
        public boolean preHandle(HttpServletRequest request,
                HttpServletResponse response, Object handler) throws Exception {
            System.out.println("[FirstInterceptor] preHandle");
            return true;
        }
    
        /**
         * 调用目标方法之后, 但渲染视图之前. 
         * 可以对请求域中的属性或视图做出修改. 
         */
        @Override
        public void postHandle(HttpServletRequest request,
                HttpServletResponse response, Object handler,
                ModelAndView modelAndView) throws Exception {
            System.out.println("[FirstInterceptor] postHandle");
        }
    
        /**
         * 渲染视图之后被调用. 释放资源
         */
        @Override
        public void afterCompletion(HttpServletRequest request,
                HttpServletResponse response, Object handler, Exception ex)
                throws Exception {
            System.out.println("[FirstInterceptor] afterCompletion");
        }
    
    }
    View Code

     springmvc异常处理

    //    @ExceptionHandler({RuntimeException.class})
    //    public ModelAndView handleArithmeticException2(Exception ex){
    //        System.out.println("[出异常了]: " + ex);
    //        ModelAndView mv = new ModelAndView("error");
    //        mv.addObject("exception", ex);
    //        return mv;
    //    }
        
        /**
         * 1. 在 @ExceptionHandler 方法的入参中可以加入 Exception 类型的参数, 该参数即对应发生的异常对象
         * 2. @ExceptionHandler 方法的入参中不能传入 Map. 若希望把异常信息传导页面上, 需要使用 ModelAndView 作为返回值
         * 3. @ExceptionHandler 方法标记的异常有优先级的问题. 
         * 4. @ControllerAdvice: 如果在当前 Handler 中找不到 @ExceptionHandler 方法来出来当前方法出现的异常, 
         * 则将去 @ControllerAdvice 标记的类中查找 @ExceptionHandler 标记的方法来处理异常. 
         */
    //    @ExceptionHandler({ArithmeticException.class})
    //    public ModelAndView handleArithmeticException(Exception ex){
    //        System.out.println("出异常了: " + ex);
    //        ModelAndView mv = new ModelAndView("error");
    //        mv.addObject("exception", ex);
    //        return mv;
    //    }
    View Code

     给异常类定制响应码和消息: ResponseStatus

    异常类如下:

    package com.atguigu.springmvc.test;
    
    import org.springframework.http.HttpStatus;
    import org.springframework.web.bind.annotation.ResponseStatus;
    
    @ResponseStatus(value=HttpStatus.FORBIDDEN, reason="用户名和密码不匹配!")
    public class UserNameNotMatchPasswordException extends RuntimeException{
    
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
    
        
    }
    View Code

    方法类如下:

        @RequestMapping("/testResponseStatusExceptionResolver")
        public String testResponseStatusExceptionResolver(@RequestParam("i") int i){
            if(i == 13){
                throw new UserNameNotMatchPasswordException();
            }
            System.out.println("testResponseStatusExceptionResolver...");
            
            return "success";
        }

    springmvc运行流程

     springmvc与spring 的ioc区别以及配置引用

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
            http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
    
        <!--  
            需要进行 Spring 整合 SpringMVC 吗 ?
            还是否需要再加入 Spring 的 IOC 容器 ?
            是否需要再 web.xml 文件中配置启动 Spring IOC 容器的 ContextLoaderListener ?
            
            1. 需要: 通常情况下, 类似于数据源, 事务, 整合其他框架都是放在 Spring 的配置文件中(而不是放在 SpringMVC 的配置文件中).
            实际上放入 Spring 配置文件对应的 IOC 容器中的还有 Service 和 Dao. 
            2. 不需要: 都放在 SpringMVC 的配置文件中. 也可以分多个 Spring 的配置文件, 然后使用 import 节点导入其他的配置文件
        -->
        
        <!--  
            问题: 若 Spring 的 IOC 容器和 SpringMVC 的 IOC 容器扫描的包有重合的部分, 就会导致有的 bean 会被创建 2 次.
            解决:
            1. 使 Spring 的 IOC 容器扫描的包和 SpringMVC 的 IOC 容器扫描的包没有重合的部分. 
            2. 使用 exclude-filter 和 include-filter 子节点来规定只能扫描的注解
        -->
        
        <!--  
            SpringMVC 的 IOC 容器中的 bean 可以来引用 Spring IOC 容器中的 bean. 
            返回来呢 ? 反之则不行. Spring IOC 容器中的 bean 却不能来引用 SpringMVC IOC 容器中的 bean!
        -->
        
        <context:component-scan base-package="com.atguigu.springmvc" use-default-filters="false">
            <context:include-filter type="annotation" 
                expression="org.springframework.stereotype.Controller"/>
            <context:include-filter type="annotation" 
                expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
        </context:component-scan>
    
        <!-- 配置视图解析器 -->
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/WEB-INF/views/"></property>
            <property name="suffix" value=".jsp"></property>
        </bean>
        
        <mvc:default-servlet-handler/>
        <mvc:annotation-driven></mvc:annotation-driven>
        
    </beans>
  • 相关阅读:
    用户态和内核态
    04 _ 如何利用事务消息实现分布式事务?
    03 _ 消息模型:主题和队列有什么区别
    01 _ 为什么需要消息队列?
    洛谷P2257 YY的GCD
    HDU2669 Romantic (扩展欧几里德)
    CQOI2015 选数
    A. Pride
    测试开发进阶——python-java——appium003——Desired Capabilities —— 自动化常用方法——面试整理
    HDU 5050
  • 原文地址:https://www.cnblogs.com/zhulibin2012/p/10480401.html
Copyright © 2020-2023  润新知