/ ,代表的就是端口后面,哪怕你在配置文件中配置了项目的映射名,也是端口后面,不是映射名后面,它会直接忽视项目的映射名,只代表端口后边。
服务器端程序,一般都基于两种形式,一种C/S架构程序,一种B/S架构程序. 使用Java语言基本上都是开发B/S架构的程序,B/S架构又分成了三层架构
三层架构
表现层:WEB层,用来和客户端进行数据交互的。表现层一般会采用MVC的设计模型
业务层:处理公司具体的业务逻辑的
持久层:用来操作数据库的
MVC全名是Model View Controller 模型视图控制器,每个部分各司其职。
Model:数据模型,JavaBean的类,用来进行数据封装。
View:指JSP、HTML用来展示数据给用户
Controller:用来接收用户的请求,整个流程的控制器。用来进行数据校验等(Hibernate Validator)
1.清晰的角色划分:
前端控制器(DispatcherServlet)
请求到处理器映射(HandlerMapping) :负责找controller类
处理器适配器(HandlerAdapter) : 负责调用controller类,得到结果,封装结果
视图解析器(ViewResolver) : 负责解析view
处理器或页面控制器(Controller)
验证器( Validator)
命令对象(Command 请求参数绑定到的对象就叫命令对象)
表单对象(Form Object 提供给表单展示和提交到的对象就叫表单对象)。
2、分工明确,而且扩展点相当灵活,可以很容易扩展,虽然几乎不需要。
3、由于命令对象就是一个 POJO, 无需继承框架特定 API,可以使用命令对象直接作为业务对象。
4、和 Spring 其他框架无缝集成,是其它 Web 框架所不具备的。
5、可适配,通过 HandlerAdapter 可以支持任意的类作为处理器。
6、可定制性, HandlerMapping、 ViewResolver 等能够非常简单的定制。
7、功能强大的数据验证、格式化、绑定机制。
8、利用 Spring 提供的 Mock 对象能够非常简单的进行 Web 层单元测试。
9、本地化、主题的解析的支持,使我们更容易进行国际化和主题的切换。
10、强大的 JSP 标签库,使 JSP 编写更容易。
………………还有比如RESTful风格的支持、简单的文件上传、约定大于配置的契约式编程支持、基于注解的零配
置支持等等。
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.0.2.RELEASEversion>
dependency>
<dependency>
<groupId>javax.servlet.jspgroupId>
<artifactId>javax.servlet.jsp-apiartifactId>
<version>2.3.1version>
<scope>providedscope>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>javax.servlet-apiartifactId>
<version>3.1.0version>
<scope>providedscope>
dependency>
dependencies>
在webapp里创建
index.jsp
<%--
Created by IntelliJ IDEA.
User: xiaomi
Date: 2021/9/9
Time: 9:06
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Titletitle>
head>
<body>
<h2>这是首页~h2>
<a href="/sayHi">点我发起请求a>
body>
html>
在webapp里创建
success.jsp
<%--
Created by IntelliJ IDEA.
User: xiaomi
Date: 2021/9/9
Time: 9:06
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Titletitle>
head>
<body>
<h2>这是成功的页面~h2>
body>
html>
com.mingye.controller
包中创建类Controller01
@Controller
注解,声明成为一个beansayHi方法
,并在方法上增加@RequestMapping
注解,声明方法的访问路径/*
@Controller:
1. 标记了这个类专门是用来处理请求的,它就是一个控制器!
1.1 springmvc会扫描这个注解标注的类,然后创建对象,使用IOC容器管理起来。
1.2 这个类当中所有@RequestMapping标注的方法全部会被当成是 页面的路径地址!
@RequestMapping:
1. 标记这个方法它的映射路径地址,也就是什么请求过来的时候,会执行这个方法!
2. 属性介绍:
value: 用来设置映射地址
method: 用来设置请求方式
RequestMethod.POST: 处理POST请求
RequestMethod.GET: 处理GET请求
params: 要求一定要携带指定的参数
*/
@Controller
public class Controller01 {
@RequestMapping(value = "/sayHi03", params ={"name=admin" , "password=123"}, method ={RequestMethod.POST , RequestMethod.GET} )
public String sayHi03(){
System.out.println("hi~03!~! springmvc...");
return "success";
}
/*
使用物理视图跳转:
1. 返回值是页面的完整地址。看起来直观,但是写起来麻烦!
*/
@RequestMapping("/sayHi")
public String sayHi(){
System.out.println("hi~!~! springmvc...");
return "/success.jsp";
}
/*
使用逻辑视图跳转:
1. 返回值写起来简单,但是不直观。看不出来是哪个页面
2. 需要搭配视图解析器才能识别是哪里的页面
*/
@RequestMapping("/sayHi02")
public String sayHi02(){
System.out.println("hi~02!~! springmvc...");
return "success";
}
}
在
resources
中创建springmvc的配置文件springmvc.xml
, 这个名字可以随意,也可以写成前几天的applicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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.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.xsd">
<context:component-scan base-package="com.mingye"/>
beans>
在
webapp/WEB-INF/web.xml
中配置前端控制器DispatcherServlet
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<servlet>
<servlet-name>dispatcherservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:springmvc.xmlparam-value>
init-param>
<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>dispacherservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
web-app>
sayHi
方法被访问到,并且页面跳转到了success.jsp
spring-webmvc, servlet-api, jsp-api
掌握入门案例执行流程
掌握入门案例的配置
HandlerMapping
处理器映射器
Controller
及拦截器(类似过滤器)链HandlerAdapter
处理器适配器
Controller
执行Controller,得到模型和视图ViewResolver
视图解析器
DispatcherServlet
DispatcherServlet
HandlerMapping
处理器映射器,根据请求路径,查找匹配的Controller
及拦截器Controller
和拦截器(执行链)DispatcherServlet
HandlerAdapter
处理器适配器,调用控制器Controller
ModelAndView
对象(其中View指视图路径,Model要响应的数据对象)DispatcherServlet
ViewResolver
解析视图,得到真实视图(视图路径对应的页面)跟前几天的
applicationContext.xml
是一样的。只是换了个名字而已。springmvc和spring可以共用同一个配置文件!
<context:component-scan base-package="com.mingye.controller"/>
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
bean>
<mvc:default-servlet-Handler/>
<mvc:annotation-driven/>
标签,可以加载SpringMVC的组件
Controller
的方法中,返回的字符串就是跳转的视图(页面)路径/success.jsp | success.jsp
,即:视图的真实路径(完整路径)
success
,需要配合视图解析器,才能得到真实路径
Controller
的方法中,直接返回物理视图路径。@Controller
public class Controller01 {
//物理视图跳转: 要写完整的路径地址
@RequestMapping("/sayHi02")
public String sayHi02(){
System.out.println("调用了Controller01的sayHi02方法~!~");
return "/a/b/c/success.jsp";
}
}
springmvc.xml
中增加以下内容:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
bean>
Controller
中修改代码,简化方法返回值@Controller
public class Controller01 {
//逻辑视图跳转:只要写页面的名字即可,需要搭配视图解析器来使用
@RequestMapping("/sayHi03")
public String sayHi03(){
System.out.println("调用了Controller01的sayHi03方法~!~");
return "success";
}
}
prefix + "success" + suffix
,拼接成物理视图/success.jsp
使用SpringMVC时,客户端访问静态资源时,会访问不到 , 会得到404
Tomcat本身具备处理静态资源的能力,但是我们配置的DispatcherServlet
把Tomcat的默认处理器覆盖掉了;而DispatcherServlet
没有处理静态资源的能力,所以:访问不到静态资源
Tomcat里面有一个Servlet,可以处理静态资源: DefaultServlet,它的映射路径是 /
我们使用SpringMVC的时候,在web.xml中,配置DispatcherServlet,配置的地址路径也是 /
方案一:指定静态资源的位置
<mvc:resources mapping="/html/**" location="/html/"/>
<mvc:resources mapping="/js/**" location="/js/"/>
<mvc:resources mapping="/css/**" location="/css/"/>
方案二:由Tomcat处理静态资源(推荐)
<mvc:default-servlet-handler/>
配置视图解析器
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
bean>
如果有静态资源要访问,把静态资源仍然交给Tomcat处理
<mvc:default-servlet-handler/>
开启mvc的注解驱动:会注册一些组件,提供一些功能
<mvc:annotation-driven/>
开启组件扫描
<context:component-scan base-pcakge="com.mingye.controller"/>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<servlet>
<servlet-name>dispatcherservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:springmvc.xmlparam-value>
init-param>
<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>dispatcherservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
web-app>
load-on-startup
:配置Servlet的创建时机,值是整数
DispatcherServlet
是SpringMVC一切功能的基础和核心,要求:服务器启动时就创建,并且要最早创建,所以设置值为1init-param
:配置Servlet的初始化参数
contextConfigLocation
:配置springmvc.xml的路径,让DispatcherServlet被创建时,加载配置文件,初始化Spring容器url-pattern
:配置Servlet的路径,通常配置为/
DispatcherServlet
配置成/
和/*
的区别:对JSP的处理不同。当客户端请求了xxx.jsp
时
如果DispatcherServlet
配置的是/*
,不能正常访问JSP
/*
是目录匹配,优先级高于扩展名匹配(Tomcat里有JspServlet
,路径是*.jsp
)DispatcherServlet
来处理JSP,但是DispatcherServlet不具备查找和处理jsp的能力,会报错如果DispatcherServlet
配置的是/
,可以正常访问JSP
/
是缺省匹配,优先级低于扩展名匹配(Tomcat里有JspServlet
,路径是*.jsp
)完全路径匹配 > 目录匹配 > 扩展名匹配 > 缺省匹配
/aa > /* > *.do > /
package com.mingye.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.servlet.Servlet;
/*
@Controller :
1. 表示这个类是一个控制器,可以处理请求。
2. spring会把这个类管理起来, 创建这个类的对象。
RequestMapping :
1. 表示方法的映射地址,当什么请求来的时候,会执行这个方法。
2. 属性:
value|path : 用来设置映射路径
method : 用来设置请求方式,表示什么样的请求方式,才能执行这个方法。【默认是都支持!】
RequestMethod.GET : 允许get请求到这里来
RequestMethod.POST : 允许post请求到这里来
如果设置了post,页面还是用get请求过来,那么会报错:
Request method 'GET' not supported
params : 用来要求请求一定要携带指定名称的参数
params="username"`:必须提交了 名称为username的表单参数,才可以访问
params="username=tom"`:必须提交了 名称为username、值为tom的表单参数,才可以访问
params="username!=tom"`:提交了表单参数 名称为username、值不是tom, 才可以访问
3. 这个注解可以打在方法身上,也可以打在类身上!
3.1 在类身上写@RequestMapping,访问方法时,需要加上类上面的映射路径
3.2 这样子做的好处主要是为了和其他的模块进行区分。有前缀的划分。
*/
@Controller
@RequestMapping("/controller01")
public class Controller01 {
@RequestMapping(value = "/sayHi04", method = RequestMethod.GET , params = "username")
public String sayHi04(){
System.out.println("调用了Controller01的sayHi04方法~!~");
return "success";
}
}
@RequestMapping
注解 , 通常用在Controller
里,用于设置访问路径
@RequestMapping(
value="访问路径",
method=请求方式,
params="请求参数"
)
RequestMethod
中取值
RequestMethod.POST
:必须是POST方式,才可以访问到RequestMethod.GET
:必须是GET方式,才可以访问到params="username"
:必须提交了 名称为username的表单参数,才可以访问params="username=tom"
:必须提交了 名称为username、值为tom的表单参数,才可以访问params="username!=tom"
:提交了表单参数 名称为username、值不是tom, 才可以访问@RequestMapping("/user")
@RequestMapping("/save")
/user/save
绑定机制
表单提交的数据都是key=value格式的(username=zs&password=123), SpringMVC的参数绑定过程是把表单提交的请求参数,作为控制器中方法的参数进行绑定的(要求:提交表单的name和方法的参数的名称是相同的)
<form action="">
用户名:<input type="text" name="username"/>
密码: <input type= "password" name="password"/>
<input type="submit"/>
form>
public String register(String username , String password){
}
//======================================================
class User{
private String username;
private String password;
}
public String register02(User user){
}
支持的数据类型
基本数据类型和字符串类型
实体类型(JavaBean)
集合数据类型(List、map集合等)
使用要求
如果是基本类型或者 String 类型: 要求我们的参数名称必须和controller中方法的形参名称保持一致。 (严格区分大小写) .
如果是 对象 类型,或者它的关联对象: 要求表单中参数名称和对象类的属性名称保持一致
如果是集合类型,有两种方式:
SpringMVC的参数绑定过程是把表单提交的请求参数,作为controller里面方法的参数进行绑定的。
基本数据类型和字符串类型
实体类型(JavaBean)
集合数据类型(List、map集合等)
说明
页面
index.jsp
<h2>提交简单的参数:h2>
<form action="/requestSimpleParam" method="post">
用户名:<input type="text" name="username"/><br/>
密 码:<input type="text" name="password"/><br/>
年 龄:<input type="text" name="age"/><br/>
<input type="submit"/>
form>
<%--
Created by IntelliJ IDEA.
User: xiaomi
Date: 2021/9/29
Time: 11:10
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Titletitle>
head>
<body>
<h2>这是成功的页面~!~h2>
body>
html>
package com.mingye.controller;
import com.mingye.bean.*;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
@Controller
public class Controller01 {
/*
获取简单的参数:
要求:
1. 方法的参数名字必须和页面的form表单中的name属性的值 一样!
用户名:
*/
@RequestMapping("/requestSimpleParam")
public String requestSimpleParam(String username, String password , int age){
System.out.println("username = " + username);
System.out.println("password = " + password);
System.out.println("age = " + age);
return "success";
}
}
SpringMVC会帮我们自动把表单参数,封装成对象,但是要求:
- 客户端提交的表单参数名称,必须和JavaBean的属性名一样!
package com.mingye.bean;
import lombok.Data;
@Data
public class User {
private String username;
private String password;
private int age;
}
<h2>提交对象的参数:h2>
<form action="/requestObjectParam">
用户名:<input type="text" name="username"/><br/>
密 码:<input type="text" name="password"/><br/>
年 龄:<input type="text" name="age"/><br/>
<input type="submit"/>
form>
package com.mingye.controller;
import com.mingye.bean.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
@Controller
public class Controller01 {
/*
获取对象参数:
要求:
1. 页面提交上来的form表单的name属性值必须和JavaBean的属性名字一样!
用户名:
public class User {
private String username;
}
*/
@RequestMapping("/requestObjectParam")
public String requestObjectParam(User user){
System.out.println("user = " + user);
return "success";
}
}
注:只能2接前端多个参数(一个名字对应多个值),不能用List集合。确实需要List集合接收时,使用包装user.list
<h2>提交数组的参数:h2>
<form action="/requestArrayParam">
请选择您的爱好:<br/>
<input type="checkbox" name="hobby" value="smoke"/>抽烟
<input type="checkbox" name="hobby" value="drink"/>喝酒
<input type="checkbox" name="hobby" value="firehead"/>烫头<br/>
<input type="submit"/>
form>
package com.mingye.controller;
import com.mingye.bean.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
@Controller
public class Controller01 {
/*
获取数组参数:
要求:
1. 页面上的表单项,name属性值必须一样!
2. 方法参数的名字必须和name属性的值一样!
*/
@RequestMapping("/requestArrayParam")
public String requestArrayParam(String [] hobby){
System.out.println("hobby=" + Arrays.toString(hobby));
return "success";
}
}
请求参数类型是简单(基本,String)类型
请求参数类型是pojo对象类型
提交数组,只能用数组接收,多个参数的name属性名一致,参数要与controller中的参数名一致。
如果请求参数或者响应中有中文就会乱码。在web阶段,我们通过一个自定义的过滤器实现了统一乱码解决
req.setCharacterEncoding(“utf-8”)
resp.setContentType(“text/html;charset=utf-8”);
但是在springMVC中,处理post请求时,由于它的运作机制,DispatcherServlet很早就已经把数据(参数)拿出来了,此时的数据是乱码的,这个时候你在方法中设置了编码也没用了,所以只能用过滤器了,因为过滤器会先拦截请求,早于servlet。
现在SpringMVC本身 ,也给我们提供了一个过滤器
CharacterEncodingFilter
,用于解决乱码问题 。 只有在post请求才会有中文乱码,如果tomcat > 8.5的版本,那么tomcat已经帮助修复了get请求的中文乱码。如果使用了tomcat7的插件来跑项目, get请求还是会有乱码的!需要配置一下下!
<filter>
<filter-name>charfilter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>utf-8param-value>
init-param>
filter>
<filter-mapping>
<filter-name>charfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.mavengroupId>
<artifactId>tomcat7-maven-pluginartifactId>
<version>2.2version>
<configuration>
<port>82port>
<path>/path>
<uriEncoding>utf-8uriEncoding>
configuration>
plugin>
plugins>
build>
默认情况下,SpringMVC已经实现一些数据类型自动转换。 内置转换器全都在:
org.springframework.core.convert.support
包下 ,如遇特殊类型转换要求,需要我们自己编写自定义类型转换器。
)
<h2>提交包含日期的参数:h2>
<form action="/requestDateParam">
用户名:<input type="text" name="username"/><br/>
密 码:<input type="text" name="password"/><br/>
出生日期:<input type="text" name="birthday"/><br/>
<input type="submit"/>
form>
package com.mingye.bean;
import lombok.Data;
import java.util.Date;
@Data
public class User04 {
private String username;
private String password;
private Date birthday;
}
package com.mingye.controller;
import com.mingye.bean.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
@Controller
public class Controller01 {
/*
获取日期格式的数据
*/
@RequestMapping("/requestDateParam")
public String requestDateParam(User04 user04){
System.out.println("user04 = " + user04);
return "success";
}
}
步骤:
实现:
定义一个类,实现 Converter 接口
该接口有两个泛型,S:表示接受的类型, T:表示目标类型(需要转的类型)
package com.mingye.converter;
import org.springframework.core.convert.converter.Converter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/*
自定义日期格式转换器
1. 定义类,实现接口Converter
里面有两个泛型: S : 表示的是源数据的类型 , T: 表示的是目标数据的类型
2. 实现方法convert
*/
public class DateConverter implements Converter<String , Date> {
/**
*
* @param source 从页面接收到的数据
* @return 转化出来的日期对象。
*/
public Date convert(String source) {
try {
System.out.println("来到我们的日期转化器了:" + source);
//1. 定义SimpleDateFormat对象
SimpleDateFormat sf =null ;
if(source .contains("-")){
sf = new SimpleDateFormat("yyyy-MM-dd");
}else if(source.contains("/")){
sf = new SimpleDateFormat("yyyy/MM/dd");
}
//2. 转化
return sf.parse(source);
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
}
在springmvc.xml里面配置转换器
spring 配置类型转换器的机制是,将自定义的转换器注册到类型转换服务中去
<mvc:annotation-driven conversion-service="cs"/>
<bean id="cs" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<bean class="com.mingye.converter.DateConverter"/>
property>
bean>
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.0.2.RELEASEversion>
dependency>
<dependency>
<groupId>javax.servlet.jspgroupId>
<artifactId>javax.servlet.jsp-apiartifactId>
<version>2.3.1version>
<scope>providedscope>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>javax.servlet-apiartifactId>
<version>3.1.0version>
<scope>providedscope>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>1.18.18version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.9.6version>
dependency>
dependencies>
<%--
Created by IntelliJ IDEA.
User: xiaomi
Date: 2021/9/10
Time: 8:58
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
这是首页~!
<%--
Created by IntelliJ IDEA.
User: xiaomi
Date: 2021/9/10
Time: 8:58
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
这是成功的页面~!
<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.xsd">
<context:component-scan base-package="com.mingye"/>
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
bean>
<mvc:default-servlet-handler/>
beans>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<servlet>
<servlet-name>dispatcherservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:springmvc.xmlparam-value>
init-param>
<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>dispatcherservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
<filter>
<filter-name>charfilter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>utf-8param-value>
init-param>
filter>
<filter-mapping>
<filter-name>charfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
web-app>
作用:
属性
value: 要求携带的参数名字
required:请求参数中是否必须提供此参数。 默认值: true。表示必须提供,如果不提供将报错。
defaultValue:默认值
package com.mingye.controller;
import com.mingye.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
/*
常用的注解:
*/
@Controller
public class Controller01 {
/*
@RequestParam:
作用: 要求客户端来访问的时候,一定要携带指定名称的参数,否则报错!
步骤:
1. 在方法参数的前面打注解 @RequestParam
属性:
name|value : 用来指定携带的参数名称,如果不指定,那么就以参数名为参考标准。
required: 表示是否一定要携带参数,默认值是true,
defaultValue: 默认值
*/
@RequestMapping("/requestParam")
public String requestParam(@RequestParam(value="abc" , required = false , defaultValue = "张三") String username , @RequestParam String password){
System.out.println("username = " + username);
System.out.println("password = " + password);
return "success";
}
}
@RequestParam 只能用于接收 url 的传参 ?name=xxx, form表单的提交。
无法接收提交的json数据(contentType=application/json)
作用
**注意: get 请求方式不适用。 **
属性
required:是否必须有请求体。默认值是:true。当取值为 true 时,get 请求方式会报错。如果取值为 false, get 请求得到是 null。
<h2>使用@RequestBody获取请求体:h2>
<form action="/requestBody01" method="post">
用户名: <input type="text" name="username"/><br/>
密码: <input type="text" name="password"/><br/>
<input type="submit">
form>
package com.mingye.controller;
import com.mingye.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
/*
常用的注解:
*/
@Controller
public class Controller01 {
/*
@RequestBody
作用:
1. 可以获取表单提交上来的请求体,只有post请求才有请求体,get请求是没有请求体【不常用】
拿到的是一个字符串: username=admin&password=123456;
2. 可以接收页面提交上来的json数据,封装到JavaBe里面【常用】
步骤:
1. 方法参数的前面打上注解 @RequestBody,springmvc就会把请求体赋值给方法的参数。
*/
@RequestMapping("/requestBody01")
public String requestBody01(@RequestBody String body) throws UnsupportedEncodingException {
System.out.println("body = " + body);
}
/*
页面提交中文的时候,默认情况下,浏览器会对内容进行编码,使用URLEncoder.encode("张三","utf-8");
6张三7 ----URLEncoder.encode("张三","utf-8")-----6%E5%BC%A0%E4%B8%897
如果我们希望看到正常的张三:
1. 必须要设置过滤器,真正的解决中文乱码的问题。
2. 对这份数据解码即可:
6%E5%BC%A0%E4%B8%897 ----------URLDecoder.decode("6%E5%BC%A0%E4%B8%897", utf-8);
*/
String data = URLDecoder.decode(body, "utf-8");
System.out.println("data = " + data);
return "success";
}
}
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.9.6version>
dependency>
因为发请求,需要ajax的支持。
<mvc:default-servlet-handler/>
使用@RequestBody来获取json数据
package com.mingye.controller;
import com.mingye.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
/*
常用的注解:
*/
@Controller
public class Controller01 {
/*
@RequestBody:
接收页面提交上来的json数据,封装到JavaBean对象身上。
步骤:
1. 前端页面必须提交的是一份json数据
2. 添加进来jackson-databind的依赖
如果不加依赖,会报错: 415 Unsupported Media Type
3. 定义一个JavaBean,属性名字不能乱写,必须和json里面的KEY一样。
4. 在Controller方法参数的前面加上注解@RequestBody
如果不加,那么得到的是默认值!
*/
@RequestMapping("/requestBody02")
public String requestBody02(@RequestBody User user ) {
System.out.println("user = " + user);
return "success";
}
}
作用:
用于截取请求地址(url)里面的某些部分的数据。这个需要配合RestFul风格来说明
以前删除用户: localhost:82/deleteUser?id=3restFul : localhost:82/delete/3
属性:
value: 用于指定 url 中占位符名称。
required:是否必须提供占位符。
<h2>使用@PathVariable来获取地址中的参数h2>
<a href="/delete/1">点我发请求a>
<a href="/delete02/30/40">点我发请求2a>
package com.mingye.controller;
import com.mingye.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
/*
常用的注解:
*/
@Controller
public class Controller01 {
/*
现在以 按照id来删除用户举例:
以前的写法: localhost:82/delete?id=1
restFul: localhost:82/delete/1
@PathVariable:
作用: 用来截取地址栏中的参数,赋值给方法的形参
步骤:
1. 在映射地址里面使用 {占位符名字} 来占位,表示匹配这个位置的数据
2. 在方法参数的前面加上注解 @PathVariable("占位的名字")
属性:
name | value : 用来指定|设置 占位符的名称。
如果name和value不写,只有一种情况可以不写,就是占位符的名字和方法的参数名字一样!
*/
@RequestMapping("/delete/{id}")
public String pathVariable(@PathVariable(value="id") int id) {
System.out.println("id = " + id);
return "success";
}
@RequestMapping("/delete02/{id}/{id2}")
public String pathVariable02(@PathVariable int id , @PathVariable int id2) {
System.out.println("id = " + id);
System.out.println("id2 = " + id2);
return "success";
}
}
<h2>使用@ReqeustHeader来获取请求头的数据h2>
<a href="/requestHeader">点我发请求a>
package com.mingye.controller;
import com.mingye.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
/*
常用的注解:
*/
@Controller
public class Controller01 {
/*
@RequestHeader:
作用: 用来获取指定名称的请求头数据,赋值给方法的参数
*/
@RequestMapping("/requestHeader")
public String requestHeader(@RequestHeader("User-Agent") String data) {
System.out.println("data = " + data);
return "success";
}
}
作用:
用于把指定 cookie 名称的值传入控制器方法参数。
属性:
value:指定 cookie 的名称。
required:是否必须有此 cookie, 默认值是:true
<h2>使用@CookieValue来获取Cookie的值h2>
<a href="/cookieValue">点我发请求a>
package com.mingye.controller;
import com.mingye.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
/*
常用的注解:
*/
@Controller
public class Controller01 {
/*
@CookieValue
作用: 用来获取指定名称的cookie的值,赋值给方法的形参。
属性:
name&value : 指定cookie的名字!
JESSIONID:
1. 这是session作用域的id的名称,它会存放到cookie里面去。
2. 当我们打开首页的时候,访问的是index.jsp ----背后会被翻译成========> Servlet
3. 在这个翻译成的servlet里面,它会创建session对象,并且把session的地址存放到cookie里面去。
存放的cookie的KEY 叫做: JSESSIONID.
*/
@RequestMapping("/cookieValue")
public String cookieValue(@CookieValue("JSESSIONID") String data) {
System.out.println("data = " + data);
return "success";
}
}
AppConfig
/*配置DishpatcherServlet*/
public class AppConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
//用来配置除了SpringMVC之外的其他配置类: spring的配置类 、mybatis的配置类
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
//用来配置SpringMVC的配置类是哪些!
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringmvcConfig.class};
}
//DispatcherServlet 映射路径是什么?
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
//设置过滤器
@Override
protected Filter[] getServletFilters() {
return new Filter[]{new CharacterEncodingFilter("utf-8")};
}
}
SpringConfig
暂时还用不到
SpringmvcConfig
@EnableWebMvc // 启用MVC的功能,可以看成是相当于 注解驱动
@ComponentScan("com.mingye") //扫描包
@Configuration //表示这是一个配置类
public class SpringmvcConfig extends WebMvcConfigurerAdapter {
// 用来配置视图解析器
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
//1. 创建视图解析器对象
InternalResourceViewResolver vr = new InternalResourceViewResolver();
//2. 配置前缀和后缀
vr.setPrefix("/");
vr.setSuffix(".jsp");
//3. 把视图解析器的对象,放到视图解析器注册器里面去
registry.viewResolver(vr);
}
// 用来控制是否启用Tomcat里面的DefaultServlet
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
会报以下错误,说:不认识cache相关的东西,就是因为错导了cache的命名空间。
命名空间导了,但是有的时候会出现约束没有导,也会报错
如果约束没写,会报以下错误
Tomcat7依赖运行会有一些jar包不兼容的情况,有冲突的jar都是按照这种办法处理,tomcat8以上版本就不会有这个问题了