上次我已经带领大家建立起了自己的第一个是springMVC工程,并成功的运行起来。然而作为开发者的我们,对这样一个工程是必须知道它是什么,怎么样。这次我就来和大家掰扯掰扯这个spring工程里面都有什么吧。
这是我们上次建立的spring工程目录结构,大体以中间三个library作为分界线,上面的三个src目录就是后台的主程序,下面的src目录则是前端页面相关的内容,pom.xml我们已经很熟悉了是MAVEN的配置文件,所以它并不属于spring工程结构中。相比较普通的javaWeb项目,有一个很明显的文件是spring独有的,就是springContext.xml(不一定非得起这个名字,但一定要有这个xml文件),它是做什么的呢?先放一放,我们从web.xml开始看。
<web-app version="3.0" 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_3_0.xsd">
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
contextConfigLocation:这是指明部署applicationContext的xml文件,下面的classpath就是spring.xml配置文件的全名,系统会根据名称自己寻找。
dispather:是前置控制器,配置在web.xml文件中的。拦截匹配的请求,Servlet拦截匹配规则要自已定义,把拦截下来的请求,依据某某规则分发到目标Controller(我们写的Action)来处理。
servlet-mapping: 表示拦截的模式,这里是“/”,表示对于所有的请求的拦截,包括静态资源如html, js, jpg等。这时候对于静态资源的访问就会报404的错误。关于如何解决后面会介绍。
listener: 顾名思义,监听器,具体的业务内容可以自己查看spring的相关介绍或者源码。
其他关键字都是.xml的通用配置,具体意思可以自己查阅。
接下来就是springContext.xml了
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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">
<!-- 搜索spring控件 -->
<context:component-scan base-package="com.test"></context:component-scan>
<!-- 视图页面配置 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/views/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
</beans>
context : 指明页面对应controller的所在位置,"base-package"指明了要在这个包中寻找,上面我的目录中已经有一个com.text的package了,而helloworldController.java就在这个包中。
property : 有两个,一个把name定义为前缀,一个定义为后缀,组合起来就是在/WEB-INF/views/的目录下,寻找所有.jsp格式的文件,这样就定位到了我的hellospring.jsp文件
还记得上一节我们运行web后的样子吗?
点击中间的链接后就跳到了我自己的hellospring界面:
这个跳转过程是怎么实现的呢?我们先来看一下index.jsp代码:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Spring 4 MVC - HelloWorld Index Page</title>
</head>
<body>
<center>
<h2>Hello World</h2>
<h3>
<a href="hello?name=Jarvan">点击跳转</a>
</h3>
</center>
</body>
</html>
很简单,就是写了一行字,然后有一个链接“hello?name=Jarvan”发送到了后台,我们再来看一下controller的代码:
package com.test;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class HelloSpringController {
String message = "Welcome to Spring MVC!";
@RequestMapping("/hello")
public ModelAndView showMessage(@RequestParam(value = "name", required = false, defaultValue = "Spring") String name) {
ModelAndView mv = new ModelAndView("hellospring");//指定视图
mv.addObject("message", message);
mv.addObject("name", name);
return mv;
}
}
注意到了RequestMapping没?这个注释里面的内容正是hello,也就是说,href发送后台的链接是通过requestmapping来进行定位的,通过这个注解,找到showMessage这个方法,来获取下一步的操作。当然,你也可以分级写这个请求,假如前端的链接是这样的:
<a href="springmvc/hello?name=Jarvan">点击跳转</a>
我希望在后台把不同的链接进行分类管理,前面的springmvc就是我的一级目录,怎么办?很简单,在controller外再加一个注释:
@RequestMapping("/springmvc")
@Controller
public class HelloSpringController {
String message = "Welcome to Spring MVC!";
@RequestMapping("/hello")
public ModelAndView showMessage(@RequestParam(value = "name", required = false, defaultValue = "Spring") String name) {
ModelAndView mv = new ModelAndView("hellospring");//指定视图
mv.addObject("message", message);
mv.addObject("name", name);
return mv;
}
}
外侧定位第一级,里面的具体内容定位后面的。
再补充一点,RequestMapping可以实现模糊匹配路径,比如:
?:匹配一个字符
*:匹配任意字符
**:匹配多层路径
/springmvc/**/lastTest 就可以匹配/springmvc/firstTest/secondTest/lastTest这样的路径
除此之外大家一定发现了还有一个注释RequestParam,它是用来获取参数的,前台向后台传参时使用。注意在该方法中,我们通过@RequestParam这个注解声明了一个变量,用来获取请求中query所带的参数值,required代表这个参数是否是必须的,defaultValue代表了若前台不给这个值的话,赋给它一个默认值。
使用ModelAndView类用来存储处理完后的结果数据,以及显示该数据的视图。从名字上看ModelAndView中的Model代表模型,View代表视图,这个名字就很好地解释了该类的作用。业务处理器调用模型层处理完用户请求后,把结果数据存储在该类的model属性中,把要返回的视图信息存储在该类的view属性中,然后让该ModelAndView返回该Spring MVC框架。框架通过调用配置文件中定义的视图解析器,对该对象进行解析,最后把结果数据显示在指定的页面上。
hellospring.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Spring 4 MVC -HelloWorld</title>
</head>
<body>
<center>
<h2>Hello World</h2>
<h2>
${message} ${name} </h2>
</center>
</body>
</html>