美文网首页
Spring MVC入门实践

Spring MVC入门实践

作者: 我不是刺猬_ | 来源:发表于2019-10-18 14:44 被阅读0次

    1. 简介

    spring mvc是spring框架的一个组件,该组件的作用是在url访问与后台java bean之间起到访问控制,路由映射的作用,传统的是servlet + jsp + java,spring将这个流程整合为spring mvc。
    模型(Model):指java bean产生的一些信息,如模型数据。
    视图(View):jsp的统称,占位符,标签元素确定展示形式,可以引用前端js文件。
    控制器(Controller):spring mvc主要起到路由与方法映射的作用,被映射的类称为控制器。
    有两种方式配置url与控制类的映射,XML方式与java注解方式。

    2. 请求流程

    image.png

    xml方式配置实现url映射
    1)web.xml : 在web.xml中配置/与DispatcherServlet的映射,所有http请求都经过DispatcherServlet调度,DispatcherServlet将其转发到另一个具体映射类简单url处理器映射(SimpleUrlHandlerMapping),接下来流转到第二个配置文件springmvc-servlet.xml。

        <servlet>
            <servlet-name>springmvc</servlet-name>
            <servlet-class>
                org.springframework.web.servlet.DispatcherServlet
            </servlet-class>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>springmvc</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
    

    2)springmvc-servlet.xml :在SimpleUrlHandlerMapping bean下配置具体url与Controller的映射,例如/index与indexController。

    <bean id="simpleUrlHandlerMapping"
            class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
            <property name="mappings">
                <props>
                    <prop key="/index">indexController</prop>
                </props>
            </property>
        </bean>
        <bean id="indexController" class="controller.IndexController"></bean> 
    

    3)控制器:IndexController.java : Controller会将http请求头request作为参数,此阶段可以获取url参数,经过逻辑处理后,通过模型与视图对象(ModelAndView)将模型数据与视图打包,此时的视图只是逻辑视图名index.jsp,

    //@Controller//注解方式
    public class IndexController {
    //public class IndexController implements Controller {
        //@RequestMapping("/index")//  忽略,这是注解方式映射路由,不同于xml方式
        public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
            ModelAndView mav = new ModelAndView("index");
            mav.addObject("message", "Hello Spring MVC4");
            return mav;
        }
    }
    

    4)后续数据流程 : 返回给DispatcherServlet,DispatcherServlet将逻辑视图与具体的视图匹配后,将数据注入到视图中,返回客户端进行渲染呈现。访问 http://127.0.0.1:8080/springmvc/index

    3. 注解方式实现url映射

    • web.xml不变,与xml方式配置相同。
    • DispatcherServlet.xml文件中,将第二步代码注释,添加
    <context:component-scan base-package = "controller"/>
    

    指定组件扫描包,扫描的就是我们要用@Cotroller修饰的类。

    • 在控制类用@Controller修饰,方法用@requestMaping(“/index”)作为路由映射

    4.视图定位

    1)为什么需要视图定位?

    假设我们在localhost/spring/下放一些jsp文件,那么用户可以直接访问url就能获取,比如说用户通过尝试一些url,造成数据泄露
    解决方法:我们在WEB-INF目录下新增page文件夹,将所有的jsp文件都放置到page目录下,使用户在不改变url:http://localhost/spring/index.jsp路径,依然能访问到资源,这种方法就是通过视图定位实现的。
    做法: 在DispatcherServlet.xml文件中,增加用来控制视图定位的bean,如下

    
    <bean id= "viewResolver" class = "org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name = "prefix" value= "/WEB-INF/page/"></property>
            <property name = "suffix" value = ".jsp"> </property>
        </bean>
    

    还记得上一步控制类组装视图与模型数据么?ModelAndView一开始获取到的只是逻辑视图,就是一个jsp 的name,此时并没有与模型数据组合,此时返回给DispatcherSevlet,它将逻辑视图与真正的视图进行映射数据的组合,最后返回给客户端。

    5. 接受表单数据

    1)表单访问页
    WebContent一级目录下创建addProduct.jsp页

    image.png
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8" import="java.util.*" isELIgnored="false"%>
    //action属性相当于跳转到的目标路由
    <form  action = "addProduct" method = "post">
        <input  type = "text" name = "name" value = ""/>
        <input type = "text" name = "price"  value = ""/>
        <input type = "submit" value = "add product"/>
    </form>
    
    

    2)实体类 :src/pojo/下创建Product.java作为实体类

    package pojo;
    
    public class Product {
        private String name;
        private float price;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public float getPrice() {
            return price;
        }
        public void setPrice(float price) {
            this.price = price;
        }
    }
    
    

    3)控制类

    image.png
    上图为目录结构
    package controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.servlet.ModelAndView;
    import pojo.Product;
    
    @Controller
    public class ProductController {
        @RequestMapping("/addProduct")
        public ModelAndView add(Product product) throws Exception{
            ModelAndView mov = new ModelAndView("showProduct");
            return mov;
        }
    }
    

    解释 : addProduct.jsp 提交的name和price会自动注入到参数 product里,参数product会默认被当做值加入到ModelAndView 中,相当于mav.addObject("product",product);

    4)生成新视图
    创建ShowProduct.jsp用来M

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8" isELIgnored="false"%>
        
        name:${product.name}
        price:${product.price}odelAndView注入数据的新视图
    

    6.客户端跳转

    相当于url重定向,访问/jump会重定向到/index

        @RequestMapping("/jump")
        public ModelAndView jump() {
            ModelAndView moa = new ModelAndView("redirect:/index");
            return moa;
        }
    

    7.用session记录回话访问次数

        @RequestMapping("/check")
        public ModelAndView getSession(HttpSession session) {
            Integer count = (Integer)session.getAttribute("count");
            if(count == null) {
                count = 0;
            }
            count++;
            session.setAttribute("count", count);
            ModelAndView moa = new ModelAndView("check");
            return moa;
        }
            
    
    • 在page下新建check.jsp视图
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8" isELIgnored="false"%>
        
    session中记录访问次数:${count}
    
    
    • 访问下图url
      image.png

    8. 中文编码配置

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

    9. 上传文件

    1)配置允许访问jpg文件,在web.xml中增加

    <servlet-mapping>
            <servlet-name>default</servlet-name>
            <url-pattern>*.jpg</url-pattern>
        </servlet-mapping>
    

    2)DispatcherSevlet.xml中配置上传功能需要的 java bean

    <!--  上传功能支持 --> 
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
     <mvc:interceptors>
    

    3)上传页面
    WebContent下添加upload.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8" import="java.util.*" isELIgnored="false"%>
        
    <form  action = "uploadImage" method = "post" enctype = "multipart/form-data">
        <input type = "file" name = "image" accept = "image/*">
        <input type = "submit" value = 上传>
    
    </form>
    

    4)接受图片类
    pojo下新建UploadedImageFile,文件目录如下

    image.png
    加入如下代码
    package pojo;
    
    import org.springframework.web.multipart.MultipartFile;
    
    public class UploadedImageFile {
        MultipartFile image;
    
        public MultipartFile getImage() {
            return image;
        }
    
        public void setImage(MultipartFile image) {
            this.image = image;
        }
    }
    
    

    5)控制类 UploadController

    //上传没问题,路径显示有问题
    @Controller
    public class UploadController {
        @RequestMapping("/uploadImage")
        public ModelAndView upload(HttpServletRequest request,UploadedImageFile file) 
                throws IllegalStateException, IOException{
            String name = RandomStringUtils.randomAlphanumeric(10);
            String newFileName = name + ".jpg";
            File newFile = new File(request.getServletContext().getRealPath("/image"), newFileName);
            newFile.getParentFile().mkdirs();
            file.getImage().transferTo(newFile);
            System.out.println(request.getServletContext().getRealPath("/image"));
            ModelAndView mav = new ModelAndView("showUploadedFile");
            mav.addObject("imageName", newFile);
            return mav;
        }
    }
    
    

    6) page下新建showUploadFile.jsp接受图片视图

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8" isELIgnored="false"%>
    
    <image src = "${imageName}}"/>
    

    7)访问http://127.0.0.1:8080/springmvc/upload.jsp

    10. 拦截器

    目的:拦截器的作用是访问某个url时,被映射的控制器会在被调用前访问指定方法,调用时访问指定方法,调用结束后访问指定方法。
    1)DispatcherServlet.xml中配置添加拦截器bean

     <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path = "/index"/> //需要拦截器的路由
            <bean class = "interceptor.IndexInterceptor"/>
        </mvc:interceptor>
     </mvc:interceptors>
    

    2)配置拦截器类
    src/interceport包下新建拦截器类

    package interceptor;
    
    public class IndexInterceptor extends HandlerInterceptorAdapter{
        public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object Handler) throws Exception{
            System.out.println("拦截处理器被调用");
            
            return true;
        }
        
        public void postHandle(HttpServletRequest request,HttpServletResponse response,
                Object handler, ModelAndView mav) throws Exception{
            mav.addObject("date",new Date());
            System.out.println("postHandle(),访问路由对应控制器后,视图访问前,添加一个时间对象到视图中,拦截处理器被调用");
        }
        
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
                Object obj, Exception exp)throws Exception{
            System.out.println("aftercompletion()拦截处理器被调用完后执行");
        }
    }
    

    3)访问配置了拦截器的地址:http://localhost:8080/springmvc/ndex

    image.png

    总结:直白些,spring mvc就是将所有的请求都交给了DispatcherServlet,它来调配具体url与控制类的映射,控制类调用其他java类与方法在逻辑处理后,控制类将视图与模型数据再返回给DispatcherServlet,进行视图与数据真正组合,再返回前端渲染。欢迎留言指导!!

    相关文章

      网友评论

          本文标题:Spring MVC入门实践

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