一、SpringMVC 简介
SpringMVC 是 Spring 针对 MVC 设计模式所推出的一种框架,尤其是针对 MVC 模式中的控制层。SpringMVC 结构设计完全符合传统的 MVC 设计开发。最大特点在于简单易用。
MVC 设计模式
在当今的企业级项目开发中,MVC 设计模式是主要的设计模式,是行业所遵循的。Java EE 最初的设计阶段,MVC 的结构如下:
实际上可将以上结构分为两部分
Web 开发技术:JSP + Servlet + Filter + JSTL + EL + JavaScript + jQuery + ......(Web 开发技术通俗来讲就是前端技术,相对复杂许多,因为其需要与用户交互,也即显示层和控制层)
EJB 开发技术:会话 Bean(SessionBean)、实体 Bean(EntityBean)、消息驱动 Bean(MessageDriverBean),包含业务层和数据层会话 Bean:进行业务处理实体 Bean:数据层,进行数据库操作消息驱动 Bean:Java 消息服务(JMS),产生出了 ActiveMQ、RabbitMQ、Kafka
图 MVC 设计模式
资金雄厚的企业往往选择付费软件,例如 web 容器选择 IBM 的 WebSphere,数据库选择 Oracle 或者 DB2,银行系统就是用了 WebSphere 容器。
web 开发技术与会话层互相访问,需要通过远程协议 RMI(Remote Method Invocation)进行。同时,远程访问,传递参数,故 VO 类需要序列化。这也是 VO 对象序列化的原因。
图 Web 与 EJB 远程访问
因为 EJB 技术过于复杂,同时思想超前。所以,人们将精力更多的放到了 web 技术上。并且,由于免费容器的推出和一系列框架的诞生,诸如 struts、spring、hibernate 等。使得开发越来越便捷。而 SpringMVC 可以说是控制层框架里目前发展最好的,很好的解决了一下 MVC 设计问题:
更多的多业务处理,避免开发者进行反射操作;
轻松实现 VO 与传递参数的互相转换,本质在于 servlet,可以通过 request 对象获取客户端请求的所有信息,再通过反射机制最终实现转换;
提供了拦截器(struts1.x 没有拦截器,struts2.x 才有拦截器),为服务器端接受的参数进行验证;
便捷的文件上传;
提供安全的访问机制,所有 JSP 保存在 WEB-INF 后可以轻松取得。
二、配置 Spring MVC 开发环境
2.1、在配置 Spring 框架的基础上,增加 SpringMVC 包的支持,pom.xml 配置文件添加的信息如下:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.13.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.13.RELEASE</version>
</dependency>
复制代码
2.2、web.xml 增加 Spring 框架支持
2.2.1、SpringMVC 是建立在 Spring 容器之上运行的,因此,项目需要添加 Spring 框架支持。Spring 容器的启动交由 web 容器控制,在 web.xml 文件中添加监听。
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
复制代码
2.2.2、Spring 容器启动,需要 applicationContext.xml 配置文件的支持,这样才能读取 Spring 容器的上下文信息,因此,需要添加 applicationContext.xml 的位置信息。
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/classes/applicationContext.xml
</param-value>
</context-param>
复制代码
2.2.3、Spring 容器之中添加 SpringMVC 需要的处理用户请求的操作类(org.springframework.web.servlet.DispatcherServlet),由这个操作类进行参数的验证、后续程序的调用以及用户请求的处理。
<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:applicationContext-mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
复制代码
2.2.4、Spring 提供了过滤器进行编码过滤
<filter>
<filter-name>encoding</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>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
复制代码
2.2.5、添加 applicationContext-mvc.xml 配置文件,专门负责 MVC 的配置,同时添加 Spring MVC 框架的规则支持,以下展示简要部分。
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
</beans>
复制代码
2.2.6、配置文件打开注解支持以及 applicationContext-mvc.xml 增加 mvc 的注解支持和默认 servlet 操作类
<context:annotation-config/>
<context:component-scan base-package="org.fuys.own"/>
<mvc:annotation-driven/>
<mvc:default-servlet-handler/>
复制代码
三、SpringMVC 程序示例
處理數據發送至 JSP 頁面進行顯示,由控制層跳轉到 JSP 頁面進行參數傳遞需要使用 request 屬性範圍,這個 request 屬性對象可以通過 ModelAndView 進行控制。
org.springframework.web.servlet.ModelAndView 沒有父類,實際上負責頁面跳轉和參數傳遞,類似與 request.getRequestDispatcher()、forward()、request.setAttribute()。
Java 源程序:
package org.fuys.own.controller;
import java.util.ArrayList;
import java.util.Map;
import java.util.UUID;
import java.util.WeakHashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
@RequestMapping("/goal/*")
public class GoalController {
private Logger logger = LoggerFactory.getLogger(GoalController.class);
// 1、從類到方法上的整體請求路徑的簡易設置
@RequestMapping("/goal")
// 2、開發者自定義返回數據類型,若爲空,則頁面顯示http狀態為404
// 3、可以直接定義傳遞參數
public void goal(String goalId){
logger.info("Goal id is " + goalId);
}
// ModelAndView負責頁面跳轉和參數傳遞
@RequestMapping("queryGoalList")
public ModelAndView queryQoalList(String name){
logger.info("Goals' name is " + name);
return null;
}
@RequestMapping("updateGoal")
public ModelAndView updateGoal(String goalId){
ModelAndView mav = new ModelAndView("/pages/goal.jsp");
mav.addObject("goal", goalId);
logger.info("GoalId is " + goalId);
return mav;
}
@RequestMapping("addGoal")
public ModelAndView addGoal(String name){
Map<String, Object> map = new WeakHashMap<>();
map.put("goalId", UUID.randomUUID());
map.put("name", name);
ModelAndView mav = new ModelAndView("/pages/goal.jsp");
mav.addAllObjects(map);
mav.addObject("goal", "okay");
logger.info("GoalId is " + map);
return mav;
}
}
复制代码
四、SpringMVC 方法參數
4.1、使用 int 進行接收
@RequestMapping("/test")
public ModelAndView test(int id){
logger.info("test id is " + id);
return null;
}
复制代码
4.2、設置參數名稱
儅出現傳遞參數名稱和方法參數名稱不一致時,可以通過設置參數名稱,達到正確傳參。
@RequestMapping("/test")
public ModelAndView test(@RequestParam("tid") int id){
logger.info("test id is " + id);
return null;
}
复制代码
4.3、分頁處理
若沒有傳遞參數值,則可以設置默認值。
@RequestMapping("querytestList")
public ModelAndView queryTestList(
@RequestParam(value="cp",defaultValue="1")int currentPage,
@RequestParam(value="ls",defaultValue="10")int lineSize,
@RequestParam(value="kw",defaultValue="test")String keyword){
logger.info("currentPage is " + currentPage);
logger.info("lineSize is " + lineSize);
logger.info("keyword is " + keyword);
return null;
}
复制代码
4.4、内置對象設置
使用 HttpServletRequest 和 HttpServletResponse 類進行處理操作。例如:cookie、頭信息、映射路徑以及 Ajax 輸出支持。
@RequestMapping("getTest")
public ModelAndView getTest(@RequestParam(value="tid",defaultValue="10")int id,
HttpServletRequest request,HttpServletResponse response){
logger.info(" *** id ***" + id);
logger.info(" *** sessionId ***" + request.getSession().getId());
logger.info(" *** contextPath ***" + request.getContextPath());
logger.info(" *** realPath ***" + request.getServletContext().getRealPath("/"));
try {
response.getWriter().print("request and response object");
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
复制代码
4.5、參數與 VO 轉換
VO 類:
package org.fuys.own.vo;
import java.io.Serializable;
import org.springframework.stereotype.Repository;
@Repository
public class Goal implements Serializable {
private static final long serialVersionUID = -3571483870932700806L;
private String goalId;
private String name;
private String description;
}
复制代码
controller 類方法:
@RequestMapping("/goal")
public void goal(Goal goal){
logger.info("Goal id is " + goal.getGoalId());
}
复制代码
爲了能夠處理傳遞參數包含日期的問題,則定義一個父類,進行日期的格式化處理,建議該父類為抽象類,可以方便擴展。该方式便是一个模板设计模式的应用。
package org.fuys.own.controller;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
/**
* define public abstract class for controller
* to get public method
* @author ys
*
*/
public abstract class AbstractController {
/**
* format date parameter
* @param data
*/
@InitBinder
public void initBinder(WebDataBinder data) {
data.registerCustomEditor(Date.class,
new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"), true));
}
}
复制代码
對於對象嵌套的問題,傳遞參數可以使用“對象.屬性”進行參數傳遞。
五、安全訪問
在整個 web 項目的目錄中,WEB-INF 是具有最高的安全級別,標準的 Spring 結構應當把 JSP 頁面放置于 WEB-INF 目錄下。傳統的方式文件保存在 WEB-INF 目錄下,就必須通過配置文件 web.xml 取得。所以,Spring 對此,進行了改進,既保存在 WEB-INF 目錄下,又能夠方便取得。
下面在 applicationContext-mvc.xml 文件裏追加配置。
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
复制代码
六、配置資源文件
現在開發的項目都會使用到屬性文件,因此,也可以通過配置的方式對資源文件進行操作處理,資源文件如 log4j.properties 文件。下面在 applicationContext-mvc.xml 文件裏添加配置。其中 id 的名稱固定。
配置文件:
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<array>
<value>log4j</value>
</array>
</property>
</bean>
复制代码
Java 代碼:
package org.fuys.own.controller;
import javax.annotation.Resource;
import org.springframework.context.MessageSource;
/**
* define public abstract class for controller
* to get public method
* @author ys
*/
public abstract class AbstractController {
@Resource
private MessageSource messageSource;
public String getValue(String key,Object ...args){
return this.messageSource.getMessage(key, args, Locale.getDefault());
}
}
复制代码
评论