文章目录
什么是SpringMVC
- 是Spring框架的一个模块,是基于mvc的webframework模块。
- 解决了V-C交互的问题,传统的javaEE项目中,我们使用的控制器是Servlet,每个用户的请求都需要一个Servlet。大量的Servlet,不方便管理和维护。
五大核心组件
- DispatcherServlet:前端控制器,接收所有请求,但是不处理,将请求分发给不同的子控制器
- HandlerMapping:记录请求路径与控制器的对应关系
- Controller:实际处理请求
- ModelAndView:处理完请求后的结果
- ViewResolver:根据视图名称确定负责响应的视图组件
使用SpringMVC实现helloworld
1.使用idea创建maven项目。
命名项目,一路Next,这里就不详细介绍了
2.创建完项目之后,在mian文件夹下面添加java,resource和Test三个文件夹,然后分别给上不同的标记
3.在pom.xml文件中配置相关的jar包依赖
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.9.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
<version>3.1.0</version>
</dependency>
4.在java包下面创建package 取名为spring,然后创建类UserController(用户请求的控制器)
package spring;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author ydy
* @create 2019-03-24 11:16
*/
@Controller
public class UserController {
@RequestMapping("hello.do")
public String showHello(){
System.out.println("UserController.showHello");
return "hello";
}
}
5.在resource资源文件夹下面创建我们的配置文件,取名为spring.xml
其中:prefix属性表示前缀,suffix属性表示后缀,它的工作模式是以项目中的webapp为根目录,前缀 + 处理请求的方法的返回值 + 后缀,得到视图文件(.html、.jsp等)的位置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 组件扫描 -->
<context:component-scan
base-package="spring"/>
<context:component-scan base-package="spring"></context:component-scan>
<!-- 视图解析器 -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
6.在WEB-INF文件夹下面创建hello.jsp,内容就随意啦
<%--
Created by IntelliJ IDEA.
User: admin
Date: 2019/3/24
Time: 11:22
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Hello</title>
</head>
<body>
Hello SpringMVC
</body>
</html>
7.配置web.xml
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<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:spring.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
8.指定路径,并把war包放到Tomcat上
9.运行程序,idea默认打开index.jsp
输入后缀hello.do
进阶篇
接收参数请求
方法一
** 直接将请求参数声明为处理请求的方法的参数**
准备一个注册界面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>开始注册</title>
<link href="templets/style/reg.css" rel="stylesheet" type="text/css" />
</head>
<body>
<h1>用户注册</h1>
<form action="handleReg.do" method="post">
用户名:<input type="text" placeholder="请输入账号" name="username">
密码:<input type="password" placeholder="请输入密码" name="password"> 年龄:<input
type="text" placeholder="请输入年龄" name="age"> 手机号码:<input
type="text" placeholder="请输入手机号码" name="phone"> 电子邮箱:<input
type="text" placeholder="请输入邮箱" name="email"> <input
type="submit" value="注册">
</form>
</body>
</html>
在UserController里面添加两个方法,showReg负责展示注册界面,handleReg负责处理用户提交过来的表单
@RequestMapping("reg.do")
public String showReg() {
System.out.println("UserController.showReg");
return "reg";
}
@RequestMapping("handleReg.do")
public String handleReg(String username,String password,String phone,String email,Integer age) {
System.out.println("UserController.handleReg");
System.out.println("username = [" + username + "], password = [" + password + "], phone = [" + phone + "], email = [" + email + "], age = [" + age + "]");
return "";
}
启动项目,在注册界面输入一些信息
点击注册,很明显404,因为我们还没有做对应的处理
但是我们来看看控制台输出什么
用户填写的信息成功的被我们拿到了!!!
这种方式适用于请求的参数比较少的时候
使用这种做法时,必须保证请求参数的名称与方法的参数名称保持一致,如果不一致,控制器将视为“客户端没有提交某参数”,则控制器的参数值将是null。
接下来介绍第二种
方法二
将请求参数封装为处理请求的方法的参数对象
在spring包下面创建User类,生成get,set,toString,属性与我们注册界面一致
package spring;
public class User {
private String username;
private String password;
private String age;
private String phone;
private String email;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "User [username=" + username + ", password=" + password + ", age=" + age + ", phone=" + phone
+ ", email=" + email + "]";
}
}
修改UserController的handleReg方法
@RequestMapping("handleReg.do")
public String handleReg(User user) {
System.out.println("user = " + user);
return "";
}
再次启动项目,发现springmvc自动的将我们的信息放到了user对象里面
这种方式适用于请求参数过多的应用场景
在使用这种做法时,依然需要保证名称的一致,即请求参数的名称与封装的类型中的属性名称需要保持一致!
指定SpringMVC的编码
我们可以在web.xml文件中进行配置,通过filter来将整体的编码全部改成utf-8
<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>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
响应处理结果
重定向
准备一张登入的界面,位置也是在WEB-INF文件夹下面
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>登录</title>
</head>
<body>
<form action="handleLogin.do" method="post">
用户名:<input type="text" name="username" />
密码:<input type="text" name="password" />
<input type="submit" value="登录" />
</form>
</body>
</html>
之前用户注册之后我们只是简单的控制台打印了一下,接下来我们可以进行重定向了。在之前的handleReg方法中 return “”;修改为return “redirect:login.do”;同时添加login.do的处理方法
@RequestMapping("handleReg.do")
public String handleReg(User user) {
System.out.println("user = " + user);
return "redirect:login.do";
}
@RequestMapping(value="login.do")
public String showLogin() {
return "login";
}
此时,当我们再次点击注册,页面成功跳转
转发
创建用户登入结果的界面result.jsp
<%--
Created by IntelliJ IDEA.
User: admin
Date: 2019/3/24
Time: 15:45
To change this template use File | Settings | File Templates.
--%>
<%@ page isELIgnored="false"%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登入结果</title>
</head>
<body>
${msg}
</body>
</html>
在UserController里面添加处理用户登入请求的方法,假设账号密码都是root
@RequestMapping("handleLogin.do")
public String handleLogin(String username, String password, HttpSession session, ModelMap modelMap) {
System.out.println("username:" + username + "password:" + password);
String msg;
if ("root".equals(username)) {
if ("root".equals(password)) {
msg = "登入成功欢迎" + username + "回来";
modelMap.addAttribute("msg", msg);
} else {
msg = "密码错误";
modelMap.addAttribute("msg", msg);
}
} else {
msg = "账号不存在";
modelMap.addAttribute("msg", msg);
}
return "result";
}
然后就大功告成,启动项目进行调试
这里我们使用ModelMap封装需要转发的数据,需要调用其addAttribute()方法。
转发与重定向的区别
-
转发:
客户端只发出了1次请求,
服务器端的控制器和JSP组合完成功能并响应(控制器适合处理数据却不适合显示数据,JSP适合显示数据却不适合处理数据),最终客户端的浏览器中也不会发生变化; -
重定向:
客户端发出第1次请求时,服务器端给回30X响应码及重定向到的目标路径,由客户端发出第2次请求,所以,2次处理过程中的数据不可共享(除非使用Session等相关技术进行处理),且客户端的浏览器的地址栏会发生变化。
总结
- 相比于之前的传统Servlet开发的方法,SpringMVC省略了大量的代码
- 通过配置文件解耦合,不过对于这种方式,首次的预处理以及初始化容器则需要较长的时间
- 使用注解进行开发,效率更高,同时也方便维护