一: 入门案例
1.1:创建maven项目,并引入pom依赖
此时你会发现没有main目录下,没有java和resource目录,所以需要手动来创建一个文件夹,
java目录:右键mark Derectory as,选择Source Rootresources目录:右键mark Derectory as,选择resources Root
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.11.RELEASE</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.6</version>
<scope>provided</scope>
</dependency>
</dependencies>
1.2:在web.xml中配置dispatcherServler
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<!--拦截所有-->
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
1.3:在自定义的springmvc配置文件中
<?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"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<!--自动扫描-->
<context:component-scan base-package="com.baidu"></context:component-scan>
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
1.4:配置tomcat
注意:将/后面的项目名去掉后,访问的时候就不用加项目了。
1.5创建Controller
@Controller
public class HelloController {
@RequestMapping("/hello")
public String index(){
System.out.println("执行了index...");
return "index"; //这是逻辑视图,视图解析器会根据逻辑视图找到物理视图!
}
}
二:SpringMVC注解
2.1:@RequestMapping,@RequestParam
/*表示必须是get方法,而且参数必须有name,和id=10*/
@RequestMapping(value = "/hello", method = RequestMethod.GET, params = {"name","id"})
public String hello(@RequestParam("name") String username, Integer id){
System.out.println(username); //这样就获取了 name参数的值,前提是方法中的参数和params里面的参数名称一致,否则需要用@RequestParam指定一下
System.out.println(id); //这样就获取了id参数的值,前提是方法中的参数和params里面的参数名称一致
System.out.println("执行了hello...");
return "index";
}
2.2:@PathVariable
- springMVC也支持Resutful风格的url
- 传统 url:http:localhost:8080/rest?username=wzj&id=10
- Rest:http:localhost:8080/rest/username/id
@RequestMapping("/rest/{name}/{id}")
public String rest(@PathVariable("1")String name, @PathVariable("2")Integer id){
System.out.println(name);
System.out.println(id);
return "index";
}
使用restful风格的时候,@RequestMapping和方法名的参数对应也不行了,必须指定@PathVariable来完成请求参数和形参的映射!
2.3:@CookieValue
@RequestMapping("/testCookie")
public String cookie(@CookieValue("JSESSIONID") String id){
System.out.println(id);
return "index";
}
获取JSESSIONID的cookie值!
2.4:使用javaBean来绑定参数
SpringMVC会根据请求参数名和javaBean中的属性进行自动匹配,自动为对象属性填充同时支持级联属性
- 注册页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/user/register" method="POST">
用户id:<input type="text" name="id"/><br/>
用户名:<input type="text" name="name"/><br/>
地址:<input type="text" name="address.city"/><br/>
<input type="submit" value="注册"/>
</form>
</body>
</html>
- 实体类
@Data
public class User {
private Integer id;
private String name;
private Address address;
}
@Data
public class Address {
private String city;
}
- Controller
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping(value = "register", method = RequestMethod.POST)
public String register(User user){
System.out.println(user);
return "index";
}
}
注意:此时由于我填的用户名是中文,导致出现了乱码
- 解决中文乱码,在web.xml配置
<filter>
<filter-name>encodingFilter</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>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2.5:jsp页面的转发和重定向
springMvc默认以转发的形式响应客户端
1、转发
@RequestMapping("/forward")
public String forward(){
return "forward:/index.jsp"; //和 return "index.jsp";一致
}
2、重定向
@RequestMapping("/redirect")
public String redirect(){
return "redirect:/index.jsp";
}
三:数据绑定
springmvc的数据绑定,就是将请求参数映射到方法的形参中,数据绑定的工作是由HandlerAdapter来完成的
3.1:基本数据类型
//http://localhost:8080/baseType 请求的时候如果不给id参数会IllegalStateException报错!
@RequestMapping("/baseType")
@ResponseBody
public String baseType(int id){
return id+"";
}
@ResponseBody表示会直接将方法的返回值返回给客户端,如果不加@ResponseBody注解,那么springmvc会将返回值传递给DispatcherServlet,DispatcherServlet调用ViewResolver视图解析器对返回值进行解析,映射一个jsp资源!
3.2:包装类
@RequestMapping("/packageType")
@ResponseBody
public String packageType(@RequestParam(value = "num", required = false, defaultValue = "0") Integer id){
return id+"";
}
注:写成这样的如果不传num参数,默认会给形参id赋值为0,而不是null
包装类可以接收 null,当 HTTP 请求没有参数时,使用包装类定义形参的数据类型,程序不会抛出异常。
@ReqeustParam
value:将请求参数num的值,赋值给形参id
required:表示请求参数num是否是必须的,true必须的,false可选的
defaultValue=0:表示http请求中没有参数num,默认值为0
3.3:数组
@RestController
public class DataBindController {
@RequestMapping("array")
public String array(String[] id){
return Arrays.toString(id);
}
}
访问: http://localhost:8080/array?id=1&id=2 输出: [1, 2]
上面的写法也等同于下面
@Controller
public class DataBindController{
@RequestMapping("array")
@ResponseBody
public String array(String[] id){
return Arrays.toString(id);
}
}
@RestController表示控制器直接将方法的返回值返回给客户端!不进行视图解析
@Controller表示控制器默认会将每个方法的返回值交给试图解析图进行解析,如果只是需要将方法的返回值响应给客户端,而不需要进行视图解析,则在对应的方法定义处加上@ResponseBody即可!
3.4:List
springmvc不支持直接对List类型进行转换,需要包装
1、页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/list" method="POST">
<!--name属性值和实体类的属性名一致! -->
用户1编号:<input type="text" name="users[0].id"/><br/>
用户1名称:<input type="text" name="users[0].name"/><br/>
用户2编号:<input type="text" name="users[1].id"/><br/>
用户2名称:<input type="text" name="users[1].name"/><br/>
<input type="submit" value="提交"/>
</form>
</body>
</html>
2、实体类
@Data
public class UserList {
private List<User> users;
}
3、Controller
@RequestMapping("/list")
@ResponseBody
public String list(UserList userList){
StringBuffer sb = new StringBuffer();
for (User user:userList.getUsers()){
sb.append(user); //user默认会调用toString方法
}
return sb.toString();
}
页面输出:
User(id=1, name=???, address=null)User(id=2, name=??, address=null)User(id=3, name=??, address=null)
从页面到后台的是ok的,但从后台返回到页面的时候却出现了乱码!,此时需要加一个消息转换器!
4、在springmvc.xml中加入消息转换器!
<mvc:annotation-driven>
<!--消息转换器-->
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes" value="text/html;charset=UTF-8"></property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
3.5:map
Spring MVC 不支持 Map 类型的直接转换,需要对 List 集合进行包装。
1、页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/map" method="POST">
用户1编号:<input type="text" name="users['a'].id"/><br/>
用户1名称:<input type="text" name="users['a'].name"/><br/>
用户2编号:<input type="text" name="users['b'].id"/><br/>
用户2名称:<input type="text" name="users['b'].name"/><br/>
<input type="submit" value="提交"/>
</form>
</body>
</html>
2、实体类
@Data
public class UserMap {
private Map<String,User> users;
}
3、controller
@RequestMapping("/map")
@ResponseBody
public String map(UserMap userMap){
String map = userMap.getUsers().toString();
return map;
}
页面输出:{a=User(id=1, name=达到, address=null), b=User(id=2, name=大大, address=null)}
3.6:JSON
客户端直接发送Json格式的数据,直接通过springmvc绑定到方法的形参中!
1、springmvc无法访问静态资源!,我这里无法访问都不是什么被DispatcherServlet拦截了,我就没配springmvc的配置还是访问不了图片,我就感觉很奇怪,后来发现在pom.xml中,maven.compiler的是1.7,而我jdk是1.8,改成
1.8即可!
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
注:maven里面写的要和jdk版本一致!
2、处理 Spring MVC 无法加载静态资源,在 web.xml 中添加配置即可。(有很多种方式处理)
<!--让default去处理js-->
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.js</url-pattern>
</servlet-mapping>
3、jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript">
$(function () {
var user = {
"id":1,
"name":"wzj"
};
$.ajax({
url:"/data/json",
type:"post",
data:JSON.stringify(user),
contentType:"application/json;charset=UTF-8", /*发送json*/
dataType:"json", /*返回也是json类型*/
success:function(data){
alert(data.id+"-"+data.name)
},
error:function () {
alert("失败!")
}
});
});
</script>
</head>
<body>
</body>
</html>
4、controller
@Controller
public class AController {
@RequestMapping(value = "/data/json")
@ResponseBody
public User json(@RequestBody User user){
System.out.println(user);
user.setId("2");
user.setName("张三");
return user;
}
}
POST http://localhost:8080/data/json 415,无法将前台的json数据封装到实体类,需要引入fastjson
Spring MVC 中的 JSON 和 JavaBean 的转换需要借助于 fastjson,pom.xml 引入相关依赖。
5、pom依赖和springmvc中的配置
<!--fastJson-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.32</version>
</dependency>
<mvc:annotation-driven>
<!-- 消息转换器 -->
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes" value="text/html;charset=UTF-8"></property>
</bean>
<!-- 配置fastjson -->
<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter4"></bean>
</mvc:message-converters>
</mvc:annotation-driven>
来自:虽然帅,但是菜的cxy!!