zoukankan      html  css  js  c++  java
  • SpringMVC

    第一轮总结性笔记

    针对表现层的 MVC

    M : Model

    V : View

    C : Controller

    不知道你们玩过Struts没,现在Struts都是一些传统的老项目维护在使用,基本是被市场淘汰了;

    之前Struts出过几次比较重大失误,虽然后面也在更新,但是大家心里都怕了,所谓一朝被蛇咬,十年怕井绳,而SpringMVC又是由Spring提供的一个web层框架,Spring背后的社区力量可想而知,如今已经成为web层最优秀的框架;

    SpringMVC主要是由前端控制器,处理器映射器,处理器适配器,后端控制器,视图解析器等组成

    给我两块钱,我给你一张原理图:(面试常问)

      

    第一步:用户向服务器发送请求,请求被Spring前端控制器 DispatcherServlet捕获;

    第二步: DispatcherServlet调用HandlerMapping对请求URL进行解析,得到请求资源标识符(URL),获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以HandlerExecutionChain对象的形式返回;

    第三步: DispatcherServlet 根据获得的Handler,选择一个合适的HandlerAdapter。(附注:如果成功获得HandlerAdapter后,此时将开始执行拦截器的preHandler(…)方法)

    第四步:提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)。 在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作: >> 1. HttpMessageConveter: 将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息 >> 2. 数据转换:对请求消息进行数据转换。如String转换成Integer、Double等 >> 3. 数据根式化:对请求消息进行数据格式化。 如将字符串转换成格式化数字或格式化日期 >> 4. 数据验证: 验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中

    第五步: Handler执行完成后,向DispatcherServlet 返回一个ModelAndView对象;

    第六步:根据返回的ModelAndView,选择一个适合的ViewResolver(必须是已经注册到Spring容器中的ViewResolver)返回给DispatcherServlet ;

    第七步:ViewResolver 结合Model和View,将模型数据填充至视图中

    第八步:将渲染结果返回给客户端。

    SSM整合

    https://www.cnblogs.com/msi-chen/p/10531638.html

    Controller返回值

    ModelAndView: 一般不用 ,Model装载数据,View指定视图

    Void : 一般用于返回Json数据,当然也可以在形参上定义request和response

    String : 返回的是视图名,可以转发和重定向 return " redirect / forward:index" ; //配合视图解析器

    当方法上有@ResponsaBody注解时,mvc不会解析其为跳转路径

    POJO:配合@ResponsaBody使用

    常用注解和诸多玩法

    常用注解

    @Conrtoller @RequestBody @Requestarem @ResponseBody

    @ResponsaBody注解:将返回的数据封装到Http Response Body中,不会放置到Model中,mvc也不会解析为跳转路径

    Json是默认的的一种返回格式(需要相关 jar 的支持)

    @RequestBody注解 :可以将请求的Json字符串中的值绑定到Bean上

    @RequestMapping : 定义出路起映射规则 value={"/itemList","listItem"},可以是单个值也可以是多个映射规则 数组形式

    参数绑定

    简单类型参数绑定 保证请求参数key和形参名保持一致即可(8中基本数据类型和包装类和String均受理)

    @RequestParam : 请求参数中key和形参名称不一致是使用,进行参数绑定

    @RequestParam(value=" ",required=true,default=" ") // 参数名称 -- 是否必须有值 -- 默认给值

    绑定POJO,要求参数中的key 和POJO中的属性名得保持一致

    绑定包装POJO,页面请求参数如下 stu.name 对应的包装类Class类内有一属性 stu stu内有一属性name

    使用简单类型数组接收批量传递的简单数据类型数据,比如String[ ] 或者 POJO内的属性 String[ ]

    比如这个:http://localhost:8080/xxx/deleteItem?id=1&id=2&id=3 就可以用Integer[ ] 接收

    若相拥List去接收传递的请求参数的话,List必须是一个POJO类内的一个属性,而不能直接以List接收

    如果要接收Date类型数据,需要自定义转换器:Conveter

      public class DateConverter implements Converter<String, Date> {
             @Override
             public Date convert(String source) {
                      SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                      try {
                              return simpleDateFormat.parse(source);
                      } catch (ParseException e) {
                              e.printStackTrace();
                      }
                      return null;
             }
    }

    配置在springmvc.xml中配置Conveter

    <!-- 加载注解驱动 -->
    <mvc:annotation-driven conversion-service="conversionService"/>
    <!-- 转换器配置 -->
    
    <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
      <property name="converters">
        <set>
          <bean class="com.kkb.ssm.controller.converter.DateConverter"/>
        </set>
      </property>
    </bean>

    异常处理器

    dao,service,controller出现异常都通过throw Exception向上抛出,最后由springmvc交由异常处理器进行异常处理

    自定义异常类,继承Excption;

    自定义异常处理类 实现HandlerReceptionResolver;

    在springmvc.xml中注册该类即可;

    图片上传

    springmvc的上传,是由commons-fileupload这个jar包实现的

    文件上出啊需要指定<form>标签的一个属性 : enctype=”multipart/form-data”

    在springmvc中配置Multipart解析器

    <!-- multipart类型解析器,文件上传 -->

    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">

    <!-- 上传文件的最大尺寸 5M-->

    <property name="maxUploadSize" value="5242880"/>

    </bean>

    Controller类:

    @RequestMapping(value = "/updateItem")
    public String updateItem(Model model,Item item,MultipartFile pictureFile) throws Exception {
             if(pictureFile != null){
                      System.out.println(pictureFile.getOriginalFilename());
                      //原始图片名称
                      String originalFilename = pictureFile.getOriginalFilename();
                      //如果没有图片名称,则上传不成功
                      if(originalFilename != null && originalFilename.length()>0)
                      {
                              //存放图片的物理路径
                             String picPath = "E:\03-teach\07-upload\temp\";
                              //新文件的名称
                              String newFileName = UUID.randomUUID()+originalFilename.substring(originalFilename.lastIndexOf("."));
                              //新的文件
                              File newFile = new File(picPath+newFileName);
                              //把上传的文件保存成一个新的文件
                              pictureFile.transferTo(newFile);
                              //同时需要把新的文件名更新到数据库中
                              item.setPic(newFileName);
                      }else{
                              throw new BusinessException("图片名称不存在,上传不成功");
                      }
             }          
             // 根据页面传入的商品信息,调用修改方法,进行修改(此时还没有讲参数绑定,暂时无法进行)
             itemService.updateItem(item);
             return "success";

    Json数据交互

    KV结构,请求是Json(一般情况下),@ResponseBody默认响应也是Json 依赖 jackson-databind.jar 当然依赖传递进来的还有一个io.jar

    Restful支持

    理解:是一种软件架构风格,基于这个风格设计的软件更简洁,更有层次感,Rest指的就是一组架构条件而原则,满足额这个原则设计出来的应用就是Resuful风格

    四个表示操作方式的动词: GET 、POST、PUT、DELETE,分别对应四种基本操作

    springmvc对RESTful的支持:

    web.xml中设置拦截规则为 / ,可以拦截RESTful请求

    但也是因为设置了 /,就必须对静态资源进行访问处理

        <!-- 当DispatcherServlet配置为/来拦截请求的时候,需要配置静态资源的访问映射 -->
            <mvc:resources location=*"/js/"* mapping=*"/js/**"*/>
            <mvc:resources location=*"/css/"* mapping=*"/css/**"*/>

    @PathVariable注解可以解析出URL中的模版变量 如下所示:

    请求URL:http://localhost:8080/ssm/item/1/wangbadan

    @RequestMapping(" {id} / {name} ")

    public void queryItemByIDAndName(@PathVariable Integer id,@PathVariable String name ){}

    @RequestMapping注解可以通过method属性,可以将同一个请求映射到不同的方法上 GET/POST/PUT/DELETE

    以至于优化出了以下注解 @GetMapping 、@PostMapping、@PutMapping、@DeleteMapping,效果同上

    拦截器:HandlerInterceptor

    springmvc有自己的拦截器,实现对请求前后的相关逻辑处理,相当于Servlet的Filter过滤器

    springmvc中定义一个Interceptor有一下四种方式:

    实现HandlerInterceptor接口,或继承实现了该接口的类 ,比如HandlerInterceptorAdapter

    实现Spring的 WebRequestInterceptor接口,或者继承实现了该接口的类

    一般常用第一种,实现HandlerInterceptor接口,重写

    preHandle :Handler执行前执行,比如登录认证,身份授权,返回Boolean

    postHandle :进入Handler,并在返回ModelAndView前执行,一般用于统一指定视图

    afterCompletion :执完Handler之后执行,比如异常处理,日志处理,释放资源等

    配置拦截器(全局拦截器配置):

    <!-- 配置全局mapping的拦截器 -->
    <mvc:interceptors>
         <!-- 公共拦截器可以拦截所有请求,而且可以有多个 -->
         <bean class="com.kkb.ssm.interceptor.MyHandlerInterceptor1" />
        <bean class="com.kkb.ssm.interceptor.MyHandlerInterceptor2" />
             <!-- 如果有多个拦截器,则按照顺序进行配置 -->
             <mvc:interceptor>
                      <!-- /**表示所有URL和子URL路径 -->
                      <mvc:mapping path="/test/**" />
             <!-- 特定请求的拦截器只能有一个 -->
                      <bean class="com.kkb.ssm.interceptor.MyHandlerInterceptor3" />
             </mvc:interceptor>
    </mvc:interceptors>

    如果有多个拦截器,则配置到最上面的拦截器的优先级最高

    SpringMVC父子容器

    画了个图外加描述理解一下:​

      

    Spring和SpringMVC是两个容器;

    Spring容器中存放着mapper代理对象,service对象,而SpringMVC中存放的事Controller对象,子容器可以通过@Autowired访问父容器注册过的中的Java实列,反之父容器想注入子容器中的Java实列就不行,比如在service中注入Controller行不通的;

    两个容器导入的配置文件,都只能在自己的容器里面使用,不具有传递性

    跨域处理

    跨域:域名,端口,协议的组合不同的访问就是跨域

    解决跨域的方式有多种:基于Js,基于Jq的JSONP以及基于CORS的方式

    JSONP只能解决get方式提交触发的跨域问题,CORS支持多种提交方式

    CORS是一个W3C标准,全称:“跨资源共享”,他允许浏览器向跨源服务器发起Ajax请求,克服了Ajax只能同源访问的限制

    CORS原理:只需要向响应头header中注入Access-Control-Allow-Origin,这样浏览器检测到header中的Access-Control-Allow-Origin,则就可以跨域操作了。

    详情见:https://www.cnblogs.com/msi-chen/p/10511558.html

    乱码解决

    Get提交:

      手段一: 修改Tomcat的编码格式为 UTF-8

      手段二:对请求参数进行重新编码,String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8")

    Post提交:

      手段一:在web.xml中限定编码

    <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>

      手段二:在RequestMapping注解中produces属性,指定响应体的编码格式

  • 相关阅读:
    Dllimport函数時无法在Dll中找到的入口点
    cb35a_c++_STL_算法_for_each
    cb34a_c++_STL_算法_查找算法_(7)_lower_bound
    cb33a_c++_STL_算法_查找算法_(6)binary_search_includes
    cb32a_c++_STL_算法_查找算法_(5)adjacent_find
    cb31a_c++_STL_算法_查找算法_(4)find_first_of
    cb30a_c++_STL_算法_查找算法_(3)search_find_end
    cb29a_c++_STL_算法_查找算法_(2)search_n
    cb28a_c++_STL_算法_查找算法_(1)find_find_if
    cb27a_c++_STL_算法_最小值和最大值
  • 原文地址:https://www.cnblogs.com/msi-chen/p/10835709.html
Copyright © 2011-2022 走看看