spring-mvc結構
1. DispatcherServlet:中央控制器,把請求給轉發到具體的控制類
1. Controller:具體處理請求的控制器
2. handlerMapping:映射處理器,負責映射中央處理器轉發給controller時的映射策略
3. ModelAndView:服務層返回的數據和視圖層的封裝類
4. ViewResolver & View:視圖解析器,解析具體的視圖
5. Interceptors :攔截器,負責攔截我們定義的請求然後做處理工作
spring-mvc流程
springMVC依賴的包
org.springframework.aop-3.0.3.RELEASE.jar |
spring的aop面向切面編程 |
org.springframework.asm-3.0.3.RELEASE.jar |
spring獨立的asm字節碼生成程序 |
org.springframework.beans-3.0.3.RELEASE.jar |
IOC的基礎實現 |
org.springframework.context-3.0.3.RELEASE.jar |
IOC基礎上的擴展服務 |
org.springframework.core-3.0.3.RELEASE.jar |
spring的核心包 |
org.springframework.expression-3.0.3.RELEASE.jar |
spring的表達式語言 |
org.springframework.web-3.0.3.RELEASE.jar |
web工具包 |
org.springframework.web.servlet-3.0.3.RELEASE.jar |
mvc工具包 |
springmvc的配置文件
配置中央控制器
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<!-- 中央控制器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!-- struts習慣使用/*,在springmvc不管用 -->
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
springmvc的核心配置文件
文件的命名規則:中央控制器(servlet的名稱)的名稱+“-servlet.xml”
默認位置:WEB-INF下
配置:controller和視圖解析器
創建controller
三種handlerMapping
1.BeanNameUrlHandlerMapping (默認)
<!-- 按着controller的name來映射尋找controller,默認存在 -->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
2.SimpleUrlHandlerMapping
<!-- 使用簡單url來映射 -->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/hello1.do">myController</prop>
</props>
</property>
</bean>
3.ControllerClassNameHandlerMapping
<!-- 控制類的類名控制器,訪問時類名首字母需要小寫 -->
<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"></bean>
springmvc基於註解的開發
創建web項目springmvc的配置文件中指定註解驅動,配置掃描器
<!-- mvc的註解驅動 -->
<mvc:annotation-driven/>
<!-- 一旦有掃描器的定義mvc:annotation-driven不需要,掃描器已經有了註解驅動的功能 -->
<context:component-scan base-package="cn.itcast.springmvc"/>
<!-- 前綴+ viewName +後綴 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- webroot到某一指定的文件夾的路徑 -->
<property name="prefix" value="/WEB-INF/jsp/"></property>
<!-- 視圖名稱的後綴 -->
<property name="suffix" value=".jsp"></property>
</bean>
註解方式參數以及例子
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import org.springframework.web.servlet.ModelAndView;
import cn.itcast.springmvc.model.Person;
import cn.itcast.springmvc.model.User;
@Controller
// 用來標註當前類是springmvc的控制層的類
@RequestMapping("/test")
// controller的唯一標識或者命名空間
public class TestController {
/**
* @return
*/
@RequestMapping("/hello.do")
// 用來訪問控制層的方法的註釋
public String hello() {
return "jsp1/index";
}
@RequestMapping("/toPerson.do")
public String toPerson(HttpServletRequest request) {
String result = request.getParameter("name");
System.out.println(result);
return "jsp1/index";
}
/**
* 在參數列表上直接定義要接收的參數名稱,只要參數名稱能匹配的上就能接收所傳送過來的數據,
* 可以自動轉換參數列表裏面的類型,注意的是:值與類型之間可以轉化的
*
* @param name
* @return
*/
@RequestMapping("/toPerson1.do")
public String toPerson1(String name, Integer age, String address,
Date birthday) {
System.out.println("name:" + name + "," + "age:" + age + ","
+ "address:" + address + "birthday:" + birthday);
return "jsp1/index";
}
/**
* 註冊時間類型的屬性編輯器
*
* @param binder
*/
@InitBinder
public void initBinder(ServletRequestDataBinder binder) {
binder.registerCustomEditor(Date.class, new CustomDateEditor(
new SimpleDateFormat("yyyy-MM-dd"), true));
}
/**
* 傳遞的參數的名字必須要與實體類的屬性set方法後面的字符串上才能接受到參數,首字符的大小寫不區分
* 請求中傳的參數只要是和參數列表裏面的變量名或者實體裏面的set後面的字符串匹配的上就能接收到
*
* @param person
* @return
*/
@RequestMapping("/toPerson2.do")
public String toPerson2(Person person, User user) {
System.out.println(person);
System.out.println(user);
return "jsp1/index";
}
@RequestMapping("/toPerson3.do")
public String toPerson3(String[] name) {
for (String str : name) {
System.out.println(str);
}
return "jsp1/index";
}
/**
* 方法的返回值採用ModelAndView,new ModelAndView("index",map) ,相當於把結果數據放到request裏面
*
* @param name
* @return
* @throws Exception
*/
@RequestMapping("/toPerson4.do")
public ModelAndView toPerson4(String[] name) throws Exception {
Person person = new Person();
person.setName("Sunny");
person.setAge(28);
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
person.setAddress("Beijing");
Date date = format.parse("2012-12-12");
person.setBirthday(date);
Map<String, Object> map = new HashMap<String, Object>();
map.put("p", person);
return new ModelAndView("index", map);
}
/**
* 直接在方法的參數列表中來定義Map,這個Map即使ModelAndView裏面的Map,
* 由視圖解析器統一處理,統一走ModelAndView的接口
*
* @param map
* @return
* @throws Exception
*/
@RequestMapping("/toPerson5.do")
public String toPerson5(Map<String, Object> map) throws Exception {
Person person = new Person();
person.setName("Sunny");
person.setAge(28);
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
person.setAddress("廣州");
Date date = format.parse("2012-12-12");
person.setBirthday(date);
map.put("p", person);
return "index";
}
/**
* @param map
* @return
* @throws Exception
*/
@RequestMapping("/toPerson6.do")
public String toPerson6(Model model) throws Exception {
Person person = new Person();
person.setName("Sunny");
person.setAge(28);
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
person.setAddress("廣州");
Date date = format.parse("2012-12-12");
person.setBirthday(date);
// 把參數放到request類裏面去
model.addAttribute("p", person);
return "index";
}
@RequestMapping(value = "/toPerson7.do", method = RequestMethod.POST)
public String toPerson7(Person person) {
System.out.println(person);
return "jsp1/index";
}
@RequestMapping("/toForm.do")
public String toForm() {
return "form";
}
@RequestMapping("/toAjax.do")
public String toAjax() {
return "ajax";
}
@RequestMapping("/rediectToForm.do")
public String rediectToForm() {
return "redirect:toForm.do";
}
/**
* controller之間的重定向:必須要指定好controller的命名空間再指定requestMapping的值:
* 後必須加"/" 是從根目錄開始找
*
* @return
*/
@RequestMapping("/rediectToForm1.do")
public String rediectToForm1() {
return "redirect:/test1/toForm.do";
}
/**
* ajax的請求返回值類型應該是void,參數列表裏直接定義HttpServletResponse,
* 獲得PrintWrite的類,最後可把結果寫到頁面 不建議試用
*
* @return
*/
@RequestMapping("/ajax.do")
public void ajax(String name, HttpServletResponse response)
throws Exception {
String result = "hello" + name;
response.getWriter().write(result);
}
/**
* 直接在參數列表上定義PrintWriter,out.write(result);把結果寫到頁面,建議使用
*
* @param name
* @param out
* @throws Exception
*/
@RequestMapping("/ajax1.do")
public void ajax1(String name, PrintWriter out) throws Exception {
String result = "hello" + name;
out.write(result);
}
}
文件上傳
引入jar包
配置視圖解析器
<!-- id="multipartResolver"必須是multipartResolver -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- maxUploadSize:文件上傳的最大值以byte爲單位 -->
<property name="maxUploadSize" value="1024000"></property>
</bean>
文件上傳的例子
@SuppressWarnings("resource")
@RequestMapping(value = "/toPerson8.do", method = RequestMethod.POST)
public String toPerson8(Person person,HttpServletRequest request) throws Exception {
//第一步轉化request
MultipartHttpServletRequest rm=(MultipartHttpServletRequest) request;
//獲得文件
CommonsMultipartFile cfile=(CommonsMultipartFile) rm.getFile("pic");
//獲得文件的字節數組
byte[] bfile=cfile.getBytes();
String fileName="";
//獲得當前時間的最小精度
SimpleDateFormat format=new SimpleDateFormat("yyyyMMddHHmmSSS");
fileName=format.format(new Date());
//獲得三位隨機數
Random random=new Random();
for(int i=0;i<3;i++){
fileName=fileName+random.nextInt(9);
}
//獲得原始文件名
String origFileName=cfile.getOriginalFilename();
String suffix=origFileName.substring(origFileName.lastIndexOf("."));
//定義文件的輸出流
String path=request.getSession().getServletContext().getRealPath("/");
OutputStream out=new FileOutputStream(new File(path+"/upload/"+fileName+suffix));
out.write(bfile);
out.flush();
out.close();
return "jsp1/index";
}
攔截器
攔截示意圖:
攔截器的配置文件的配置
<mvc:interceptors>
<mvc:interceptor>
<!-- 某一模塊的攔截:/myPath/**, 攔截所有的請求/**-->
<mvc:mapping path="/**"/>
<bean class="cn.itcast.springmvc.interceptor.MyIntercepor"></bean>
</mvc:interceptor>
</mvc:interceptors>
代碼示例:
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class MyIntercepor implements HandlerInterceptor {
/*
*執行時機:視圖已經解析完畢,類似try catch後的finally
*/
@Override
public void afterCompletion(HttpServletRequest arg0,
HttpServletResponse arg1, Object arg2, Exception ex)
throws Exception {
System.out.println("afterCompletion...");
}
/*
*執行時機:在controller執行完,視圖解釋器沒有把視圖解析成頁面,
* 對視圖做統一的修改,主要體現在Model上
*/
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
Object arg2, ModelAndView mv) throws Exception {
System.out.println("postHander...");
Map<String , Object> map=mv.getModel();
map.put("test", "append something");
}
/*
*執行時機:在執行controller之前來執行
* 返回值類型:boolean:true 代表放行就可以訪問controller,false不可以訪問controller
*/
@Override
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,
Object arg2) throws Exception {
System.out.println("preHander...");
return true;
}
}
相關的資源文件地址: