您的位置:首页 > 编程语言 > Java开发

Spring MVC(1):文件配置 & 使用示例

2018-01-09 14:39 295 查看

Spring MVC 体系概述

 Spring MVC 是基于 Model2 实现的 MVC 框架,Model 2是经典 MVC 模型在 Web 应用中的变体,这个改变是源于 HTTP 协议的无状态性;
Spring MVC 模型的整体架构如下:



其中 DispatcherServlet 处于核心地位,负责协调和组织不同的组件以完成请求处理并返回响应结果;DispatcherServlet 就是 Spring MVC 的前端 Servlet , 负责接受所有请求,并将具体的工作委托给其他组件进行处理,这一点如同其他大部分的 MVC 框架;

以下是 Spring MVC 处理请求的整体过程

1)客户端发送一个 HTTP 请求,Web 服务器接受这个请求,如果请求路径符合 DispatcherServlet 的请求路径(web.xml 中定义),则 Web 服务器将该请求交给 DispatcherServlet 进行处理;

2)DispatcherServlet 接受请求后,根据请求的消息和 HandlerMapping 的配置查找处理请求的处理器 Handler(即可以把 HandlerMapping 看成路由控制器,Handler 看成目标主机);

3)当 DispatherServlet 获取相应的 Handler 后,通过 HandlerAdapter 对 Handler 进行封装,再以统一的适配器接口调用 Handler(这是由于 Spring MVC 并没有定义 Handler 接口,任何一个 Obejct 都可以作为 Handler);

4)Handler 完成业务逻辑处理后,返回一个 ModelAndView (包含了视图逻辑名,模型数据信息)给 DispatcherServlet;

5)DispatcherServlet 借助 ViewResolver 解析 ModelAndView 中的逻辑视图名到真实视图对象;

6)当获取真实视图对象 View 后,DispatcherServlet 使用该 View 对象对 ModelAndView 中的模型数据进行解析;

7)客户端获取响应结果(可能为一个HTML,XML,JSON 或 图片、PDF 等);


配置 DispatcherServlet 

在使用 Spring MVC 的第一步是在 web.xml 中对 DispatcherServlet 进行配置,一个示例的配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app .....>
    <!--加载 Spring WebApplicationContext: Service 层和 Dao 层的配置文件加载到 Spring 容器 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
    <!--启动 Spring 容器监听器-->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!--以下部分为 DispatcherServlet 的配置-->
    <!--声明 DispatcherServlet-->
    <servlet>
        <servlet-name>assad</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <!--配置 DispatcherServlet 的匹配 URL 模式-->
    <servlet-mapping>
        <servlet-name>assad</servlet-name>
        <url-pattern>/</url-pattern>     <!--匹配任何url请求,像 *.html 匹配 html 页面请求-->
    </servlet-mapping>
    
</web-app>


DispatcherServlet 遵循约定大于配置的原则,在大多情况下,用户无需进行额外的配置,只需配置 DispatcherServlet 的
<servlet> 和 <servlet-mapping>
,其中一个 <servlet-mapping> 可以配置多个<url-pattern>;
其他的 DisptahcerServlet 默认配置参数,可以通过 <servlet> 的 <init-param> 指定 ,如下:

namespace

DispatcherServlet 的命名空间,默认为 <servlet-name>-servlet(即:WEB-INF/<servlet-name>-servlet.xml ),

显示指定该属性后,可以将该配置文件的路径更改为 WEB-INF/<namespace>.xml ; 

contextConifgLocation

如果 DispatcherServlet 对应的上下文配置文件有多个,可以用该属性指定这些配置文件的路径,如:

<contextConifgLocation>classpath:smaple1.xml, classpath:sample2.xml</contextConifgLocation>

publishContext

