方式一:配置方式
步骤:
1,MVC框架要做的事情:
a) 将url映射到java或java类的方法;
b)封装用户提交的数据;
c) 处理请求——调用相关的业务处理—-封装相应的数据;
d)将响应的数据进行渲染,jsp,html等;
2, 相关准备工作:
使用约定化配置,能够进行junit测试,异常处理,本地化,国际化,数据验证类型转换,拦截器。
3, 了解结构:
4,案例:
案例框架:
(1)新建工程:springmvc
(2)导入相应包:
(3)配置web.xml文件——-配置分发器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| 1<?xml version="1.0" encoding="UTF-8"?>
2<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
5 http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
6
7 <!-- 配置springmvc核心分发器,对所有的url后缀为action的进行过滤 -->
8 <servlet>
9 <servlet-name>action</servlet-name>
10 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
11 <load-on-startup>1</load-on-startup>
12 <!-- 改变springmvc配置文件的位置和名称 -->
13 <init-param>
14 <param-name>contextConfigLocation</param-name>
15 <param-value>classpath:springmvc-servlet.xml</param-value>
16 </init-param>
17 </servlet>
18 <servlet-mapping>
19 <servlet-name>action</servlet-name>
20 <url-pattern>*.action</url-pattern>
21 </servlet-mapping>
22
23 <welcome-file-list>
24 <welcome-file>index.jsp</welcome-file>
25 </welcome-file-list>
26</web-app>
27
28注意:<p>DispatcherServlet类将加载springmvc的配置文件,会产生一个spring的子容器,该子容器存放实例</p>
29
30 |
(4)添加springmvc的配置文件,默认在web-inf下添加[DispatcherServlet]—-name-servlet.xml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| 1<?xml version="1.0" encoding="UTF-8"?>
2<beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://www.springframework.org/schema/beans
5 http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
6
7
8 <!-- 声明一个Controller -->
9 <bean name="/home.action" class="cn.itcast.controller.HomeController"/>
10
11 <!-- 配置视图jsp解析器 内部资源视图解析器 前缀+逻辑名+后缀 /WEB-INF/pages/ index .jsp -->
12 <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
13 <property name="prefix" value="/WEB-INF/pages/"/>
14 <property name="suffix" value=".jsp"/>
15 </bean>
16</beans>
17 |
1 2
| 1 (5)编写HelloController类:
2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| 1package cn.itcast.controller;
2
3import javax.servlet.http.HttpServletRequest;
4import javax.servlet.http.HttpServletResponse;
5import org.springframework.web.servlet.ModelAndView;
6import org.springframework.web.servlet.mvc.AbstractController;
7
8
9/**
10 * @Description:
11 * @Author: 潘光友
12 * @Company: http://java.itcast.cn
13 * @CreateDate: 2016-5-23
14 */
15
16public class HomeController extends AbstractController{
17 protected ModelAndView handleRequestInternal(HttpServletRequest request,
18 HttpServletResponse response) throws Exception {
19
20 System.out.println(request.getRequestURI());
21 return new ModelAndView("index"); //逻辑名
22 }
23
24}
25
26 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| 1<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
2<%
3String path = request.getContextPath();
4String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
5%>
6
7<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
8<html>
9 <head>
10 <base href="<%=basePath%>">
11
12 <title>My JSP 'index.jsp' starting page</title>
13 <meta http-equiv="pragma" content="no-cache">
14 <meta http-equiv="cache-control" content="no-cache">
15 <meta http-equiv="expires" content="0">
16 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
17 <meta http-equiv="description" content="This is my page">
18 <!--
19 <link rel="stylesheet" type="text/css" href="styles.css">
20 -->
21 </head>
22
23 <body>
24 This is my Spring MVC JSP page2. <br>
25 </body>
26</html>
27
28 |
方式二:注解方式
(1)新建项目springmvcnew;
(2)添加包:
(3)配置web.xml文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| 1<?xml version="1.0" encoding="UTF-8"?>
2<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
5 http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
6
7 <!-- 配置springmvc核心分发器,对所有的url后缀为action的进行过滤 -->
8 <servlet>
9 <servlet-name>action</servlet-name>
10 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
11 <!-- 改变springmvc配置文件的位置和名称 -->
12 <init-param>
13 <param-name>contextConfigLocation</param-name>
14 <param-value>classpath:springmvcnew-servlet.xml</param-value>
15 </init-param>
16 </servlet>
17 <servlet-mapping>
18 <servlet-name>action</servlet-name>
19 <url-pattern>*.action</url-pattern>
20 </servlet-mapping>
21
22 <welcome-file-list>
23 <welcome-file>index.jsp</welcome-file>
24 </welcome-file-list>
25</web-app>
26
27 |
1 2
| 1 (4)配置springmvcnew-servlet.xml文件:
2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| 1<?xml version="1.0" encoding="UTF-8"?>
2<beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xmlns:mvc="http://www.springframework.org/schema/mvc"
5 xmlns:context="http://www.springframework.org/schema/context"
6 xsi:schemaLocation="http://www.springframework.org/schema/mvc
7 http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
8 http://www.springframework.org/schema/beans
9 http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
10 http://www.springframework.org/schema/context
11 http://www.springframework.org/schema/context/spring-context-3.2.xsd">
12
13 <!-- 注解开发方式 -->
14 <mvc:annotation-driven/>
15
16 <!-- 包自动扫描 -->
17 <context:component-scan base-package="cn.itcast.controller"/>
18
19 <!-- 配置视图jsp解析器 内部资源视图解析器 前缀+逻辑名+后缀 /WEB-INF/pages/ index .jsp -->
20 <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
21 <property name="prefix" value="/WEB-INF/pages/"/>
22 <property name="suffix" value=".jsp"/>
23 </bean>
24
25
26</beans>
27 |
1 2
| 1 (5)编写HomeController类:
2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| 1package cn.itcast.controller;
2
3import javax.servlet.http.HttpServletRequest;
4import org.springframework.stereotype.Controller;
5import org.springframework.web.bind.annotation.RequestMapping;
6
7@Controller
8public class HomeController {
9 //http://localhost:8080/springmvcnew/home.action
10 @RequestMapping("/home2")
11 public String gohome(HttpServletRequest request){
12 //System.out.println(request.getRequestURL());
13 return "index"; //返回逻辑名
14 }
15}
16
17 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| 1<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
2<%
3String path = request.getContextPath();
4String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
5%>
6
7<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
8<html>
9 <head>
10 <base href="<%=basePath%>">
11
12 <title>My JSP 'index.jsp' starting page</title>
13 <meta http-equiv="pragma" content="no-cache">
14 <meta http-equiv="cache-control" content="no-cache">
15 <meta http-equiv="expires" content="0">
16 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
17 <meta http-equiv="description" content="This is my page">
18 <!--
19 <link rel="stylesheet" type="text/css" href="styles.css">
20 -->
21 </head>
22
23 <body>
24 This is my JSP page SpringMVC new. <br>
25
26 </body>
27</html>
28
29 |
补充:数据处理:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| 1package cn.itcast.controller;
2
3<span style="font-size:18px;">import org.springframework.stereotype.Controller;
4import org.springframework.web.bind.annotation.RequestMapping;
5import org.springframework.web.bind.annotation.RequestParam;
6import cn.itcast.domian.User;
7
8@Controller
9public class data_deal {
10 @RequestMapping("/data")
11 /*@RequestParam("data_name")----data_name是提交的域的名称
12 例如传值:http://localhost:8080/springmvcnew/data.action?data_name=panzhanggui
13 */
14 public String data(@RequestParam("data_name") String name){
15 System.out.println(name);
16 return "data";
17 }
18 @RequestMapping("/user")
19 public String user(User user){
20 System.out.println(user);
21 return "data";
22 }
23}
24</span>
25 |
传值路径:
1 2
| 1<a target=_blank href="http://localhost:8080/springmvcnew/data.action?data_name=panzhanggui">http://localhost:8080/springmvcnew/data.action?data_name=panzhanggui</a>
2 |
1 2
| 1<span style="font-family:Arial;BACKGROUND-COLOR: #ffffff"></span>
2 |
1 2
| 1<span style="font-family:Arial;BACKGROUND-COLOR: #ffffff"></span>
2 |
跳转结果的方式:
1,设置ModelAndCiew对象。根据View的名称,和视图解析器跳转到指定的页面。
页面:视图解析器的前缀+View name+视图解析器的后缀。
1 2 3 4 5 6 7 8 9 10
| 1<span style="font-size:18px;">@RequestMapping("/hello2")
2 public ModelAndView hello(HttpServletRequest requst,HttpServletResponse response){
3 ModelAndView mv=new ModelAndView();
4 //封装要显示视图的数据
5 mv.addObject("msg", "hello annotation");
6 //视图名
7 mv.setViewName("index");
8 return mv;
9 }</span>
10 |
2,通过servletAPI对象来实现(不需要视图解析器)。
1 2 3 4 5
| 1<span style="font-size:18px;"> @RequestMapping("/hello3")
2 public void hello3(HttpServletRequest requst,HttpServletResponse response) throws Exception{
3 response.getWriter().println("hello spring mvc use httpserrtvlet api");
4 }</span>
5 |
springmvc实现文件上传
1,通过common-fileuoload实现。导入相关jar包。
1 2 3
| 1commons-fileupload-1.2.2.jar
2commons-io-2.0.1.jar
3 |
1 2 3 4 5 6 7
| 1<!-- 声明CommonsMultipartResolver解析器 -->
2 <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
3 <!-- 设置上传文件的最大尺寸为1MB -->
4 <property name="maxUploadSize">
5 <value>1048576</value>
6 </property>
7 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| 1import java.io.File;
2import java.io.IOException;
3import javax.servlet.http.HttpServletRequest;
4import org.springframework.stereotype.Controller;
5import org.springframework.ui.ModelMap;
6import org.springframework.web.bind.annotation.RequestMapping;
7import org.springframework.web.bind.annotation.RequestParam;
8import org.springframework.web.multipart.MultipartFile;
9
10@Controller
11public class FileUpload {
12 @RequestMapping(value="/upload")
13 public String upload(@RequestParam(value="file",required=false)//
14 MultipartFile file,HttpServletRequest request,ModelMap model){
15 //服务器端upload文件夹物理路径
16 String path=request.getSession().getServletContext().getRealPath("upload");
17 //获取文件名
18 String fileName=file.getOriginalFilename();
19 //实例化一个File对象,表示目标文件(含物理路径)
20 File targetFile=new File(path,fileName);
21 if(!targetFile.exists()){
22 targetFile.mkdirs();
23 }
24
25 //将上传文件写到服务器上指定的文件
26 try {
27 file.transferTo(targetFile);
28 } catch (Exception e) {
29 // TODO Auto-generated catch block
30 e.printStackTrace();
31 }
32 model.put("fileUrl", request.getContextPath()+"/upload"+fileName);
33 return "result";
34
35 }
36}
37
38 |
1.DispatcherServlet
SpringMVC具有统一的入口DispatcherServlet,所有的请求都通过DispatcherServlet。
DispatcherServlet是前置控制器,配置在web.xml文件中的。拦截匹配的请求,Servlet拦截匹配规则要自已定义,把拦截下来的请求,依据某某规则分发到目标Controller来处理。 所以我们现在web.xml中加入以下配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| 1<!-- 配置springmvc核心分发器,对所有的url后缀为action的进行过滤 -->
2 <servlet>
3 <servlet-name>action</servlet-name>
4 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
5
6 <!-- 改变springmvc配置文件的位置和名称 -->
7 <init-param>
8 <param-name>contextConfigLocation</param-name>
9 <param-value>classpath:springmvcnew-servlet.xml</param-value>
10 </init-param>
11 <!-- 改变springmvc配置文件的位置和名称 结束 -->
12 </servlet>
13
14 <servlet-mapping>
15 <servlet-name>action</servlet-name>
16 <url-pattern>*.action</url-pattern>
17 </servlet-mapping>
18 |
2.静态资源不拦截
如果只配置拦截类似于*.do格式的url,则对静态资源的访问是没有问题的,但是如果配置拦截了所有的请求(如我们上面配置的“/”),就会造成js文件、css文件、图片文件等静态资源无法访问。
一般实现拦截器主要是为了权限管理,主要是拦截一些url请求,所以不对静态资源进行拦截。要过滤掉静态资源一般有两种方式,
第一种是采用<mvc:default-servlet-handler />,(一般Web应用服务器默认的Servlet名称是"default",所以这里我们激活Tomcat的defaultServlet来处理静态文件,在web.xml里配置如下代码即可:)
1 2 3 4 5 6 7 8 9 10
| 1 <!-- 该servlet为tomcat,jetty等容器提供,将静态资源映射从/改为/static/目录,如原来访问 http://localhost/foo.css ,现在http://localhost/static/foo.css -->
2 <!-- 不拦截静态文件 -->
3 <servlet-mapping>
4 <servlet-name>default</servlet-name>
5 <url-pattern>/js/*</url-pattern>
6 <url-pattern>/css/*</url-pattern>
7 <url-pattern>/images/*</url-pattern>
8 <url-pattern>/fonts/*</url-pattern>
9 </servlet-mapping>
10 |
1 2
| 1 Tomcat, Jetty, JBoss, and GlassFish 默认 Servlet的名字 -- "default"
2 |
Resin 默认 Servlet的名字 — "resin-file"
WebLogic 默认 Servlet的名字 — "FileServlet"
WebSphere 默认 Servlet的名字 — "SimpleFileServlet"
如果你所有的Web应用服务器的默认Servlet名称不是"default",则需要通过default-servlet-name属性显示指定:
1 2
| 1 <mvc:default-servlet-handler default-servlet-name="所使用的Web服务器默认使用的Servlet名称" />
2 |
3.自定义拦截器
SpringMVC的拦截器HandlerInterceptorAdapter对应提供了三个preHandle,postHandle,afterCompletion方法。preHandle在业务处理器处理请求之前被调用,
postHandle在业务处理器处理请求执行完成后,生成视图之前执行,afterCompletion在DispatcherServlet完全处理完请求后被调用,可用于清理资源等 。所以要想实现自己的权限管理逻辑,需要继承HandlerInterceptorAdapter并重写其三个方法。
首先在springmvc.xml中加入自己定义的拦截器我的实现逻辑CommonInterceptor,
1 2 3 4 5 6 7 8 9 10 11 12
| 1 <!--配置拦截器, 多个拦截器,顺序执行 -->
2 <mvc:interceptors>
3 <mvc:interceptor>
4 <!-- 匹配的是url路径, 如果不配置或/**,将拦截所有的Controller -->
5 <mvc:mapping path="/" />
6 <mvc:mapping path="/user/**" />
7 <mvc:mapping path="/test/**" />
8 <bean class="com.alibaba.interceptor.CommonInterceptor"></bean>
9 </mvc:interceptor>
10 <!-- 当设置多个拦截器时,先按顺序调用preHandle方法,然后逆序调用每个拦截器的postHandle和afterCompletion方法 -->
11 </mvc:interceptors>
12 |
1 2
| 1 我的拦截逻辑是“在未登录前,任何访问url都跳转到login页面;登录成功后跳转至先前的url”,具体代码如下:
2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
| 1 /**
2 *
3 */
4 package com.alibaba.interceptor;
5
6 import javax.servlet.http.HttpServletRequest;
7 import javax.servlet.http.HttpServletResponse;
8 import org.slf4j.Logger;
9 import org.slf4j.LoggerFactory;
10 import org.springframework.web.servlet.ModelAndView;
11 import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
12
13 import com.alibaba.util.RequestUtil;
14
15
16 /**
17 * @author tfj
18 * 2014-8-1
19 */
20 public class CommonInterceptor extends HandlerInterceptorAdapter{
21 private final Logger log = LoggerFactory.getLogger(CommonInterceptor.class);
22 public static final String LAST_PAGE = "com.alibaba.lastPage";
23 /*
24 * 利用正则映射到需要拦截的路径
25
26 private String mappingURL;
27
28 public void setMappingURL(String mappingURL) {
29 this.mappingURL = mappingURL;
30 }
31 */
32 /**
33 * 在业务处理器处理请求之前被调用
34 * 如果返回false
35 * 从当前的拦截器往回执行所有拦截器的afterCompletion(),再退出拦截器链
36 * 如果返回true
37 * 执行下一个拦截器,直到所有的拦截器都执行完毕
38 * 再执行被拦截的Controller
39 * 然后进入拦截器链,
40 * 从最后一个拦截器往回执行所有的postHandle()
41 * 接着再从最后一个拦截器往回执行所有的afterCompletion()
42 */
43 @Override
44 public boolean preHandle(HttpServletRequest request,
45 HttpServletResponse response, Object handler) throws Exception {
46 if ("GET".equalsIgnoreCase(request.getMethod())) {
47 RequestUtil.saveRequest();
48 }
49 log.info("==============执行顺序: 1、preHandle================");
50 String requestUri = request.getRequestURI();
51 String contextPath = request.getContextPath();
52 String url = requestUri.substring(contextPath.length());
53
54 log.info("requestUri:"+requestUri);
55 log.info("contextPath:"+contextPath);
56 log.info("url:"+url);
57
58 String username = (String)request.getSession().getAttribute("user");
59 if(username == null){
60 log.info("Interceptor:跳转到login页面!");
61 request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
62 return false;
63 }else
64 return true;
65 }
66
67 /**
68 * 在业务处理器处理请求执行完成后,生成视图之前执行的动作
69 * 可在modelAndView中加入数据,比如当前时间
70 */
71 @Override
72 public void postHandle(HttpServletRequest request,
73 HttpServletResponse response, Object handler,
74 ModelAndView modelAndView) throws Exception {
75 log.info("==============执行顺序: 2、postHandle================");
76 if(modelAndView != null){ //加入当前时间
77 modelAndView.addObject("var", "测试postHandle");
78 }
79 }
80
81 /**
82 * 在DispatcherServlet完全处理完请求后被调用,可用于清理资源等
83 *
84 * 当有拦截器抛出异常时,会从当前拦截器往回执行所有的拦截器的afterCompletion()
85 */
86 @Override
87 public void afterCompletion(HttpServletRequest request,
88 HttpServletResponse response, Object handler, Exception ex)
89 throws Exception {
90 log.info("==============执行顺序: 3、afterCompletion================");
91 }
92
93 }
94
95
96
97 |