在项目中搭建SpringMVC框架
1、步骤
第一步:构建Web项目
第二步:导入所需jar包
第三步:配置前端控制器DispatcherServlet
第四步:编写Controller控制器(也称为Handler处理器)
第五步:配置处理器映射器(可省去,有默认配置)
第六步:配置处理器适配器(可省去,有默认配置)
第七步:配置视图解析器(可省去,有默认配置,但是前缀和后缀都为"")
第八步:配置控制器/处理器
1)构建Web项目
在自己Eclipse中创建一个动态web项目(DynamicWebProject),注意JDK版本和项目版本的选择
2)导入所需的jar包
在lib目录下放入如下jar包,这是初始jar包,根据后续需求会陆续加入jar包
commons-logging-1.2.jar
spring-beans-4.3.7.RELEASE.jar
spring-context-4.3.7.RELEASE.jar
spring-core-4.3.7.RELEASE.jar
spring-expression-4.3.7.RELEASE.jar
spring-web-4.3.7.RELEASE.jar
spring-webmvc-4.3.7.RELEASE.jar
3)配置前端控制器DispatcherServlet以及需要读取的xml配置文件
前端控制器(DispatcherServlet)主要负责整体的控制流程的调度部分:
1、负责将请求委托给控制器进行处理;
2、根据控制器返回的逻辑视图名选择具体的视图进行渲染(并把模型数据传入)。
因此MVC中完整的C(包含控制逻辑+功能处理)由(DispatcherServlet + Controller)组成。
SpringMVC的前端控制器就是一个Servlet对象,继承自HttpServlet,所以需要在web.xml文件中配置。
例如:web.xml中配置
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
SpringMVC是Spring提供的一个模块,Spring所有的模块都是基于Spring IOC功能的。
所有SpringMVC的DispatcherServlet对象再初始化前也会去实例化Spring的容器对象(ApplicationContext),那么就要读取Spring配置文件;
默认读取的配置文件要方法web项目的WEB-INF目录下,文件名为上面配置的[servlet-name]-servlet.xml;比如上面配置对应的Spring配置文件名为:SpringMVC-servlet.xml;默认读取的配置文件路径和名字不能错否则报错
当然也可以自己配置Spring配置文件的位置和名字,但是要在web.xml中指定,在和之间使用下面代码:
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-web-mvc.xml</param-value>
</init-param>
例如:
<!-- 配置前端控制器 -->
<!-- 需要指定配置文件。 -->
<!-- 但如果没有指定,会读取一个默认的固定位置、固定名称的xml文件
/WEB-INF/[servlet-name]-servlet.xml -->
<!-- <servlet-name>SpringMVC</servlet-name> -->
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 这里不配置就默认读取/WEB-INF/SpringMVC-servlet.xml文件 -->
<!-- 这里配置了就不会读取SpringMVC-servlet,而是直接读取(classpath)src下的spring-web-mvc.xml -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-web-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<!-- 前端控制器拦截-->
<!--
1./* :拦截所有资源请求(包括.jsp、.js、.jpg、.css等),不建议使用
2.*.action *.do :拦截所有对action或do后缀资源的请求
3. / :拦截所有非.jsp后缀的所有资源请求,建议使用
-->
<url-pattern>/</url-pattern>
</servlet-mapping>
注意:
配置文件在WEB-INF下:
/WEB-INF/spring-web-mvc.xml
配置文件在classpath下,(即src下,web打包后src下的就是classpath下的):
classpath:spring-web-mvc.xml
4)编写Controller控制器(headler)
Controller控制器,是MVC中的部分C,因为此处的控制器主要负责功能处理部分:
1、收集、验证请求参数并封装到对象上;
2、将对象交给业务层(service),由业务对象处理并返回模型数据;
3、返回ModelAndView(Model部分是业务层返回的模型数据,视图部分为逻辑视图名)。
Controller接口中只有一个需要实现的方法就是handleRequest方法,方法中接收两个参数,分别对应Servlet对象中的request,response对象。可以从request中获取客户端提交过来的请求参数。
返回值ModelAndView,既包含要返回给客户端浏览器的逻辑视图又包含要对视图进行渲染的数据模型。
例如:
public class HelloWorldController implements Controller{
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
//ModelAndView对象中包括了要返回的逻辑视图,以及数据模型
ModelAndView mv = new ModelAndView();
//设置逻辑视图名称
mv.setViewName("hello");
//设置数据模型
mv.addObject("name", "tom");
return mv;
}
}
5)配置映射器(可省去,有默认配置)
在自己定义的sec下面spring-web-mvc.xml或者默认配置的/WEB-INF/SpringMVC-servlet.xml文件中配置
注意:如果xml文件不能自动提示,那么可以在Eclipse中把schame配置过来即可,schame文件也在下载的spring的压缩包中
Spring容器需要根据映射器来将用户提交的请求url和后台Controller/Handler进行绑定,所以需要配置映射器。
例如:
<!-- 配置处理器映射器(可省略,有默认值) -->
<!-- 将客户端发送的url请求和对应的Controller进行映射 -->
<bean
class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"
/>
BeanNameUrlHandlerMapping:表示将请求的URL和Bean名字映射,如URL为 “/hello”,则Spring配置文件必须有一个名字为"/hello"的Bean.
注意:这里/代表的含义是url中项目名后面的/
6)配置适配器(可省去,有默认配置)
在自己定义的sec下面spring-web-mvc.xml或者默认配置的/WEB-INF/SpringMVC-servlet.xml文件中配置
例如:
<!-- 配置处理器适配器(可省略,有默认值) -->
<!-- 将来指定调用Controller中的哪个方法 -->
<bean
class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"
/>
SimpleControllerHandlerAdapter:表示所有实现了org.springframework.web.servlet.mvc.Controller接口的Bean可以作为SpringMVC中的处理器。如果需要其他类型的处理器可以通过实现HadlerAdapter来解决。
7)配置视图解析器(可省去,有默认配置,但是前缀和后缀都为""即无前缀和后缀)所有最好自己配置
在自己定义的sec下面spring-web-mvc.xml或者默认配置的/WEB-INF/SpringMVC-servlet.xml文件中配置
当处理器执行完成后,返回给spring容器一个ModelAndView对象,这个对象需要能够被解析成与之相对应的视图,并且使用返回的Model数据对视图进行渲染。
例如:
<!-- 视图解析器 ,可省略,但默认值无前后缀,所有最好不省略-->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
***加粗样式*** value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
注意:如果配置设置为如上操作,即加了前缀后缀,那么在自定义的Handler中返回的逻辑视图的名字不能有后缀.jsp,并且具体页面一定放在/WEB-INF目录下。
8)配置处理器
把编写好的handler/controller在spring中进配置,让其接受Spring IoC容器管理
<bean name="/hello" class="com.briup.web.controller.HelloWorldController"/>
com.briup.web.controller包下编写了HelloWorldController文件
package com.briup.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
//处理器,实现Controller接口
public class HelloController implements Controller{
@Override
public ModelAndView handleRequest(HttpServletRequest reauest, HttpServletResponse response) throws Exception {
//以前咋Servlet能做的事情,在这里也可以进行
//只是将来需要处理数据通过ModelAndView对象返回
ModelAndView mv=new ModelAndView();
//存放数据
mv.addObject("name", "tom");
//设置逻辑视图名
mv.setViewName("hello");
return mv;
//注:可以使用以前的方法使用response将数据用流的方式写到前端页面,return null;不用进行解析
}
}
在WEB-INF目录下面建一个文件夹jsp,专门放jsp文件,这样客户端无法直接访问jsp,更安全,在下面建一个hello.jsp用于显示
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
/* http://127.0.0.1:10086/JD1911-SpringMVC/
request.getContextPath()包含/JD1911-SpringMVC的斜杠 */
//getScheme()协议名称;getServerName()服务器名或ip;getServerPort()端口号;getContextPath()项目名(有/)
String basepath=request.getScheme()+"://"
+request.getServerName()+":"
+request.getServerPort()
+request.getContextPath()+"/";
%>
<!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>hello</title>
<!-- 配置页面跳转的路径 -->
<base href="<%=basepath%>">
<!-- 将css样式引入 -->
<link href="static/css/div.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<h1>hello.jsp页面</h1>
<h2>获取存放的name:</h2>
<h3>${name}</h3>
</body>
</html>
文件大致结构:
2、额外功能
静态资源的访问,如jpg,js,css
如果DispatcherServlet拦截".do"这样的有后缀的URL,就不存在访问不到静态资源的问题。
如果DispatcherServlet拦截"/",为了实现REST风格,拦截了所有的请求,那么同时对.js,*.jpg等静态文件的访问也就被拦截了。
例如:
<link href="static/css/hello.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="static/js/hello.js"></script>
<img alt="none" src="static/images/logo.png">
解决方式一:利用Tomcat的defaultServlet来处理静态文件
在web.xml文件中配置
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.jpg</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>*.css</url-pattern>
</servlet-mapping>
或者:
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.css</url-pattern>
<url-pattern>*.js</url-pattern>
<url-pattern>*.png</url-pattern>
</servlet-mapping>
特点:1.要配置多个,每种文件配置一个。
2.要写在DispatcherServlet的前面(和tomcat版本有关),让defaultServlet先拦截请求, 这样请求就不会进入Spring了
3. 高性能。
解决方式二: 使用mvc:resources标签,例如:
在spring配置文件中spring-web-mvc.xml配置,上面自定义的,默认是[servlet-name]-servlet.xml文件
<mvc:resources mapping="/images/**" location="/images/"/>
<mvc:resources mapping="/js/**" location="/js/"/>
<mvc:resources mapping="/css/**" location="/css/"/>
mapping: 映射
两个*,表示映射指定路径下所有的URL,包括子路径
location:本地资源路径
这样如果有访问/images或者/js或者/css路径下面的资源的时候,spring就不会拦截了
解决方式三: 使用mvc:default-servlet-handler/标签
***在spring配置文件中spring-web-mvc.xml配置,上面自定义的,默认是[servlet-name]-servlet.xml文件***在spring配置文件中加入此标签配置即可
<mvc:default-servlet-handler/>
3、.spring提供的编码过滤器
在web.xml中配置
查看这个过滤器类源码便可知这里所传的俩个参数的作用
<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>
<!--true表示request和response都设置编码为UTF-8-->
<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>