Spring MVC

MVC是什么?

MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写。
模型(Model) :模型是应用程序的主体部分。模型表示业务数据,或者业务逻辑。
视图(View) :视图是应用程序中用户界面相关的部分,是用户看到并与之交互的界面。
控制器(controller) :控制器工作就是根据用户的输入,控制用户界面数据显示和更新model对象状态。
MVC 式的出现不仅实现了功能模块和显示模块的分离,同时它还提高了应用系统的可维护性、可扩张性、可移植性和组件的可复用性。


image.png

Spring MVC是什么?

在web模型中,MVC是一种很流行的框架,通过把Model,View,Controller分离,是为了简化开发,减少出错。还是为了组内开发人员之间的配合。总之就是一种分层工作的办法。


7264030-a57dfd40d56add40.png

spring mvc(注解方式)

//Web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <init-param>   
<-- 默认为springmvc-servlet.xml 可以修改成自定义 -->
            <param-name>contextConfigLocation</param-name>
            <param-value>WEB-INF/springmvc.xml</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

//根据 web.xml的配置文件加载springmvc.xml

//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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <!--spring的扫描器实现bean的自动载入-->
    <context:component-scan base-package="Controller" />

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/page/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>
//controller
@Controller
public class controller {

    @RequestMapping("/index")
    public ModelAndView handleRequest(
            HttpServletRequest request, HttpServletResponse response)  {
        ModelAndView mav = new ModelAndView("index");
        mav.addObject("obj", "Hello Spring MVC");
        return mav;
    }
}

//启动tomcat 运行http://localhost:8080/index 
    输出:Hello Spring MVC

接受表单参数

//pojo
public class Product {
    private int id;
    private String name;
    private float price;
    //set get..
// 在web文件下先做一个直接可以显示.jsp
<form action="addProduct">   //提交表单

    产品名称:<input type="text" name="name"><br>
    产品价格:<input type="text" name="price">
    <input type="submit" value="增加商品">
</form>
//ProductController
@Controller
public class ProductController {
    @RequestMapping("/addProduct")
    public ModelAndView add(Product product) {
        ModelAndView mav = new ModelAndView("showProduct");
        mav.addObject("p", product);
        return mav;
    }
}

在WEB-INF/page下创建

//showProduct
产品名称: ${p.name}<br>
产品价格: ${p.price}

Springmvc客户端跳转

上面的例子都是将的服务端跳转,这时说的是客户端跳转

那什么是服务端跳转和客户端跳转呢?

客户端跳转时用HttPservletResopse对象的sendRedirect函数实现,服务器端跳转是使用RequestDispather对象的forward方法实现的。

客户端跳转:服务器端将请求结果返回给客户端,客户端向服务器发出另一次请求。在客户端跳转过程中是两次不同的请求。在地址栏中显示的是最后一次请求地址。
因为地址栏显示的是重定向后的url,所以只会执行后面的url映射的控制器.

服务器端跳转(容器内跳转):能够自动的在服务器内部进行跳转,这种跳转对用户来说是透明的。两次跳转时同一个request,在地址栏中显示的事第一次页面地址。

因为是同一个request,拦截器只会拦截前一个url,如果前一个url在
映射时未配置到拦截器拦截,则拦截后一个url,即只拦截一次;

因为地址栏显示的是转发前的url,所以会依次执行前后两个控制器.

//redirect

@Controller
public class ProductController {
    @RequestMapping("/addProduct")
    public ModelAndView add(Product product) {
        ModelAndView mav = new ModelAndView("redirect:/showProduct");
        mav.addObject("p", product);
        return mav;
    }

    @RequestMapping("/showProduct")
    public ModelAndView show(Product product) {
        ModelAndView mav = new ModelAndView("showProduct");
        return mav;
    }
}
//访问http://localhost:8080/addProduct.jsp 并提交数据
//因为使用了"redirect:/showProduct"
//此时地址栏是http://localhost:8080/showProduct

产品名称: 
产品价格:
为什么输出是空白呢?
因为地址栏显示的是重定向后的url,所以只会执行后面的url映射的控制器
//forward
//基于上面例子
@Controller
public class ProductController {
    @RequestMapping("/addProduct")
    public ModelAndView add(Product product) {
        ModelAndView mav = new ModelAndView("forward:/showProduct");
        mav.addObject("p", product);
        return mav;
    }