指定 DispatcherServlet 是否将 WevApplicationContext 分布到 ServletContext 的属性列表中(通过 DispatcherServlet#getServletContextAttributeName() 方法可以从ServletContext 中获取 WebApplicationContex 的实例),

默认值为 true;

publishEvents

指定 DispatcherServlet 处理完一个请求后,是否需要向容器发布一个 ServletRequesthandledEvent 事件,

默认值为 true;如果容器中没有任何事件监听器,可以将改值设置为 false 以提高性能;

一个简单的示例

Spring MVC 应用开发一般包括以下几个步骤:
1)配置 web.xml ,指定业务层对应的 Spring 配置文件,定义 DispatcherServlet;
2)编写处理请求的处理器 Handler;
3)编写视图对象;
4)配置 Spring MVC 的配置文件,使控制器、视图解析器等生效;

以下是一个简单的 Spring MVC 示例,演示一个登陆业务流程;
完整示例代码地址https://gitee.com/assad/springframework-test-mvc-login-demo

示例模块:
site/assad/domain/User,LoginLog(领域对象)
site/assad/dao/UserDao,LoginLogDao(DAO对象)
site/assad/service/UserService(Service对象)
site/assad/web/LoginController(Web层控制器对象)
site/assad/applicationContext.xml(Spring 容器配置文件:针对 Dao,Service 层的配置)
webapps/WEB-INF/web.xml
webapps/WEB-INF/assad-servlet.xml(Spring-mvc
配置文件:针对 Web 层的配置)

webapps/WEB-INF/login/login.jsp,login_success.jsp(View
层  jsp视图文件)

1)编写 web.xml ,配置 Dispatcher


<?xml version="1.0" encoding="UTF-8"?>
<web-app ...>
<!--加载 Spring WebApplicationContext: Service 层和 Dao 层的配置文件加载到 Spring 容器 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!--启动 Spring 容器监听器-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!--声明 DispatcherServlet-->
<servlet>
<servlet-name>assad</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!--配置 DispatcherServlet 的匹配 URL 模式-->
<servlet-mapping>
<servlet-name>assad</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

<!--配置请求编码过滤器,解决HttpRequest传输时中文乱码的问题-->
<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>
<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>

</web-app>

以上配置文件,为了解决 Request 中文乱码问题,配置了一个编码过滤器;

2)编写 Web 层的控制器(处理器Handler)
Spring MVC 通过 @Controller ,或 @RestController 可以标注一个控制器对象,主要负责响应 URL 请求,对其进行逻辑处理后,转发到视图对象(逻辑视图);
以下控制器,分别将 “/login” “/loginCheck” 的url请求进行处理后,分别映射到 “login/login”,“login/login_success” 逻辑视图;
package site.assad.web;

@RestController  //标记为一个 Spring MVC 的Controller
public class LoginController {

@Autowired
private UserService userService;

//响应 index.html 请求,并将其转发到 login/login 逻辑视图
@RequestMapping(value="/login")
public String loginPage(){
return "login/login";
}

//响应 loginCheck.html 请求
@RequestMapping(value="/loginCheck",method = RequestMethod.POST)
public ModelAndView loginCheck(HttpServletRequest request, LoginCommand loginCommand ) throws UnsupportedEncodingException {
//验证登陆用户密码
boolean isValidUser = userService.checkUser(loginCommand.getUserName(),loginCommand.getPassword());
//验证结果处理逻辑
if(!isValidUser){
//验证失败,返回 login/login 物理视图,并携带错误信息
return new ModelAndView("login/login","error", new String("用户名或密码错误".getBytes(),"UTF-8"));
}else{
User user = userService.findUserByName(loginCommand.getUserName());
user.setLastIp(request.getLocalAddr());
user.setLastVisit(new Date());
userService.loginSuccess(user);                         //执行验证成功的业务操作
request.getSession().setAttribute("user",user);  //设置 session
//验证成功,转发到 login/login_success 逻辑视图
return new ModelAndView("login/login_success");
}
}
}



3)编写 View 视图文件

