-----------------------------------SpringWVC----------------------------
 -----------------------------------开发步骤
 1.导入SpringMVC相关坐标
      <dependency>
       <groupId>org.springframework</groupId>
       <artifactId>spring-webmvc</artifactId>
       <version>5.3.14</version>
     </dependency>
2.配置SpringMVC核心控制器DispathcerServlet
    web.xml
     <servlet>
         <servlet-name>DispatcherServlet</servlet-name>
         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
         <init-param>
             <param-name>contextConfigLocation</param-name>
             <param-value>classpath:spring-mvc.xml</param-value>
         </init-param>
         <load-on-startup>1</load-on-startup>
     </servlet>
    <servlet-mapping>
     <servlet-name>DispatcherServlet</servlet-name>
     <url-pattern>/</url-pattern>
     </servlet-mapping>
 3.创建Controller类和视图页面
4.使用注解配置Controller类中业务方法的映射地址
    @Controller
 public class UserController {
    @RequestMapping("/qucik")
     public String save(){
         System.out.println("the save running");
         return "success.jsp";
     }
 }
  
 5.配置SpringMVC核心文件spring-mvc.xml
  spring-xml
    <context:component-scan base-package="com.itheima.Controller"/>
6.客户端发起请求测试
 -----------------------------SpringMVC的执行流程
   1.用户发送请求至前端控制器DispatcherServlet
   2.DispatcherServlet收到请求调用HandlerMapping处理器映射器
   3.处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器
      (如果有则生成)一并返回给DispatcherServlet
   4.DispatcherServlet调用HandlerAdapter处理器适配器
   5.HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)
   6.Controller执行完成返回ModelAndView
   7.HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet
   8.DispatcherServlet将ModelAndView传给ViewReslover视图解析器
   9.ViewReslover解析后返回具体View
   10.DispatcherServlet根据View进行渲染视图。DispatcherServlet响应用户
     
 //SpringMVC注解解析
   @RequestMapping
    作用:用于建立请求URL和处理请求方法之间的关系
     1.用在类上 /user
     2.用在方法上  /user/quick 
   @RequestMapping(value="/quick",method=RequestMethod.GET,params={"username"})
                      URL           请求方式                 请求参数必须有username
    
 -------------------------------SpringMVC数据响应
  
 //数据相应方式
   1)页面跳转
      ·直接返回字符串
         此种方式会将返回的字符串与视图解析器的前后缀拼接后跳转
      ·通过ModelAndView对象返回
         Spring_MVC UserController
  2)回写数据
      ·直接返回字符串
         如果直接返回字符串,框架不知道你返回的是模型视图还是字符串,需要用@ResponseBody告诉框架
         
         注意:maven内置的tomcat7会出现500的错误提示
         解决方法:1.使用外置tomcat8
                   2.pom中spring-webmvc的版本,最好是5.3.0以下
      ·返回对象或集合
 //方法1
         1.导入pom依赖
             <dependency>
       <groupId>com.fasterxml.jackson.core</groupId>
       <artifactId>jackson-annotations</artifactId>
       <version>2.13.1</version>
     </dependency>
    <dependency>
       <groupId>com.fasterxml.jackson.core</groupId>
       <artifactId>jackson-core</artifactId>
       <version>2.13.1</version>
     </dependency>
    <dependency>
       <groupId>com.fasterxml.jackson.core</groupId>
       <artifactId>jackson-databind</artifactId>
       <version>2.13.1</version>
     </dependency>
         2.使用json转换类
            ObjectMapper objectMapper = new ObjectMapper();
            String json = objectMapper.writeValueAsString(user);
 //方法2
      1.配置Xml
  <bean id="mappingHandlerAdapter" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
           <property name="messageConverters">
               <list>
                   <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"></bean>
               </list>
           </property>
    </bean>
    为RequestMappingHandlerAdapter中的messageConverters配置一个MappingJackson2HttpMessageConverter
     2.实现方法
     @RequestMapping("/quick9")
     @ResponseBody
     public User save9() throws IOException {
         User user = new User();
         user.setAge(18);
         user.setName("lisi");
         return user;
     }
