写点什么

SpringMVC 基础

作者:andy
  • 2022-10-27
    北京
  • 本文字数:5169 字

    阅读完需:约 17 分钟

一、SpringMVC 简介


SpringMVC 是 Spring 针对 MVC 设计模式所推出的一种框架,尤其是针对 MVC 模式中的控制层。SpringMVC 结构设计完全符合传统的 MVC 设计开发。最大特点在于简单易用。


MVC 设计模式


在当今的企业级项目开发中,MVC 设计模式是主要的设计模式,是行业所遵循的。Java EE 最初的设计阶段,MVC 的结构如下:


  • JSP + Servlet + Session Bean + Entity Bean


实际上可将以上结构分为两部分


  • 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/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttp://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;@Repositorypublic 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());	}}
复制代码


用户头像

andy

关注

还未添加个人签名 2019-11-21 加入

还未添加个人简介

评论

发布
暂无评论
SpringMVC 基础_andy_InfoQ写作社区