    @RequestMapping("/showProduct")
    public ModelAndView show(Product product) {
        ModelAndView mav = new ModelAndView("showProduct");
        return mav;
    }
}

//因为使用了"forward:/showProduct" 转发
//会执行两个控制器(/addProduct、/showProduct)
//访问http://localhost:8080/addProduct.jsp  并提交数据
//地址栏显示的是转发前的url
//此时地址栏http://localhost:8080/addProduct?name=X&price=1

产品名称: X
产品价格: 1

springmvc使用session

Session在用户登录,一些特殊场合在页面间传递数据的时候会经常用到

//controller
 @RequestMapping("/check")
    public ModelAndView check(HttpSession session) {
        ModelAndView mav = new ModelAndView("check");
        Integer count = (Integer) session.getAttribute("count");
        if (count == null) {
            session.setAttribute("count", 1);
        } else {
            session.setAttribute("count", ++count);
        }
        return mav;
//check.jsp
访问次数:${count}

//每刷新一次 count+1

springmvc处理中文问题

<!--处理中文问题-->
    <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>
//提交数据
<form action="addProduct" method="post">  //添加post请求
    产品名称:<input type="text" name="name"><br>
    产品价格:<input type="text" name="price">
    <input type="submit" value="增加商品">
</form>

Springmvc上传文件

首先,之前我们配置web.xml拦截了所有的请求。

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

我们要上传文件都会被拦截。所以我们有两种处理方式:
第一种: DispatcherServlet拦截".do"这样的有后缀的URL,就不存在访问不到静态资源的问题。
第二种:
如果你的DispatcherServlet拦截"/",为了实现REST风格,拦截了所有的请求,那么同时对.js,.jpg等静态文件的访问也就被拦截了。所以要在web.xml配置。

//web.xml
//这个必须在springmvc的servlet之前配置
<servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.jpg</url-pattern>
</servlet-mapping>

这里的例子采用第二种方式演示

//web.xml

    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.jpg</url-pattern>
    </servlet-mapping>
 <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>WEB-INF/springmvc.xml</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    
    <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>
//配置springmvc-servlet.xml

<!--spring的扫描器实现bean的自动载入-->
    <context:component-scan base-package="Controller" />
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/page/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <!--开放对文件上传支持-->
    <bean id="multipartResolver" 
          class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    </bean>
//upload.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" import="java.util.*" isELIgnored="false" %>

    // 上传图片表单 method="post"和enctype="multipart/form-data" 缺一不可
<form action="uploadImage" method="post" enctype="multipart/form-data">
    //上传组件 增加 accept="image/*" 表示只能选择图片进行上传
    选择图片:<input type="file" name="image" accept="image/*"><br>
    <input type="submit" value="上传">
</form>
//pojo类

public class UploadedImageFile {
    //用于接受页面的注入,字段image必须和上传页面upload.jsp中的name=image一致
    MultipartFile image;
    public MultipartFile getimage(){
        return image;
    }
    public void setImage(MultipartFile image){
        this.image = image;
    }
}
//Controller

@Controller
public class UploadController {

    @RequestMapping("/uploadImage")
    public ModelAndView upload(UploadedImageFile image, HttpServletRequest request) throws IOException {
        //生成一个随机名
        String name = RandomStringUtils.randomAlphabetic(10);
        String newFileName = name+ ".jpg";

        //获取到web目录下的image目录
        File newFile= new File(request.getServletContext().getRealPath("/image"),newFileName);
        //调用getParentFile()获得父目录,用.mkdirs()生成父目录文件夹
        newFile.getParentFile().mkdirs();
        //把内存图片写入磁盘中(写入图片)
        image.getimage().transferTo(newFile);
        ModelAndView mav = new ModelAndView("showUploadedFile");
        mav.addObject("imageName",newFileName);
        return mav;
    }
}
//showUploadedFile

<img src="image/${imageName}"/>


//图片缓存在out下
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,992评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,212评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,535评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,197评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,310评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,383评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,409评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,191评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,621评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,910评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,084评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,763评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,403评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,083评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,318评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,946评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,967评论 2 351

推荐阅读更多精彩内容