美文网首页
SpringMVC 快速入门

SpringMVC 快速入门

作者: 北街九条狗 | 来源:发表于2019-05-27 20:15 被阅读0次

    什么是Spring MVC?
    Spring MVC 为展现层提供的基于 MVC 设计理念的优秀的Web 框架,是目前最主流的 MVC 框架之一。
    Spring3.0 后全面超越 Struts2,成为最优秀的 MVC 框架

    • 导入jar包
    <!-- spring相关 -->
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-web</artifactId>
          <version>${springFramework.version}</version>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-webmvc</artifactId>
          <version>${springFramework.version}</version>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>${springFramework.version}</version>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-jdbc</artifactId>
          <version>${springFramework.version}</version>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-test</artifactId>
          <version>${springFramework.version}</version>
        </dependency>
        <!--日志-->
        <dependency>
          <groupId>org.apache.logging.log4j</groupId>
          <artifactId>log4j</artifactId>
          <version>2.10.0</version>
        </dependency>
        <dependency>
          <groupId>commons-logging</groupId>
          <artifactId>commons-logging</artifactId>
          <version>1.2</version>
        </dependency>
    

    fastjson与jackson作用一样可以选用任何一个,主流是jackson
    jackson可以运用注释将所需内容转换为json字符串类型

        <dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>fastjson</artifactId>
          <version>1.2.47</version>
        </dependency>
    
        <dependency>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-databind</artifactId>
          <version>2.9.8</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
        <dependency>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-core</artifactId>
          <version>2.9.8</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
        <dependency>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-annotations</artifactId>
          <version>2.9.8</version>
        </dependency>
    
    • 配置文件web.xml(WEB-INF下)
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" 
    id="WebApp_ID" version="3.1"> 
        <!-- 配置DispatchcerServlet前端控制器,请求集合点 -->
        <servlet>
            <servlet-name>springDispatcherServlet</servlet-name>
             <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
             <!-- 配置Spring mvc下的配置文件的位置和名称 -->
             <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>springDispatcherServlet</servlet-name>
             <url-pattern>/</url-pattern>
         </servlet-mapping>
    </web-app>
    

    注意: <param-value>classpath:springmvc.xml</param-value>用于配置spring mvc的配置文件的位置和名称,这里说明会新建一个springmvc.xml的配置文件。

    这里的servlet-mapping表示拦截的模式,这里是“/”,表示对于非jsp请求进行拦截。

    • Springmvc.xml(scr下)
      在src目录下新建springmvc.xml
    <?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">
            <!-- 配置自动扫描的包 -->
            <context:component-scan base-package="com.neusoft.controller"></context:component-scan>
            <!-- 配置视图解析器 如何把handler 方法返回值解析为实际的物理视图 -->
            <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
                <property name = "prefix" value="/WEB-INF/views/"></property>
                <property name = "suffix" value = ".jsp"></property>
            </bean>
           <mvc:annotation-driven></mvc:annotation-driven>
           <mvc:resources location="/js/" mapping="/js/**"/>
    </beans>
    

    <context:component-scan base-package="com.neusoft.controller"></context:component-scan>
    表示spring监听的范围,这里是在com.neusoft.controller下

    静态资源访问<mvc:resources>

    如果在DispatcherServlet中设置url-pattern为 /则必须对静态资源进行访问处理,否则对css,js等文件的请求会被DispatcherServlet拦截。
    spring mvc 的<mvc:resources mapping="" location="">实现对静态资源进行映射访问。告诉springmvc框架,描述的静态资源,无须DispatcherServlet拦截,以及查询的目录。

    SpringMVC应用

    1. 首先要在类的前面添加“Controller”注解,表示是spring的控制器,这里会写一个方法hello()

    2. hello方法上方有一个@RequestMapping, 是用于匹配请求的路径,比如这里匹配的请求路径就是“http://localhost:8080/helloworld”,即当tomcat服务启动后,在浏览器输入这个url时,如果在这个方法打断点了,就会跳入该方法。

    //第一种写路径的方法 在方法前通过注解@GetMapping("/user/add")将路径写全
    @Controller
    public class HelloController1 {
        @GetMapping("/user/add")
        public void hello(){
            System.out.println("hello springmvc2");
        }
        @RequestMapping("/user/ald")
        public void hello1(){
            System.out.println("hello nigun");
        }
    }
    //第二种写路径的方法 在类前通过@GetMapping("/user")将一级路径配好
    @Controller
    @GetMapping("/user")
    public class HelloController1 {
        @GetMapping("/add")
        public void hello(){
            System.out.println("hello springmvc2");
        }
        @RequestMapping("/ald")
        public void hello1(){
            System.out.println("hello nigun");
        }
    }
    
    • 返回值类型
      String -- 可以转发和重定向,Model可以代替request传值
      ModelAndView
      void
      在请求转发通过return进行返回时可以不用将路径写全但是要在Springmvc.xml中有如下的配置(只有只有请求转发可以使用)
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name = "prefix" value="/WEB-INF/views/"></property>
        <property name = "suffix" value = ".jsp"></property>
    </bean>
    
    1. 返回ModelAndView
      返回ModelAndView时最常见的一种返回结果。需要在方法结束的时候定义一个ModelAndView对象,并对Model和View分别进行设置。
    @Controller
    public class HelloWorldController {
        @RequestMapping("/abc")
        public ModelAndView abc(){
            // 相当于request.setAttribute
            ModelAndView modelAndView = new ModelAndView();
           //相当于请求转发
            modelAndView.addObject("username","zhangsan");
            modelAndView.setViewName("success");
            return modelAndView;
        }
    }
    
    1. 返回String
      1). 字符串代表逻辑视图名(默认做的是请求转发)
      真实的访问路径=“前缀”+逻辑视图名+“后缀”
      注意:如果返回的String代表逻辑视图名的话,那么Model的返回方式如下:
        @RequestMapping("/helloworld")
        public String hello(Model model){
            model.addAttribute("username","zhangsan");
            System.out.println("hello world");
            return "success";
        }
    

    2):代表redirect重定向(不走视图解析器)

    redirect的特点和servlet一样,使用redirect进行重定向那么地址栏中的URL会发生变化,同时不会携带上一次的request

    案例:

    @Controller
    public class HelloWorldController {
        @RequestMapping("/helloworld")
        public String hello(Model model){
            model.addAttribute("username","zhangsan");
            System.out.println("hello world");
            return "success";
        }
        @RequestMapping("/abc")
        public ModelAndView abc(){
            ModelAndView modelAndView = new ModelAndView();
            modelAndView.addObject("username","zhangsan");
            modelAndView.setViewName("success");
            return modelAndView;
        }
        @RequestMapping("/redirect")
        public String redirect(){
              return "redirect:login.do";
        }
    }
    

    3):代表forward转发

    通过forward进行转发,地址栏中的URL不会发生改变,同时会将上一次的request携带到写一次请求中去

    案例:

    @Controller
    public class HelloWorldController {
        @RequestMapping("/helloworld")
        public String hello(Model model){
            model.addAttribute("username","zhangsan");
            System.out.println("hello world");
            return "success";
        }
        @RequestMapping("/abc")
        public ModelAndView abc(){
            ModelAndView modelAndView = new ModelAndView();
            modelAndView.addObject("username","zhangsan");
            modelAndView.setViewName("success");
            return modelAndView;
        }
    
        @RequestMapping("/redirect")
        public String redirect(){
              return "forward:login";
        }
    }
    
    1. 返回void
      返回这种结果的时候可以在Controller方法的形参中定义HTTPServletRequest和HTTPServletResponse对象进行请求的接收和响应
      1)使用request转发页面
      request.getRequestDispatcher("转发路径").forward(request,response);
      2)使用response进行页面重定向
      response.sendRedirect("重定向路径");
      3)也可以使用response指定响应结果
      response.setCharacterEncoding("UTF-8");
      response.setContentType("application/json;charset=utf-8");
      response.getWriter().println("json串");
        @RequestMapping("/returnvoid.do")
        public void returnvoid(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //        request.getRequestDispatcher("转发路径").forward(request,response);
    //        response.sendRedirect("重定向路径");
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json;charset=utf-8");
            response.getWriter().println("json串");
        }
    

    以上三种返回值没有什么重要和不重要的分别,一般来说都会使用到, 只不过有的时候使用的方式会有一些细微的差别

    当页面通过ajax发过来请求后 ,将所需内容通过json字符串形式返回,fastjson与jackjson的对比

        /*fastjson*/
       @GetMapping("serch")
        public void serch(@RequestParam("name") String name, HttpServletResponse response) throws IOException {
            Student student = new Student();
           if(name.equals("mike")){
                student.setUsername("MIKE");
               student.setPassword("123456");
                student.setAge(99);
                response.getWriter().println(JSON.toJSONString(student));
            }else{
                student.setUsername("haha");
                student.setPassword("000000");
                student.setAge(-1);
                response.getWriter().println(JSON.toJSONString(student));
            }
        }
    
        /*jackjson*/
        @GetMapping("serch")
        @ResponseBody // 利用jackson返回json字符串
        public Student serch(@RequestParam("name") String name) throws IOException {
            Student student = new Student();
            if(name.equals("mike")){
                student.setUsername("MIKE");
                student.setPassword("123456");
                student.setAge(99);
            }else{
                student.setUsername("haha");
                student.setPassword("000000");
                student.setAge(-1);
            }
            return student;
        }
    
    • @RequestMapping 后路径全写与简写对比
    @RequestMapping("/atr")
    public class HelloController {
        @RequestMapping(value = "/add",method = RequestMethod.GET)
        public void hello(){
            System.out.println("hello springmvc");
        }
        @PostMapping("/ald")
        public void hello1(){
            System.out.println("hello gun");
        }
    }
    
    • 响应ajax时可以通过@ResponseBody或类前加注解@RestController返回其它类型值
        @ResponseBody
        public int login(Userinfo userinfo, HttpSession session, HttpServletResponse response) throws IOException {
            if(userinfo.getUsername().equals("mike")&&userinfo.getPassword().equals("123")){
                return 1;
            }else {
                return 0;
            }
        }
        @GetMapping("/serch1")
        @ResponseBody
        public Userinfo serch1(Integer id){
            Userinfo userinfo=new Userinfo();
            userinfo.setUsername("tom");
            userinfo.setPassword("123");
            userinfo.setSex(1);
            return userinfo;
        }
    

    上传图片

    在页面form中提交enctype="multipart/form-data"的数据时,需要springmvc对multipart类型的数据进行解析

    在springmvc.xml中配置multipart类型解析器。

    <!-- 文件上传 -->
    
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!--限制文件大小-->
        <property name="maxUploadSize" value="80000"></property>
        <property name="defaultEncoding" value="UTF-8"></property>
    </bean>
    

    上传图片代码
    页面

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
    <form action="upload.do" method="post" enctype="multipart/form-data">
        <h2>文件上传</h2>
        文件:<input type="file" name="file1"/><br/><br/>
        用户名:<input type="text" name="username">
        <br/><br/>
        图片:<img src="${imgpath}"/><br/><br/>
        <input type="submit" value="上传"/>
    </form>
    </body>
    </html>
    

    controller方法

    @Controller
    public class uploadController {
       @RequestMapping("/upload.do")
       public void doUpload(@RequestParam MultipartFile file1, HttpServletRequest request) throws IOException {
    
           String strName = request.getParameter("username");
           System.out.println(strName);
           if(file1.isEmpty()){
             System.out.println("文件未上传!");
           }
           else {
             //得到上传的文件名
             String fileName = file1.getOriginalFilename();
             //得到服务器项目发布运行所在地址
             String strFolder = request.getServletContext().getRealPath("/image")+ File.separator;
             File folder = new File(strFolder);
             if(!folder.exists())
             {
                 folder.mkdir();
             }
             //  此处未使用UUID来生成唯一标识,用日期做为标识
             String strNewFilePath = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())+ fileName;
             String strFinalPath = strFolder + strNewFilePath;
             //查看文件上传路径,方便查找
             System.out.println(strFinalPath);
             //把文件上传至path的路径
             File localFile = new File(strFinalPath);
             file1.transferTo(localFile);
             request.getSession().setAttribute("imgpath", "image"+ File.separator+strNewFilePath);
             }
         }
    }
    

    拦截器

    拦截器是用来动态拦截 action 调用的对象。它提供了一种机制可以使开发者可以定义在一个 action 执行的前后执行的代码,也可以在一个 action 执行前阻止其执行,同时也提供了一种可以提取 action 中可重用部分的方式

    拦截器工作原理

    HandlerInterceptor概述

    • 在SpringMVC 中定义一个Interceptor是比较非常简单,实现HandlerInterceptor接口。

    • HandlerInterceptor接口主要定义了三个方法:

    1. boolean preHandle (HttpServletRequest request, HttpServletResponse response, Object handle)方法:该方法将在请求处理之前进行调用,只有该方法返回true,才会继续执行后续的Interceptor和Controller,当返回值为true 时就会继续调用下一个Interceptor的preHandle 方法,如果已经是最后一个Interceptor的时候就会是调用当前请求的Controller方法;

    2. void postHandle (HttpServletRequest request, HttpServletResponse response, Object handle, ModelAndView modelAndView)方法:该方法将在请求处理之后,DispatcherServlet进行视图返回渲染之前进行调用,可以在这个方法中对Controller 处理之后的ModelAndView 对象进行操作。

    3. void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex)方法:该方法也是需要当前对应的Interceptor的preHandle方法的返回值为true时才会执行,该方法将在整个请求结束之后,也就是在DispatcherServlet 渲染了对应的视图之后执行。用于进行资源清理。

    简单的一个例子:

    xml需要配置:两种配置方式(对所有的请求记性拦截,对特定的请求进行拦截)

         <!-- 拦截器 -->
         <mvc:interceptors>
            <mvc:interceptor>
                 <mvc:mapping path="/page/add" />
                 <bean class="com.neuedu.interceptor.CheckInterceptor"></bean>
            </mvc:interceptor>
         </mvc:interceptors>
    

    interceptors类

    package com.neuedu.interceptor;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    
    public class CheckInterceptor implements HandlerInterceptor{
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
                throws Exception {
            if(request.getSession().getAttribute("login_user") == null) {
                request.getRequestDispatcher("/WEB-INF/jsp/user/login.jsp").forward(request, response);
                return false;
            }else {
                return true;
            }
        }
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                ModelAndView modelAndView) throws Exception {
            System.out.println(456);
        }
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
                throws Exception {
            System.out.println(789);
        }
    }
    

    URL 模板模式映射

    @RequestMapping(value="/ viewItems/{id}")
    {×××}占位符,请求的URL可以是“/viewItems/1”或“/viewItems/2”,通过在方法中使用@PathVariable获取{×××}中的×××变量。@PathVariable用于将请求URL中的模板变量映射到功能处理方法的参数上。

      @RequestMapping("/viewItems/{id}") 
      public @ResponseBody viewItems(@PathVariable("id") String id) throws Exception{    
    
      }
    

    如果RequestMapping中表示为"/viewItems/{id}",id和形参名称一致,@PathVariable不用指定名称。

      @RequestMapping("/viewItems/{id}") 
      public @ResponseBody viewItems(@PathVariable String id) throws Exception{
         
      }
    

    多个参数

    @Controller  
    @RequestMapping("/person") 
    public class PersonAction{     
        @RequestMapping(value="/delete/{id}/{name}")
        public String delete(@PathVariable Integer id,@PathVariable String name){
            System.out.println(id + "   " + name) ;
            return "person";
        }
    }  
    

    相关文章

      网友评论

          本文标题:SpringMVC 快速入门

          本文链接:https://www.haomeiwen.com/subject/volktctx.html