Spring MVC入门实践

2019-10-18  本文已影响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映射

<context:component-scan base-package = "controller"/>

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

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 language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" isELIgnored="false"%>
    
session中记录访问次数:${count}

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,进行视图与数据真正组合,再返回前端渲染。欢迎留言指导!!

上一篇 下一篇

猜你喜欢

热点阅读