MVC是什么?
MVC全名是Model View Controller,是模型(model)-視圖(view)-控制器(controller)的縮寫。
模型(Model) :模型是應用程序的主體部分。模型表示業(yè)務數(shù)據(jù),或者業(yè)務邏輯。
視圖(View) :視圖是應用程序中用戶界面相關的部分,是用戶看到并與之交互的界面。
控制器(controller) :控制器工作就是根據(jù)用戶的輸入,控制用戶界面數(shù)據(jù)顯示和更新model對象狀態(tài)。
MVC 式的出現(xiàn)不僅實現(xiàn)了功能模塊和顯示模塊的分離,同時它還提高了應用系統(tǒng)的可維護性、可擴張性、可移植性和組件的可復用性。

Spring MVC是什么?
在web模型中,MVC是一種很流行的框架,通過把Model,View,Controller分離,是為了簡化開發(fā),減少出錯。還是為了組內(nèi)開發(fā)人員之間的配合??傊褪且环N分層工作的辦法。

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>
//根據(jù) 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的掃描器實現(xiàn)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
接受表單參數(shù)
//pojo
public class Product {
private int id;
private String name;
private float price;
//set get..
// 在web文件下先做一個直接可以顯示.jsp
<form action="addProduct"> //提交表單
產(chǎn)品名稱:<input type="text" name="name"><br>
產(chǎn)品價格:<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下創(chuàng)建
//showProduct
產(chǎn)品名稱: ${p.name}<br>
產(chǎn)品價格: ${p.price}
Springmvc客戶端跳轉(zhuǎn)
上面的例子都是將的服務端跳轉(zhuǎn),這時說的是客戶端跳轉(zhuǎn)
那什么是服務端跳轉(zhuǎn)和客戶端跳轉(zhuǎn)呢?
客戶端跳轉(zhuǎn)時用HttPservletResopse對象的sendRedirect函數(shù)實現(xiàn),服務器端跳轉(zhuǎn)是使用RequestDispather對象的forward方法實現(xiàn)的。
客戶端跳轉(zhuǎn):服務器端將請求結(jié)果返回給客戶端,客戶端向服務器發(fā)出另一次請求。在客戶端跳轉(zhuǎn)過程中是兩次不同的請求。在地址欄中顯示的是最后一次請求地址。
因為地址欄顯示的是重定向后的url,所以只會執(zhí)行后面的url映射的控制器.
服務器端跳轉(zhuǎn)(容器內(nèi)跳轉(zhuǎn)):能夠自動的在服務器內(nèi)部進行跳轉(zhuǎn),這種跳轉(zhuǎn)對用戶來說是透明的。兩次跳轉(zhuǎn)時同一個request,在地址欄中顯示的事第一次頁面地址。
因為是同一個request,攔截器只會攔截前一個url,如果前一個url在
映射時未配置到攔截器攔截,則攔截后一個url,即只攔截一次;
因為地址欄顯示的是轉(zhuǎn)發(fā)前的url,所以會依次執(zhí)行前后兩個控制器.
//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 并提交數(shù)據(jù)
//因為使用了"redirect:/showProduct"
//此時地址欄是http://localhost:8080/showProduct
產(chǎn)品名稱:
產(chǎn)品價格:
為什么輸出是空白呢?
因為地址欄顯示的是重定向后的url,所以只會執(zhí)行后面的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" 轉(zhuǎn)發(fā)
//會執(zhí)行兩個控制器(/addProduct、/showProduct)
//訪問http://localhost:8080/addProduct.jsp 并提交數(shù)據(jù)
//地址欄顯示的是轉(zhuǎn)發(fā)前的url
//此時地址欄http://localhost:8080/addProduct?name=X&price=1
產(chǎn)品名稱: X
產(chǎn)品價格: 1
springmvc使用session
Session在用戶登錄,一些特殊場合在頁面間傳遞數(shù)據(jù)的時候會經(jīng)常用到
//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
訪問次數(shù):${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>
//提交數(shù)據(jù)
<form action="addProduct" method="post"> //添加post請求
產(chǎn)品名稱:<input type="text" name="name"><br>
產(chǎn)品價格:<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,就不存在訪問不到靜態(tài)資源的問題。
第二種:如果你的DispatcherServlet攔截"/",為了實現(xiàn)REST風格,攔截了所有的請求,那么同時對.js,.jpg等靜態(tài)文件的訪問也就被攔截了。所以要在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的掃描器實現(xiàn)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);
//調(diào)用getParentFile()獲得父目錄,用.mkdirs()生成父目錄文件夾
newFile.getParentFile().mkdirs();
//把內(nèi)存圖片寫入磁盤中(寫入圖片)
image.getimage().transferTo(newFile);
ModelAndView mav = new ModelAndView("showUploadedFile");
mav.addObject("imageName",newFileName);
return mav;
}
}
//showUploadedFile
<img src="image/${imageName}"/>
//圖片緩存在out下