zoukankan      html  css  js  c++  java
  • Spring MVC起步

    1. MVC概念

    1.1 前端控制器       

       

    1.2 MVC概念                MVC的核心思想---业务数据抽取 与 业务数据呈现 相分离

    View:视图层,为用户提供UI,重点关注数据的呈现;
    Model:模型层,业务数据的信息表示,关注支撑业务地信息构成,通常是多个业务实体的组合;
    Cotroller:控制层,调用业务逻辑产生合适的数据,传递数据给视图层用于呈现;

    MVC是什么?
    1、MVC是一种架构模式,是程序分成,分工合作,既相互独立,有协同工作。
    2、MVC是一种思考方式,模型层思考为用户展现什么,在视图层思考如何布局,在控制层思考调用那些业务逻辑。

    2. Spring MVC概念

    2.1  Spring MVC 基本概念
    1、DispatcherServlet:  前端控制器
    2、Controller: 调用业务逻辑生成model的地方
    3、HandlerAdapter:处理器适配器DispatcherServlet通过HandlerAdapter调用controller
    4、HandlerInterceptor:处理器拦截器 该接口提供after postHandle preHandle 三个方法,调用controller前后使用
    5、HandlerMapping:前端控制器与controller映射关系的类
    6、HandlerExecutionChain: preHandle->Controller method->postHandle->afterCompletion的执行链
    7、ModelAndView:model的具体表现
    8、ViewResolver:视图解析器,决定需要用哪个视图来进行视图的呈现。

    2.2 架构流程图

    2.3  架构流程

           1、 用户发送请求至前端控制器DispatcherServlet

       2、 DispatcherServlet收到请求调用HandlerMapping处理器映射器。

           3、 处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。

         4、 DispatcherServlet通过HandlerAdapter处理器适配器调用处理器

       5、 执行处理器(Controller,也叫后端控制器)。

       6、 Controller执行完成返回ModelAndView

       7、 HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet

       8、 DispatcherServlet将ModelAndView传给ViewReslover视图解析器

       9、 ViewReslover解析后返回具体View

       10、 DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中) 

       11、 DispatcherServlet响应用户

    3. 应用maven工具,管理springMVC

     3.1  maven的三个重要概念:配置pom.xml,依赖dependency, 坐标coordinates(groupId,artifactId,version,packaging)

     3.2 maven配置     setting.xml配置镜像仓库:用UK的镜像仓库可以提高访问成功率

    镜像配置,每次访问Maven时候都先访问配置的这个库,下载所需要的软件包,这样可以降低中心仓库的负载,中心仓库为了避免大量访问造成的服务问题有时会拒绝
    我们的访问。

     3.3 Maven创建项目

    3.3.1.  添加Maven  在继承Maven的eclipse中,windows--->prefrences---->Maven--->Installation--->将新下载的maven文件add进去,确保在user Setings中配置文件的路径是之前配置了mirror的配置文件setting.xml

    3.3.2.  运行命令行创建项目 注意:需要在命令行中进入指定创建项目的路径  例如:cd C:UsersWorkspacesEclipse 

    命令: mvn archetype:generate -DgroupId=imooc-arthur -DartifactId=spring-mvc-study -DarchetypeArtifactId=maven-archetype-webapp

    参数解释:   archetype:generate 调用插件

          groupId:坐标

          artifactId:坐标的一个元素,目录结构的根目录名称

          archetypeArtifactId:目录类型的一个类型,此为webapp的类型

    3.3.3  搭建Spring MVC基础框架

      1.导入项目 import-->Maven(ExistingMaven Projects)-->刚创建的文件目录spring-mvc-study

      2.缺失Java目录时,手动添加Java目录 右键main-->folder-->java

      3.pom.xml 添加各种依赖包

      4.web.xml文件 配置 DispatcherServlet -- Spring MVC的核心

        如果不配置<init-param>,那么将会默认读取WEB-INF目录下的%servlet-name%-servlet.xml配置文件,配置init-param后将读取这里配置的文件

                

      5.mvc-dispatcher-servlet.xml 启用Spring基于annotation的DI 配置DispatcherServlet上下文, 只管理@Controller类型的bean, 忽略其他型的bean, 如@Service 扩充了注解驱动,可以将请求参数绑定到控制器参数 配置ViewResolver;可以用多个ViewResolver;使用order属性排序;InternalResourceViewResolver放在最后。

      6.创建Controller类

      7.创建home.jsp

      8.运行jetty(在配置文件中配置的jetty插件为我们提供了一个运行的容器环境),访问

    4. 在具体项目中实现springMVC

    4.1 配置文件

    4.1.1  在web.xml文件中如此配置

     <!-- Spring应用上下文, 理解层次化的ApplicationContext -->
      <context-param>
             <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/configs/spring/applicationContext*.xml</param-value>
      </context-param>
    <!-- DispatcherServlet对应的上下文配置, 默认为/WEB-INF/$servlet-name$-servlet.xml
             -->
            <init-param>
              <param-name>contextConfigLocation</param-name>
              <param-value>/WEB-INF/configs/spring/mvc-dispatcher-servlet.xml</param-value>
            </init-param>

            

     通过使用不同的dispatcher-servlet来做不同的分发,可以更好的服务不同来源的请求。

    4.1.2  配置名为mvc-dispatcher的DispatcherServlet,为其提供spring MVC配置  

    mvc-dispatcher-servlet.xml文件中
    <beans>
       xmlns=········
    ············································省略..
    <!-- 本配置文件是供名为mvc-dispatcher的DispatcherServlet使用, 提供其相关的Spring MVC配置 -->
    
        <!-- 启用Spring基于annotation的DI, 使用户可以在Spring MVC中使用Spring的强大功能。 激活 @Required 
            @Autowired,JSR 250's @PostConstruct, @PreDestroy and @Resource 等标注 -->
        <context:annotation-config />
    
        <!-- DispatcherServlet上下文, 只管理@Controller类型的bean, 忽略其他型的bean, 如@Service -->
        <context:component-scan base-package="com.zang.mvcdemo">
            <context:include-filter type="annotation"
                expression="org.springframework.stereotype.Controller" />
        </context:component-scan>
    
        <!-- HandlerMapping, 无需配置, Spring MVC可以默认启动。 DefaultAnnotationHandlerMapping 
            annotation-driven HandlerMapping -->
    
        <!-- 扩充了注解驱动,可以将请求参数绑定到控制器参数 -->
        <mvc:annotation-driven />
    
        <!-- 静态资源处理, css, js, imgs -->
        <mvc:resources mapping="/resources/**" location="/resources/" />
    
    
        <!-- 配置ViewResolver。 
          可以用多个ViewResolver。 
          使用order属性排序。 
         InternalResourceViewResolver放在最后。 -->
        <bean
            class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
            <property name="order" value="1" />
            <property name="mediaTypes">
                <map>
                    <entry key="json" value="application/json" />
                    <entry key="xml" value="application/xml" />
                    <entry key="htm" value="text/html" />
                </map>
            </property>
    
            <property name="defaultViews">
                <list>
                    <!-- JSON View -->
                    <bean
                        class="org.springframework.web.servlet.view.json.MappingJackson2JsonView">
                    </bean>
                </list>
            </property>
            <property name="ignoreAcceptHeader" value="true" />
        </bean>
    
        <bean
            class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="viewClass"
                value="org.springframework.web.servlet.view.JstlView" />
            <property name="prefix" value="/WEB-INF/jsps/" />
            <property name="suffix" value=".jsp" />
        </bean>
    </beans>

    4.1.3 配置applicationContext.xml

        <context:annotation-config />
    
        <context:component-scan base-package="com.zang.mvcdemo">
        <!-- context:exclude-filter:不需要管理Controller了     -->
            <context:exclude-filter type="annotation"
                expression="org.springframework.stereotype.Controller" />
        </context:component-scan>

    4.2 Controller代码

    @Controller声明了一个Controller
    @RequestMapping对应到具体的请求
    @RequestParam 和@PathVariable绑定了请求中的参数
    也可以使用HttpServletRequest 或HttpSession请求响应
    @Controller
    @RequestMapping("/courses")
    // /courses/**
    public class CourseController {
        
        private static Logger log = LoggerFactory.getLogger(CourseController.class);
    
        private CourseService courseService;
    
        @Autowired
        public void setCourseService(CourseService courseService) {
            this.courseService = courseService;
        }
    
        
        //本方法将处理 /courses/view?courseId=123 形式的URL
        @RequestMapping(value="/view", method=RequestMethod.GET)
        public String viewCourse(@RequestParam("courseId") Integer courseId,
                Model model) {
            
            
            log.debug("In viewCourse, courseId = {}", courseId);
            Course course = courseService.getCoursebyId(courseId);
            model.addAttribute(course);
            return "course_overview";
        }
        
        //本方法将处理 /courses/view2/123 形式的URL
        @RequestMapping("/view2/{courseId}")
        public String viewCourse2(@PathVariable("courseId") Integer courseId,
                Map<String, Object> model) {
            
            log.debug("In viewCourse2, courseId = {}", courseId);
            Course course = courseService.getCoursebyId(courseId);
            model.put("course",course);
            return "course_overview";
        }
    
        //本方法将处理 /courses/view3?courseId=123 形式的URL
        @RequestMapping("/view3")
        public String viewCourse3(HttpServletRequest request) {
            
            Integer courseId = Integer.valueOf(request.getParameter("courseId"));        
            Course course = courseService.getCoursebyId(courseId);
            request.setAttribute("course",course);
            
            return "course_overview";
        }   }
    4.3 Binding——绑定(将请求中的字段按照名字匹配的原则填入模型对象))
    @RequestMapping中也可以添加params="add"属性,表示带add参数的请求才可以进来;返回字符串可以加/来进行相对目录的指定。
    @ModelAttribute可以用于绑定对象,返回值加上"redirect:XXXX"就可以重定向 方法级别数据绑定@ModelAttribute注释一个方法的参数
    1.从Model中获取
       2.从Form表单或URL参数中获取(实际上,不做此注释也能拿到user对象)
    redirect(重定向)/forward(请求转发)
    @RequestMapping(value="/admin", method = RequestMethod.GET, params = "add")
        public String createCourse(){
            return "course_admin/edit";
        }
        
        @RequestMapping(value="/save", method = RequestMethod.POST)
        public String  doSave(@ModelAttribute Course course){        
            
            log.debug("Info of Course:");
            log.debug(ReflectionToStringBuilder.toString(course));
            
            //在此进行业务操作,比如数据库持久化
            course.setCourseId(123);
            return "redirect:view2/"+course.getCourseId();
        }

    4.4 fileUpload 单文件上传

    ①注册使用到的类:CommonsMultipartReslover类,这个类需要在spring的配置文件中进行配置,并设置一些必要的属性,比如是否延迟加载,上传文件的大小等等。
    ②注意form表单中,对应的表单的name值应该和controller中参数Multipart file的名称一致,另外注意表单提交方式为post,MIME编码为multipart/form-data
    ③在controller中通过传入的参数类型为Multipart file并且使用@Requestparam注解,完成参数的绑定,这样表单中的file就被复制到参数对象中。然后通过Multipart的一些方法,
    获取文件的名字信息并得到文件流对象,然后使用FileUtils类的copyInputStreamToFile(文件流,文件)完成文件的上传。
    4.4.1 mvc-dispatcher-servlet.xml文件中加入如下bean配置
        <!--200*1024*1024即200M resolveLazily属性启用是为了推迟文件解析,以便捕获文件大小异常 -->
        <bean id="multipartResolver"
            class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
            <property name="maxUploadSize" value="209715200" />
            <property name="defaultEncoding" value="UTF-8" />
            <property name="resolveLazily" value="true" />
        </bean>

    4.4.2 pom.xml文件里配置相关jar包依赖

    4.4.3 Controller

        @RequestMapping(value="/upload", method=RequestMethod.GET)
        public String showUploadPage(@RequestParam(value= "multi", required = false) Boolean multi){    
            if(multi != null && multi){
                return "course_admin/multifile";    
            }
            return "course_admin/file";        
        }
        
        @RequestMapping(value="/doUpload", method=RequestMethod.POST)
        public String doUploadFile(@RequestParam("file") MultipartFile file) throws IOException{
            
            if(!file.isEmpty()){
                log.debug("Process file: {}", file.getOriginalFilename());
                FileUtils.copyInputStreamToFile(file.getInputStream(), new File("c:\temp\imooc\", System.currentTimeMillis()+ 
         file.getOriginalFilename())); }
    return "success"; } @RequestMapping(value="/doUpload2", method=RequestMethod.POST) public String doUploadFile2(MultipartHttpServletRequest multiRequest) throws IOException{ Iterator<String> filesNames = multiRequest.getFileNames(); while(filesNames.hasNext()){ String fileName =filesNames.next(); MultipartFile file = multiRequest.getFile(fileName); if(!file.isEmpty()){ log.debug("Process file: {}", file.getOriginalFilename()); FileUtils.copyInputStreamToFile(file.getInputStream(), new File("c:\temp\imooc\", System.currentTimeMillis()+
           file.getOriginalFilename())); } }
    return "success"; }

    4.5 JSON(一种轻量级的数据交换的格式)

    springMVC使用viewResovler来处理含义相同格式不同(json xml html)的数据
    4.5.1 mvc-dispatcher-servlet.xml文件中(记得加入依赖)
     <!-- 配置ViewResolver。  可以用多个ViewResolver。      使用order属性排序。    InternalResourceViewResolver放在最后。 -->
        <bean
            class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
            <property name="order" value="1" />
            <property name="mediaTypes">
                <map>
                    <entry key="json" value="application/json" />
                    <entry key="xml" value="application/xml" />
                    <entry key="htm" value="text/html" />
                </map>
            </property>
    
            <property name="defaultViews">
                <list>
                    <!-- JSON View -->
                    <bean
                        class="org.springframework.web.servlet.view.json.MappingJackson2JsonView">
                    </bean>
                </list>
            </property>
            <property name="ignoreAcceptHeader" value="true" />
        </bean>

    Controller

         @RequestMapping(value="/{courseId}",method=RequestMethod.GET)
        public @ResponseBody Course getCourseInJson(@PathVariable Integer courseId){
            return  courseService.getCoursebyId(courseId);
        }
           
         @RequestMapping(value="/jsontype/{courseId}",method=RequestMethod.GET)
        public  ResponseEntity<Course> getCourseInJson2(@PathVariable Integer courseId){
            Course course =   courseService.getCoursebyId(courseId);        
            return new ResponseEntity<Course>(course, HttpStatus.OK);
        }

    4.5.2 在前端使用ajax异步处理,触发请求,在请求的url中传入id,到后台之后,后台根据url,分解出pathVariable ,调用service方法,获得数据对象,然后返回@ResponseBody,此时,前台的ajax正在监听服务端的状态,如果是成功状态,将触发回调函数,函数中封装了对数据的逻辑,也就是使用js技术把数据对号入座,并且美化,展示页面。请求路径是一种restful风格。

    前台异步获取数据

    <script>
    jQuery(function($){
        var urlStr = "<%=request.getContextPath()%>/courses/<%=request.getParameter("courseId")%>";
        //alert("Before Call:"+urlStr);
        $.ajax({
            method: "GET",
            url: urlStr,
            success:function(data,status,jqXHR){
                //alert("Success:"+data);
                var course = data;
                var path = "<%=request.getContextPath()%>/";    
                $(".course-title").html(course.title);
                $(".course_video").attr("src", path+course.imgPath);
                $("#learningNum").text(course.learningNum);
                $("#duration").text(course.duration);
                $("#levelDesc").text(course.levelDesc);
                $(".course_shortdecription").html(course.descr);
                
                var chapterList = course.chapterList;
                var chapter;
                
                for(var i = 0;i<chapterList.length;i++){
                    chapter = chapterList[i];    
                    
                    var liObj = $("li",$("#chapterTemplate")).clone();                 
                    $(".outline_name", liObj).text(chapter.title);
                    $(".outline_descr", liObj).text(chapter.descr);                
                    liObj.appendTo("#couList");                
                }// ~ end for            
            }
        }); // end ajax
    });
    </script>

    4.5.3 Json view的三种方式

       ContentNegotiatingViewResolver 决定返回的数据是以Json还是jsp格式展示

       ResponseEntity将返回的数据包裹在其中,便可以以Json格式返回

       @ResponseBody/@ResquestBody 可以将请求值和返回值变成Json格式传输

    5. summary

  • 相关阅读:
    Devops运维交流群
    CentOS7.5下二进制安装MySQL5.7.26
    CentOS7.5安装MySQL8.0.18简易流程
    Kubernetes中的Pod生命周期详解
    Linux系统发行版本及其区别
    数据库设计
    Vue 起步
    CSS 中的伪类和伪元素
    百度智能云虚拟主机 Typecho 分类功能失效 | 开启伪静态地址
    C#开发BIMFACE系列39 网页集成开发3:审图系统中三维模型比对
  • 原文地址:https://www.cnblogs.com/zjfjava/p/6746704.html
Copyright © 2011-2022 走看看