//方法3
   在xml中加上一行 <mvc:annotation-driven/>
      使用它,会自动加载处理器映射器和处理器适配器,可以在xml中代替注解处理器和适配器的配置
      并且默认底层就会继承jackson进行对象或集合的json格式字符串的转换
------------------------------SpringMVC获得请求数据
 1.基本类型参数
    @RequestMapping("/quick10")
     @ResponseBody
     public void save10(String userName,String age) throws IOException {
         System.out.println(userName);
         System.out.println(age);
     }
2.POJO类型参数
   @RequestMapping("/quick11")
     @ResponseBody
     public void save11(User user) throws IOException {
         System.out.println(user);
     }
 3.数组类型参数
   @RequestMapping("/quick12")
     @ResponseBody
     public void save12(String[] str) throws IOException {
         System.out.println(Arrays.asList(str));
     }
 4.集合类型参数
    当使用ajax提交时,可以指定contextType为json形式,那么在方法参数位置
    使用@RequestBody可以直接接受几何数据而无需使用POJO进行包装
 //静态资源访问开启:
   SpringMVC的工作机制是:来自浏览器的所有访问都会被前端控制器(DispatcherServlet)捕获,然后前端控制器把请求转交给处理器映射(HandlerMapping),HandlerMapping为请求分配对应的控制器(Controller)进行请求处理
   通过上面的配置,DispatcherServlet将捕获Web容器所有请求,包括静态资源请求。
   通过学习HTTP协议我们知道,浏览器访问服务器的一个页面,实际上是包含了很多次请求的。除了请求页面本身,页面上的图片,js等静态资源也是通过请求资源在服务器上的相对地址实现的。但是SpringMVC的环境下,对静态资源的请求也会被前端控制器捕获,并转交给处理器映射。由于我们的代码中不会有对应的控制器处理请求,因此请求无法被相应,导致网页无法加载静态资源。
   
     解决方法:<mvc:default-servlet-handler/>或者<mvc:resources mapping="/js/**" location="/js/"/>
 //请求数据乱码问题
    当post请求时,数据会出现乱码,我们可以设置一个过滤器来进行编码的过滤器
    web.xml:
     
       <!--配置全局过滤的Filter-->
     <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>
     </filter>
    <filter-mapping>
         <filter-name>CharacterEncodingFilter</filter-name>
         <url-pattern>/*</url-pattern>
     </filter-mapping>
 //@RequestParam
   绑定参数和表单的name  @RequestParam("name") String username
                          <input type="text" name="name"><br>
    但是此时提交数据不能为空 否则将打不开页面
    @RequestParam(value="name",required=false)
     还有一个defaultValue属性:当没有指定请求参数时,则使用指定的默认值赋值
//@PathVariable
  @RequestMapping("/quick16/{username}")
     @ResponseBody
     public void save16(@PathVariable(value = "username") String name) throws IOException {
         System.out.println(name);
     }
 //自定义类型转换器
   1.SpringMVC默认提供了一些常用类型转换器,例如客户端提交的字符串转换成int
   2.但不是所有的数据类型都提供了转换器,这就需要自定义。例如日期类型数据
  
   自定义类型转换器:
    1.定义转换类实现Converter接口
      public class DateConverter implements Converter<String, Date> {
     @Override
     public Date convert(String source) {
         //将日期的字符串Fri Dec 21 00:00:00 HKT 2018转换成Date对象
         SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
         Date date = null;
         try {
             date = simpleDateFormat.parse(source);
         } catch (ParseException e) {
             e.printStackTrace();
         }
         return date;
     }
 }
   2.在配置文件中声明转换器
  <bean id ="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
       <property name="converters">
           <list>
               <bean class="com.itheima.converter.DateConverter"/>
           </list>
       </property>
   </bean>
   3.在<annotatin-driven>中引用转换器
     <mvc:annotation-driven conversion-service="conversionService"/>
 //获得请求头
   1.@RequestHeader
    相当于web中的request.getHeader(name)
    @RequestHeader注解的属性如下:
     value:请求头的名称 User-Agent
     required:是否必需携带此请求头
   
   2.@CookieValue  
     可以获得指定的Cookie值
    注解的属性如下:
     value:指定cookie的名称
     required:是否必需携带此cookie
 //文件上传
   1.文件上传客户端三要素
     1.type="file"
     2.表单的提交方式时post
     3.表单的enctype属性是多部份表单形式,及enctype="multipart/from-data"
 2.文件上传原理
    当form表单修改为多部份表单时。request.getParameter()将失效
    当enctype="application/x-www-form-urlencoded"时,form表单的正文内容格式是:
     key=value&key=value
    当form表单enctype取值为enctype="multipart/form-data"时,请求正是内容就变成
    多部分形式
   <form action="${pageContext.request.contextPath}/user/quick19" method="post" enctype="multipart/form-data">
       名称<input type="text" name="username"><br>
       文件<input type="file" name="upload"><br>
       <input type="submit" value="提交">
   </form>
 3.单文件上传步骤
    1.导入fileuoload和io坐标
 <dependency>
       <groupId>commons-fileupload</groupId>
       <artifactId>commons-fileupload</artifactId>
       <version>1.4</version>
     </dependency>
     <dependency>
       <groupId>commons-io</groupId>
       <artifactId>commons-io</artifactId>
       <version>2.4</version>
     </dependency>
    2.配置文件上传解析器 
     <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
         <property name="maxUploadSize" value="500000"/>
         <property name="defaultEncoding" value="UTF-8"/>
     </bean>
    3.编写文件上传代码
     @RequestMapping("/quick19")
     @ResponseBody
     public void save18(String username, MultipartFile upload) throws IOException {
         System.out.println(username);
         System.out.println(upload);
         //获得上传文件的名称
         String originalFilename = upload.getOriginalFilename();
         //将文件存到本低
         upload.transferTo(new File("D:\\upload\\"+originalFilename));
     }
    4.多文件上传:
           @RequestMapping("/quick19")
     @ResponseBody
     public void save18(String username, MultipartFile[] uploads) throws IOException {
         System.out.println(username);
         for(MultipartFile file :uploads) {
          System.out.println(file);
          //获得上传文件的名称
          String originalFilename = file.getOriginalFilename();
          //将文件存到本低
          file.transferTo(new File("D:\\upload\\" + originalFilename));
      }
-------------------------------jdbcTemplate开发步骤
  1.导入spring-jdbc和spring-tx坐标
  2.创建数据库表和实体
  3.创建jdbcTemplate对象
  4.执行数据库操作
 --------------------------SpringMVC拦截器
 类似于servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理
将 拦截器按一定的顺序连接成一条链,成为拦截器链 ,拦截器按照定义好的顺序被调用
//快读入门: 
 1.创建拦截器类实现HandlerInterceptor接口
 2.配置拦截器
 3.测试拦截器的拦截效果
------------------------SpringMVC异常处理机制
 1.系统中异常包括两类:预期异常和运行时异常RuntimeException,前者通过捕获异常从而获取异常信息,
   后者主要通过代码规范开发、测试等手段减少运行时异常的发生
2.Dao、Service、Controller出现都通过throws向上抛出,最后由SpringMVC前端控制器交由异常处理器进行异常处理
//异常处理的两种方式
 1.SpringMVC提供多个简单异常处理器SimpleMappingExceptionResolver
 <!--配置异常处理器-->
     <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
 <!--value是自定义的jsp文件-->
         <property name="defaultErrorView" value="error"/>
         <property name="exceptionMappings">
             <map>
                 <entry key="java.lang.ClassCastException" value="error2"/>
             </map>
         </property>
     </bean>
 2.使用Spring的异常处理接口HandlerExceptionResolver自定义自己的异常处理器
   步骤:1.创建异常处理器类实现HandlerExceptionResolver
             public class MyExceptionSolver implements HandlerExceptionResolver {
     @Override
     public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
         ModelAndView modelAndView = new ModelAndView();
         if(ex instanceof ClassCastException)
         {
             //相关操作
         }else if (ex instanceof ClassNotFoundException)
         {
             //相关操作
         }
         modelAndView.setViewName("/error.jsp");
         return modelAndView;
     }
 }
         2.配置异常处理器
   <!--自定义异常处理器-->
     <bean class="com.itheima.resolver.MyExceptionSolver"/>
         3.编写异常页面
         4.测试异常页面跳转
--------------------------aop
 //aop简介
 面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术
 //作用
   在程序运行期间,在不修改源码的情况下对方法进行功能增强
   减少代码重复,提高开发效率,并且便于维护
//AOP的底层实现
   通过Spring提供的动态代理技术实现的。
  动态代理技术:
   JDK代理:基于接口的动态代理技术  
   cglib代理:基于父类的动态代理技术
 //相关概念:
   Target(目标对象):代理的目标对象
   Proxy(代理):一个类被AOP织入增强后,就产生一个结果代理类
   Jionpoint(连接点):可以被增强的方法叫连接点。被拦截到的点(需要增强的方法)
   Pointcut(切入点):所谓切入点就是指我们要对哪些joinpoint进行拦截的定义
   Advice(通知/增强):指拦截到Jionpoint之后所要做的事情就是通知(增强方法)
   Aspect(切面):是切入点和通知(引介)的结合
   Weaving(织入):将切点和增强结合的过程就是织入过程
//开发明确的事项
   1.需要编写的内容
      ·编写业务核心代码(目标类的目标方法)
      ·编写切面类,切面类种有通知(增强功能方法)
      ·在配置文件中,配置织入关系,即将哪些通知与哪些连接点结合
   2.AOP技术实现的内容
     SPring框架监控切入点方法的执行。一旦监控到切入点方法被运行,使用代理机制,
     动态创建目标对象的代理对象,根据通知类别,在代理对象的对应位置,将通知
     对应的功能织入,完成完整的代码逻辑运行
   3.AOP底层使用哪种代理方式
     在spring种,框架会根据目标类是否实现了接口来决定使用哪种动态代理方式
     有接口使用jdk代理 没有使用cglib代理
//基于XML快速入门
   1.导入AOP相关坐标
   2.创建目标接口和目标类(内部有切点)
   3.创建切面类(内部有增强方法)
   4.将目标类和切面类的对象创建权交给spring
   5.在applicationContext.xml种配置织入关系
   6.测试代码
 //切点表达式
   例子:execution(public void com.itheima.aop.Target.save())
   execution([修饰符] 返回值类型 包名.类名.方法名(参数))
    ·访问修饰符可以省略
    ·返回值类型、包名、类名、方法名可以使用星号*代表任意
    ·包名与类名之间一个点.代表当前包下的类,两个点代表当前包及其子包下的类
    ·参数列表可以使用两个点..表示任意两个数,任意类型的参数列表
//通知的类型
   before           在切入点方法(被增强方法)之前执行
   after-returning  在切入点方法执行之后执行
   around           在切入点方法之前和之后执行
   throwing         增强方法在出现异常时执行
   after            无论是否有异常都会执行
//切点表达式的抽取
   <!--目标对象-->
     <bean id="target" class="com.itheima.aop.Target"/>
 <!--配置切面对象-->
     <bean id="myAspect" class="com.itheima.aop.MyAspect"/>
 <!--配置织入 告诉Spring框架哪些方法(切点)需要进行哪些增强(前置、后置)-->
     <aop:config>
         <!--声明切面-->
        <aop:aspect ref="myAspect">
             <!--抽取切点表达式-->
             <aop:pointcut id="myPointCut" expression="execution(public void com.itheima.aop.Target.save())"/>
             <!--切面=切入点+通知-->
             <aop:before method="Before" pointcut-ref="myPointCut"/>
 <!--            <aop:around method="Around" pointcut="execution(* com.itheima.aop.*.*(..))"/>-->
         </aop:aspect>
     </aop:config>
 //基于注解快速入门
    1.导入AOP相关坐标
   2.创建目标接口和目标类(内部有切点)
   3.创建切面类(内部有增强方法)
   4.将目标类和切面类的对象创建权交给spring
   5.在切面类中使用注解配置织入关系
   6.在配置文件中开启组件扫描和AOP代理
   6.测试代码
 -----------------------Spring事务控制
 Spring声明式事务控制底层就是AOP
    
  










