`
MagicMa_007
  • 浏览: 25681 次
  • 性别: Icon_minigender_1
  • 来自: 郑州
社区版块
存档分类
最新评论

Spring MVC

阅读更多
Table of Contents
Spring MVC

1. 簡介

Spring MVC是一個和Spring完美結合的Web框架。我先前學過Struts2,再學Spring MVC,覺得Spring MVC更為簡約、高效和優雅,它有不少東西借鑒自Struts2,如依賴注入等。它功能完整,推薦在新項目中替代Struts2,至於Struts,直接秒殺。

下面的配置均采用Spring 3版本,Spring MVC基於Java Servlet技術規範,主要處理流程圖:



來自瀏覽器的請求URL由DispatcherServlet統一處理(除了css、js、圖片等靜態文件),它符合Java Servlet規範。在web.xml文件中配置哪些URL由該Servlet處理。
DispatcherServlet根據配置(通常由註解或xml文件配置)將URL請求發往相應的Controller處理,這個過程會帶上服務器端傳遞過來的參數並自動裝載給Controller。
Controller接收到參數後,調用相應的方法處理之,方法裡可以調用業務層接口或數據層接口等,然後將處理結果打包到一個ModelAndView對象中並返回。
DispatcherServlet將ModelAndView對象發往視圖解析器viewResolver處理。
視圖解析器根據ModelAndView對象中指定的視圖模板位置和攜帶的數據渲染模板文件為html文件,返回渲染後的文件。
DispatcherServlet將html文件(有時候是純文本或多媒體文件)返回給瀏覽器。
很好的教程:點擊

2. 安裝及配置文件

建議使用eclipse或netbeans編寫程式,只需要導入Spring和Spring Web的所有jar包即可。

按照習慣,Spring的xml配置文件統一放在classpath根目錄下並遵循applicationContext-*.xml的命名規範;web.xml配置css、js、圖片文件為靜態文件,靠後綴識別,其它URL由DispatcherServlet處理。web.xml配置文件如下。

不要使用/js/*作為靜態文件的url-pattern,這樣可以直接訪問WEB-INF下的文件。

web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

<!-- 解決亂碼問題 -->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf8</param-value>
</init-param>
<init-param>
    <param-name>forceEncoding</param-name>
    <param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<!-- 配置靜態文件 -->
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.css</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.js</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.jpg</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.jpeg</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.png</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.gif</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.bmp</url-pattern>
</servlet-mapping>

<!-- Spring MVC Servlet配置 -->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<!-- 如果有多個spring配置文件,用逗號隔開 -->
<param-value>classpath:applicationContext-*.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
Tomcat, Jetty, JBoss, and GlassFish 默認Servlet的名字 – “default”
Google App Engine 默認Servlet的名字 – “_ah_default”
Resin 默認Servlet的名字 – “resin-file”
WebLogic 默認Servlet的名字 – “FileServlet”
WebSphere 默認Servlet的名字 – “SimpleFileServlet”
classpath下關於Spring Web的配置文件:

applicationContext-web.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">

<!-- 【注意】這裡設置所有Controller所在的包位置,該包中所有使用annotation的類都會自動加載 -->
<context:component-scan base-package="springmvc.web" />

<!--
視圖解析器,由DispatcherServlet控制,根據Controller返回值選擇對應的模板
具體:Controller返回modelAndView或String對象,由對象name前面加上prefix,後面加上subfix形成文件的真實地址
-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>

<!-- 上傳文件 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
</beans>
3. 編寫Controller之Hello World

3.1 編寫Controller

Controller可以是任意一個普通類,不需要繼承或實現任何東西。Controller類必須放在配置文件applicationContext-web.xml中指定的註解包下,如springmvc.web,應根據實際情況修改。

HelloWorldController.java
package springmvc.web;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

// 通過註解使得該類變成Controller類
@Controller
// 根目錄,默認是"/",指定後為"/hello"
@RequestMapping("hello")
public class HelloWorldController {

// 該方法對應的URL,即訪問"/hello/hello_world"將調用該方法
@RequestMapping("hello_world")
public ModelAndView handleRequest() {

// modelAndView的名稱將會結合viewResolver配置的prefix和suffix合成一個頁面的路徑
ModelAndView modelAndView = new ModelAndView("hello_world");
// modelAndView對象攜帶的信息
modelAndView.addObject("message", "hello_world MVC!");
return modelAndView;
}

        // 一個類中可以寫很多這樣的方法,名稱自取,使用註解映射到不同的URL

        // 如果沒有附帶數據,也可以直接返回String類型的名稱
}
關於其它bean依賴注入,比如業務層或數據層的對象,使用註解可以讓Spring完成自動注入:

@Autowired
private CommonDao commonDao;
注意:ModelAndView的類不是org.springframework.web.portlet.ModelAndView

3.2 編寫jsp頁面

當請求鏈接”/hello/hello_world”發送到DispatcherServlet,轉發到HelloWorldController的handlerRequest方法,該方法返回modelAndView對象,根據該對象的名稱hello_world和配置文件中的prefix和suffix組合成物理jsp地址位置:/WEB-INF/jsp/hello_world.jsp

現在創建該jsp頁面:

hello_world.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
  <body>
<p>這是Controller傳過來的數據message:${message}</p>
  </body>
</html>
modelAndView對象中附帶的message字符串將被渲染到jsp頁面中。

部署該標準Java Web項目到tomcat服務器上,本機訪問http://127.0.0.1:8080/spring_mvc/hello/hello_world就可以看到網頁,其中spring_mvc是我在eclipse中的項目名稱,默認是這樣:

这是Controller传过来的数据message:hello_world MVC!
4. 獲得來自瀏覽器的參數及環境變量

4.1 GET或POST傳遞的參數

Spring MVC採用控制反轉的思想進行依賴注入,假設HTML頁面需要傳遞參數name和age,則HTML頁面有個form:

<form action="/some/url">
Name: <input type="text" name="name"/><br />
Age:  <input type="text" name="age"/><br />
</form>
這種提交形式是POST,也可以等同地使用GET方式提交:/some/url?name=pugwoo&age=24

然後Controller中對應的方法只需要在參數上加上對應名稱和類型的參數:

    @RequestMapping("/some/url")
    public ModelAndView handleRequest(String name, Integer age) {
        // 此時name和age已經擁有服務器端傳過來的值
        // 類型也會自動轉換,比如從String轉成Integer

        // 接下來,做你想做的事情
    }
如果想指定採用GET或POST方式,在@RequestMapping中指定method即可:

@RequestMapping(value = "/url", method = RequestMethod.GET)

@RequestMapping(value = "/url", method = RequestMethod.POST)
注:我不喜欢Spring 2.0使用Spring MVC标签来写HTML页面的方式。雖然它提供了參數驗證功能,但這個由自己寫的js來做更好,這樣有利於開發的解耦。

類Struts2的OGNL傳參形式

當頁面的變量很多時,可以採用OGNL方式傳遞變量,加入有類Car,Car有屬性String name和String model並提供對應的getter和setter方法,則HTML的<input>名稱可以寫為:”name”和”model”,然後在Controller的對應方法的參數中只寫Car car,Spring MVC會將該對象及其值構建好。

注意:<input>的name屬性不是填“car.name”,而是“name”。

Date類型的參數傳遞問題

頁面傳遞過來的數據均是String類型,爾後Spring將其轉化成對應類型。有些類型不是Spring默認可以轉換的,如Date。只需要在Controller.java代碼中加入一個binder方法即可:

@InitBinder
public void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
}
其中日期格式按照實際需要進行設置,如“yyyy-MM-dd HH:mm:ss”等。

4.2 獲得Cookie的值

在Controller對應的方法的參數使用@CookieValue註解獲得:

    @RequestMapping("/some/url")
    public ModelAndView handleRequest(@CookieValue("name") String name) {
        // 接下來,做你想做的事情
    }
4.3 上传文件

首先是HTML上傳頁面的form表格:

      <form action="upload" method="post" enctype="multipart/form-data">
        <input type="file" name="myfile" />
        <input type="submit" />
      </form>
然後編寫Controller,注意一定要加上@RequestParam,原因未明:

UploadController.java
package springmvc.web;

import java.io.IOException;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class UploadController {

    @RequestMapping("upload")
    // 一定要加上@RequestParam
    public ModelAndView uploadFile(@RequestParam MultipartFile myfile) throws IOException{
    ModelAndView modelAndView = new ModelAndView("result");

    // 顯示文件內容
    StringBuilder sb = new StringBuilder();

// 判斷文件是否已上傳
if (!myfile.isEmpty()) {
sb.append("文件名稱: " + myfile.getOriginalFilename() + "<br/>");

String content = new String(myfile.getBytes());
content = content.replace("\n", "<br/>");
sb.append(content);
} else {
sb.append("沒有選擇文件");
}

    modelAndView.addObject("result", sb.toString());
    return modelAndView;
    }
}
然後新建一個/WEB-INF/result.jsp文件:

result.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
  <body>
    <p>上傳的文件信息:</p>
<p>${result}</p>
  </body>
</html>
如果出現java.lang.NoClassDefFoundError: org/apache/commons/io/output/DeferredFileOutputStream異常,加上org.apache.commons.io包即可。

4.4 獲得環境變量

標準的Servlet規範中,有HttpServletRequest和HttpServletResponse等環節變量(關於這些變量的用途,請參見標準Servlet編程),Spring MVC可以很輕鬆地獲得,只需要像上面獲得參數一樣在方法參數中寫即可:

    @RequestMapping("/some/url")
    public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response) {

        // 你已獲得HttpServletRequest和HttpServletResponse對象,比Struts2實現***Aware接口還簡單

        // 接下來,做你想做的事情
    }
5. REST形式的URL

REST形式的URL對搜索引擎友好,看起來也很簡潔漂亮。Spring MVC實現REST形式URL很簡單,例子:

/**
* 在RequestMapping中,变量用{}括起来
* 然后在处理方法中用@PathVariable获取,名称要一致
* @PathVariable 里面也可以加上value="xxx",名称可以不一致
*/
@RequestMapping("/{name}/page/{p}")
public void handleRequest(Writer writer, @PathVariable String name,
@PathVariable Integer p) throws IOException{
writer.write("you are reading " + name +"'s page " + p);
}
URL中的數值會被作為變量傳入到方法中,如name和p,同樣是依賴注入的思想,類型會自動轉換,訪問下面的URL查看效果:

http://127.0.0.1:8080/spring_mvc/pugwoo/page/1
http://127.0.0.1:8080/spring_mvc/pugwoo/page/2
http://127.0.0.1:8080/spring_mvc/nick/page/99
6. 其它技巧

輸出純文本

例子,支持中文:

@RequestMapping("test")
public void test(HttpServletResponse resp) throws IOException {
resp.setContentType("text/plain;charset=utf-8");
resp.getWriter().write("Test 測試中文");
}
該方法適合做cgi接口,輸出json等格式的數據。

客戶端跳轉

設定Controller對應的方法返回名稱“redirect:hello_world”即可跳轉到對應的頁面,如hello_world。浏览器的地址栏会变化。

服務器端跳轉

設定Controller對應的方法返回名稱“forward:hello_world”即可跳轉到對應的頁面,如hello_world。

forward並不能將變量通過modelAndView傳遞給新的URL,只能通過將變量放在request或session裏面來完成。而對於redirect,變量只能放在session裏面,不能放在request裏。

jsp頁面標籤jstl

導入標籤:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
直接獲取某個變量的值:${message} 或 ${car.name} 等

循環遍歷容器,假如有類Car,Car有屬性name並且提供getter方法,對象數組ArrayList<Car> cars,則java語句:

for(Car car : cars) {
  System.out.println(car.getName());
}
等同於

<c:forEach items="${cars}" var="car">
    ${car.name} <br />
</c:forEach>
亂碼問題

上面的web.xml中已經解決了POST數據的亂碼問題,但是GET方式傳遞數據仍有亂碼,這是URL編碼的問題,需要在服務器容器端設置,以Tomcat為例,修改conf/server.xml文件對應位置新增“URIEncoding”:

    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" URIEncoding="utf-8"/>
修訂日誌

分享到:
评论
1 楼 maml897 2016-06-21  
Spring MVC是一個和Spring完美結合的Web框架。我先前學過Struts2,再學Spring MVC,覺得Spring MVC更為簡約、高效和優雅,它有不少東西借鉴自Struts2,如依賴注入等。



spring MVC的依赖注入是 借鉴struts2的,看到这就不想看了。


相关推荐

    精通Spring MVC 4

    Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。Spring MVC4是当前zuixin的版本,在众多特性上有了进一步的提升。, 在精通Spring...

    Spring MVC 入门实例

    首先, 我需要在你心里建立起 Spring MVC 的基本概念. 基于 Spring 的 Web 应用程序接收到 http://localhost:8080/hello.do(事实上请求路径是 /hello.do) 的请求后, Spring 将这个请求交给一个名为 helloController ...

    Spring MVC+MyBatis开发从入门到项目实战

    《Spring MVC+MyBatis开发从入门到项目实战》分为4篇。第1篇是Java开发环境的搭建,包括JDK的下载与安装、环境变量的配置、MyEclipse的下载与基本配置。第2篇是MyBatis技术入门,包括剖析JDBC的弊端、MyBatis的背景...

    精通Spring MVC 4 中文

    精通Spring MVC 4 中文

    [免费]Spring MVC学习指南(高清)

    Spring MVC是Spring框架中用于Web应用快速开发的一个模块,其中的MVC是Model-View-Controller的缩写。作为当今业界最主流的Web开发框架,Spring MVC已经成为当前最热门的开发技能,同时也广泛用于桌面开发领域。 ...

    spring mvc 官方文档

    本文详细介绍spring MVC的原理和开发心得体会。

    大优惠 Spring MVC学习指南(第2版)2017.pdf

    Spring MVC是Spring框架中用于Web应用快速开发的一个模块,其中的MVC是Model-View-Controller的缩写。作为当今业界最主流的Web开发框架,Spring MVC已经成为当前最热门的开发技能,同时也广泛用于桌面开发领域。 ...

    SSM(spring+spring MVC+mybatis)开发学生信息后台管理系统

    SSM(spring+spring MVC+mybatis)开发学生信息后台管理系统,实现学生增删改查功能设计一个简单的学生信息管理系统,要求使用SSM框架技术整合实现,用户登录后能够通过Web页面添加、删除、修改和查询学生信息 ...

    Spring MVC所需jar包

    Spring MVC所需jar包,包含java开发中 Spring MVC架构中最常用的jar包

    spring MVC环境搭建 所需jar包.zip

    spring MVC环境搭建 所需jar包 ├── commons-logging-1.1.1.jar ├── jstl.jar ├── spring-aop-4.3.0.RELEASE.jar ├── spring-aspects-4.3.0.RELEASE.jar ├── spring-beans-4.3.0.RELEASE.jar ├...

    Servlet JSP和Spring MVC初学指南

    Servlet JSP和Spring MVC初学指南

    spring MVC数据绑定大全

    spring MVC数据绑定 含例子 转载自疯芒毕露的专栏 刚开始用spring mvc 做web开发时 经常会不知道如何合适绑定页面数据 用惯struts2的朋友更认为spring mvc 绑定数据不如struts2方便 本人最开始也是这么认为 经过一段...

    spring mvc

    spring mvc最小代码。spring mvc最小代码。spring mvc最小代码。spring mvc最小代码。

    Spring MVC MyBatis开发从入门到项目实战

    Spring MVC MyBatis开发从入门到项目实战

    Spring MVC, A Tutorial, second edition 【2016】

    Spring MVC: A Tutorial (Second Edition) by Paul Deck AZW3/MOBI/EPUB/PDF 多种版本 This is a tutorial on Spring MVC, a module in the Spring Framework for rapidly developing web applications. The MVC in...

    Spring+Spring mvc+Hibernate+Bootstrap、企业级员工信息管理系统

    01. 采用后台及前台的 Spring + Spring mvc + Hibernate + Bootstrap 02. 后台全注解式的开发(除了必要的spring和hibernate的xml配置以外) 03. 后台通过自定义注解结合一个访问拦截器实现整个系统的权限控制 04...

    Spring MVC + Mybatis+Spring实现的个人博客系统

    Spring MVC + Mybatis+Spring实现的个人博客系统基于SSM实现的个人博客系统.zip

Global site tag (gtag.js) - Google Analytics