在本例子中用 JSP 编写视图文件,一般项目的视图文件会放置到 webapps/WEB-INF/views 路径中(当然也可以根据需求自定义路径);
例子中包含2个JSP文件,“login/login.jsp” 为登陆页面(同时负责登陆失败的信息显示),“login/login_success.jsp” 为登陆成功页面;
login/login.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Login Page</title>
</head>
<body>
<p>
<c:if test="${!empty error}">
<c:out value="${error}" />
</c:if>
</p>
<form action="<c:url value="/loginCheck" />" method="post">
<label>用户名</label><input type="text" name="userName" /><br />
<label>密码</label><input type="password" name="password"/><br />
<input type="submit" value="登陆" />
<input type="reset" value="重置信息" />
</form>
</body>
</html>
login/login_success.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Login Success Page</title>
</head>
<body>
<h1>登陆成功!${user.name}, 您当前的积分为 ${user.credits} </h1>
</body>
</html>



4)编写 Spring-mvc 配置文件

spring-mvc 配置文件默认命名为 <DispatcherServlet-name>-servlet.xml,其中<DispatcherServlet-name>为
web.xml 中DispatcherServlet 节点的名称,如示例中为 “assad-servlet.xml” ;
一般该文件默认位于
web.xml 同目录下;
assad-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
<!--自动注入 site.assad.web 包的 bean-->
<context:component-scan base-package="site.assad.web" />

<!--配置视图解析器,映射逻辑视图名的解析-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:viewClass="org.springframework.web.servlet.view.JstlView"
p:prefix="/WEB-INF/views/"
p:suffix=".jsp" />
</beans>

示例代码配置了一个 JSP 视图解析器,配置逻辑视图映射到物理视图的规则为:物理视图文件路径 =“ /WEB-INF/views/ ” + 逻辑视图名 + “.jsp ” ;
如:“login/login” 逻辑视图名映射为 “/WEB-INF/views/login/login.jsp
” 的物理视图文件;

附:示例代码使用 gradle 作依赖管理,通过 build.gradle 配置的 gretty 插件启动内嵌 tomcat,通过 url ”http://127.0.0.1:8080/login “
即可测试登陆流程;
构建文件为:
build.gradle
group 'site.assad'
version '1.0'

apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'org.akhikhl.gretty'
sourceCompatibility = 1.8

//导入 gretty 调试插件
buildscript{
repositories{
jcenter()
}
dependencies{
classpath 'org.akhikhl.gretty:gretty:1.2.4'
}
}

repositories {
mavenCentral()
}

ext{
servlet_api_version = '3.0-alpha-1'
jstl_version = '1.2'
jsp_api_version = '2.0'
spring_version = '4.3.11.RELEASE'
log4j_core_version = '2.9.0'
log4j_api_version = '2.9.0'
junit_version = '4.12'
commons_dbcp_version = '1.4'
mysql_connector_java_version = '5.1.44'
hibernate_version = '5.2.12.Final'
}

dependencies {
//log4j 依赖
testCompile "org.apache.logging.log4j:log4j-core:${log4j_core_version}"
testCompile "org.apache.logging.log4j:log4j-api:${log4j_api_version}"
compile "org.apache.logging.log4j:log4j-core:${log4j_core_version}"
compile "org.apache.logging.log4j:log4j-api:${log4j_api_version}"

//servlet 依赖
compile "javax.servlet:servlet-api:${servlet_api_version}"
compile "javax.servlet:jstl:${jstl_version}"
compile "javax.servlet.jsp:jsp-api:${jsp_api_version}"

//spring core 依赖
compile "org.springframework:spring-beans:${spring_version}"
compile "org.springframework:spring-core:${spring_version}"
compile "org.springframework:spring-context:${spring_version}"
compile "org.springframework:spring-context-support:${spring_version}"

//spring dao 依赖
compile "org.springframework:spring-jdbc:${spring_version}"
compile "org.springframework:spring-tx:${spring_version}"
//数据源和数据库驱动:使用 Mysql,DBCP数据源
compile "commons-dbcp:commons-dbcp:${commons_dbcp_version}"
compile "mysql:mysql-connector-java:${mysql_connector_java_version}"

//spring test 依赖,使用 Junit
compile "org.springframework:spring-test:${spring_version}"
testCompile "junit:junit:${junit_version}"

//spring mvc 框架
compile "org.springframework:spring-webmvc:${spring_version}"
}
//设置 gretty 参数
gretty {
port = 8080
servletContainer = 'tomcat8'
contextPath = "/"
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