SpringMVC框架——First Day

目录

三层架构

MVC模型

SpringMVC 快速入门案例

SpringMVC的概述(了解)

SpringMVC在三层架构的位置

SpringMVC的优势(了解)

创建SpringMVC的Maven项目

1.在pom.xml中添加所需要的jar包

2.在工程的web.xml中配置核心SpringMVC的核心控制器DispatcherServlet

3.在resources目录下创建springmvc.xml配置文件

4.在web.xml中添加配置,加载springmvc.xml配置文件

5.创建处理请求的类

6.在springmvc.xml配置文件中配置视图解析器 InternalResourceViewResolver,以及开启spirngmvc的注解驱动

7.在WEB-INF目录下创建一个success.jsp页面

8.在index.jsp中请求hello这个方法

9.发布项目,进行测试

入门案例的分析

官方的详细执行流程图

入门案例中的组件分析

RequestMapping注解的属性介绍

请求参数的绑定

1.请求参数绑定演示 最简单的方式超链接请求后台携带请求参数

2.将请参数封装到JavaBean中

3.如果JavaBean的中的属性有一个属性是另一个对象,如何封装

4.解决表单提交数据是post请求方式时,中文会乱码的情况

5.如果JavaBean中的属性是一个List类型或Map类型,如何封装请求参数

6.如果JavaBean中的一个属性是Date日期类型,如何封装

在控制器中使用原生的Servlet API对象

SpringMVC 常用注解

1.RequestParam注解

2.RequestBody注解

3.PathVariable注解

PathVariable注解演示

RequestHeader注解(了解)

CookieValue注解(了解)

ModelAttribute注解(了解)

SessionAttributes注解(了解)


三层架构

1. 咱们开发服务器端程序,一般都基于两种形式,一种C/S架构程序,一种B/S架构程序
2. 使用Java语言基本上都是开发B/S架构的程序,B/S架构又分成了三层架构
3. 三层架构表现层:WEB层,用来和客户端进行数据交互的。表现层一般会采用MVC的设计模型业务层:处理公司具体的业务逻辑的 Spring持久层:用来操作数据库的 MyBatis  JDBCTemplate
​

MVC模型

1. MVC全名是Model View Controller 模型视图控制器,每个部分各司其职。
2. Model:数据模型,JavaBean的类,用来进行数据封装。
3. View:指JSP、HTML用来展示数据给用户
4. Controller:用来接收用户的请求,整个流程的控制器。用来进行数据校验等。Servlet

SpringMVC 快速入门案例

SpringMVC的概述(了解)

springmvc是spring框架的一个模块,springmvc和spring无需通过中间整合层进行整合
​
SpringMVC 是一种基于 Java 的实现 MVC 设计模型的请求驱动类型的轻量级 Web 框架,
属于 Spring FrameWork 的后续产品,已经融合在 Spring Web Flow 里面。
Spring 框架提供了构建 Web 应用程序的全功 能 MVC 模块。使用 Spring 可插入的 MVC 架构,
从而在使用 Spring 进行 WEB 开发时,可以选择使用 Spring 的 Spring MVC 框架或集成其他 MVC 开发框架,
如 Struts1(现在一般不用),Struts2 等。 
SpringMVC 已经成为目前最主流的 MVC 框架之一,并且随着 Spring3.0 的发布,
全面超越 Struts2,成 为最优秀的 MVC 框架。
它通过一套注解,让一个简单的 Java 类成为处理请求的控制器,而无须实现任何接口。同时它还支持 RESTful 编程风格的请求

SpringMVC在三层架构的位置

01三层架构.png

SpringMVC的优势(了解)

1、清晰的角色划分:  前端控制器(DispatcherServlet)  请求到处理器映射(HandlerMapping)  处理器适配器(HandlerAdapter)  视图解析器(ViewResolver)  处理器或页面控制器(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风格的支持、简单的文件上传、约定大于配置的契约式编程支持、基于注解的零配 置支持等等。 
​

创建SpringMVC的Maven项目

1.在pom.xml中添加所需要的jar包

1.项目需求:在index.jsp中有一个超链接,点击超链接,请求一个类,让类中的方法执行,并跳转到success.jsp页面
2.步骤:2.1 maven项目创建完成后在pom.xml文件中,添加jar包坐标,如下:<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><!--锁定spring的版本--><spring.version>5.0.2.RELEASE</spring.version></properties><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency>
​<dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>${spring.version}</version></dependency>
​<dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>${spring.version}</version></dependency><dependency><groupId>javax.servlet</groupId><artifactId>servlet-api</artifactId><version>2.5</version><scope>provided</scope></dependency><dependency><groupId>javax.servlet.jsp</groupId><artifactId>jsp-api</artifactId><version>2.0</version><scope>provided</scope></dependency></dependencies>

2.在工程的web.xml中配置核心SpringMVC的核心控制器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"id="WebApp_ID" version="2.5"><!--配置springMVC的核心控制器--><servlet><servlet-name>dispatcherServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class></servlet><servlet-mapping><servlet-name>dispatcherServlet</servlet-name><url-pattern>/</url-pattern></servlet-mapping>
</web-app>

3.在resources目录下创建springmvc.xml配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:context="http://www.springframework.org/schema/context"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/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"><!--开启组件的注解扫描--><context:component-scan base-package="org.westos"></context:component-scan>
​
</beans>
​

4.在web.xml中添加配置,加载springmvc.xml配置文件

  <!--配置springMVC的核心控制器--><servlet><servlet-name>dispatcherServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!--加载springmvc.xml配置文件--><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:springmvc.xml</param-value></init-param><!--服务器一开启就创建DispatcherServlet对象--><load-on-startup>0</load-on-startup></servlet><servlet-mapping><servlet-name>dispatcherServlet</servlet-name><url-pattern>/</url-pattern></servlet-mapping>

5.创建处理请求的类

@Controller  //采用注解的方式把这个类交由Spring容器管理
public class Hello {@RequestMapping(value = "/hello") //配置请求的映射路径public String hello(){System.out.println("请求来了");return "success";  //返回跳转到jsp页面的名称}
}
​
解释:我们提供了一个hello()方法这个方法就是用来处理请求,以及返回视图页面名称,进行跳转
在hello()方法上添加的 @RequestMapping注解,可以用来配置请求路径
​
​

6.在springmvc.xml配置文件中配置视图解析器 InternalResourceViewResolver,以及开启spirngmvc的注解驱动

    <!--配置视图解析器--><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="viewResolver"><!--prefix 前缀  suffix 后缀 拼完成就是 /WEB-INF/success.jsp 因为我们返回的是一个success这个字符,然后再拼接上我们配置的前缀和后缀,就可以跳转到success.jsp这个页面--><property name="prefix" value="/WEB-INF/"></property><property name="suffix" value=".jsp"></property></bean><!--开启springmvc的注解驱动--><mvc:annotation-driven></mvc:annotation-driven>

7.在WEB-INF目录下创建一个success.jsp页面

因为我们在hello()方法中返回的名称叫做success 所以这个jsp页面就叫做success.jsp
这个success.jsp要放在WEB-INF目录下,因为我们在配置视图解析器的时候,前缀配置的就是/WEB-INF/
就是这行<property name="prefix" value="/WEB-INF/"></property>

8.在index.jsp中请求hello这个方法

 <a href="${pageContext.request.contextPath}/hello">请求后台</a>

9.发布项目,进行测试

入门案例的分析

1.png

1. 入门案例的执行流程
1. 当启动Tomcat服务器的时候,因为配置了load-on-startup标签,所以会创建DispatcherServlet对象,
就会加载springmvc.xml配置文件
2. 开启了注解扫描,那么HelloController对象就会被创建
3. 从index.jsp发送请求,请求会先到达DispatcherServlet核心控制器,根据配置@RequestMapping注解  
找到执行的具体方法
4. 根据执行方法的返回值,再根据配置的视图解析器,去指定的目录下查找指定名称的JSP文件
5. Tomcat服务器渲染页面,做出响应

官方的详细执行流程图

2.png

1、  用户发送请求至前端控制器DispatcherServlet
2、  DispatcherServlet收到请求调用HandlerMapping处理器映射器。
3、  HandlerMapping处理器映射器根据请求url找到具体的处理器(也就是我们所说的Controller),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
4、  DispatcherServlet通过HandlerAdapter处理器适配器调用处理器
5、  执行处理器(Controller,也叫后端控制器,也就是我们自己编写的Controller)。
6、  Controller执行完成返回ModelAndView
7、  HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet
8、  DispatcherServlet将ModelAndView传给ViewReslover视图解析器
9、  ViewReslover解析后返回具体View
10、 DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)。
11、 DispatcherServlet响应用户

入门案例中的组件分析

以下组件通常使用框架提供实现:
1.DispatcherServlet:前端控制器用户请求到达前端控制器,它就相当于mvc模式中的c,dispatcherServlet是整个流程控制的中心,相当于是SpringMVC的大脑,由它调用其它组件处理用户的请求,dispatcherServlet的存在降低了组件之间的耦合性。2.HandlerMapping:处理器映射器HandlerMapping负责根据用户请求url找到Handler即处理器,springmvc提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。3.Handler:处理器Handler 是继DispatcherServlet前端控制器的后端控制器,在DispatcherServlet的控制下Handler对具体的用户请求进行处理。
由于Handler涉及到具体的用户业务请求,所以一般情况需要程序员根据业务需求开发Handler。这里所说的Handler就是我们自己编写的Controller
​
5.HandlAdapter:处理器适配器通过HandlerAdapter对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。6.ViewResolver:视图解析器View Resolver负责将处理结果生成View视图,View Resolver首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成View视图对象,最后对View进行渲染将处理结果通过页面展示给用户。 
7.View:视图springmvc框架提供了很多的View视图类型的支持,包括:jstlView、freemarkerView、pdfView等。我们最常用的视图就是jsp。一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户,需要由程序员根据业务需求开发具体的页面。
​
说明:在springmvc的各个组件中,处理器映射器、处理器适配器、视图解析器称为springmvc的三大组件。
需要用户开发的组件有handler、view
​
​
在 SpringMVC 的各个组件中,处理器映射器、处理器适配器、视图解析器称为 SpringMVC 的三大组件。 
使 用 <mvc:annotation-driven> 自 动 加 载 RequestMappingHandlerMapping ( 处 理 映 射 器 ) 和
RequestMappingHandlerAdapter ( 处 理 适 配 器 ) , 可 用 在 SpringMVC.xml 配 置 文 件 中 使 用
<mvc:annotation-driven>替代注解处理器和适配器的配置。 
它就相当于在 xml 中配置了: 
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" id="handlerMapping"/> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter" id="handlerAdapter"/> 由于开发中,我们常用的是  RequestMappingHandlerMapping  和 
RequestMappingHandlerAdapter  ,这两个有一个简化的写法,如下: 
<mvc:annotation-driven> 
可以用这一行配置,代替  RequestMappingHandlerMapping  和 
RequestMappingHandlerAdapter  的两行配置。 

RequestMapping注解的属性介绍

1. RequestMapping注解的作用:是建立请求URL和处理方法之间的对应关系
2. RequestMapping注解可以作用在方法和类上作用在类上:第一级的访问目录作用在方法上:第二级的访问目录
@RequestMapping(path = "/demo") //一级路径
public class Hello {@RequestMapping(value = "/hello",params ={"username=zhangsan"} ) //二级路径public String hello() {System.out.println("请求来了");return "success";}
}
​
上面组合起来的路径就是 /demo/hello 那么前台请求路径也要跟着变<a href="${pageContext.request.contextPath}/demo/hello">请求后台</a>
​
3.细节:${ pageContext.request.contextPath}动态获取上下文路径
​
*** RequestMapping的属性
1. path 配置请求路径
2. value 配置请求路径
value属性和path属性意思是一样的,用哪个都可以
3. method 配置介绍那种请求方式例如:@RequestMapping(value = "/hello",method ={RequestMethod.GET,RequestMethod.POST}) 意思是接收get请求和post请求 
4. params 指定限制请求参数的条件例如:  @RequestMapping(value = "/hello",params ={"username"} ) 表示请求的时候必须有请求参数username 当但是跟请求参数的值没关系<a href="${pageContext.request.contextPath}/hello?username=zhangsan">请求后台</a>如果配置了请求参数的名称和值,那么在请求时,必须保持一致@RequestMapping(value = "/hello",params ={"username=zhangsan"} )<a href="${pageContext.request.contextPath}/hello?username=zhangsan">请求后台</a>请求时的参数名和值要和 @RequestMapping注解中配置的一致
5. headers 发送的请求中必须包含的请求头例如:@RequestMapping(value = "/hello",headers = "cookie") 请求信息中必须包含cookie这个请求头补充:@RequestMapping(value = "/hello2",method = {RequestMethod.GET})上面的写法可以使用一个注解来代替:@GetMapping(value = "/hello2")@RequestMapping(value = "/hello3",method = {RequestMethod.POST})上面的写法可以使用一个注解来代替:@PostMapping(value = "/hello3")@PutMapping@DeleteMapping

请求参数的绑定

一. 请求参数的绑定说明绑定机制1. 表单提交的数据都是k=v格式的  username=haha&password=1232. SpringMVC的参数绑定过程是把表单提交的请求参数,作为控制器中方法的参数进行绑定的3. 要求:提交表单的name和参数的名称是相同的
二. 支持的数据类型1. 基本数据类型和字符串类型2. 实体类型(JavaBean)3. 集合数据类型(List、map集合等)
三. 基本数据类型和字符串类型1. 提交表单的name和参数的名称是相同的2. 区分大小写
四. 实体类型(JavaBean)1. 提交表单的name和JavaBean中的属性名称需要一致2. 如果一个JavaBean类中包含其他的引用类型,那么表单的name属性需要编写成:对象.属性 例如:
address.name
五. 给集合属性数据封装1. JSP页面编写方式:list[0].属性
​

1.请求参数绑定演示 最简单的方式超链接请求后台携带请求参数

1.最简单的方式超链接的请求后台携带请求参数例如:jsp页面中 <a href="${pageContext.request.contextPath}/param/get?username=zhangsan&password=123456">请求后台携带参数</a>2. 后台要求处理前台1.请求的方法的形参名称和请求参数的名称保持一致,即可接收到请求参数的值@Controller
@RequestMapping("/param")
public class ParamDemo {@RequestMapping("/get")public String getParam(String username,String password){System.out.println(username);System.out.println(password);return "success";}
}

2.将请参数封装到JavaBean中

1.如果前台是一个表单请求后台,表单中的数据较多,我们可以使用一个实体类,将表单提交的数据封装到实体类中表单如下:<form action="${pageContext.request.contextPath}/param/getform" method="post">姓名:<input type="text" name="username" /><br />密码:<input type="text" name="password" /><br />金额:<input type="text" name="money" /><br /><input type="submit" value="提交" /></form>2.提供一个JavaBean,用来封装表单中的数据,要求JavaBean的属性名和表单中的name属性值保持一致即可public class Account implements Serializable {private String username; //属性名和表单中name属性值保持一致private String password;private Double money;// get set 方法略...}3.后台处理表单请求的方法形参,是一个JavaBean类型即可  @Controller
@RequestMapping("/param")
public class ParamDemo {@RequestMapping("/getform")public String getParam(Account account){System.out.println(account);return "success";}
}

3.如果JavaBean的中的属性有一个属性是另一个对象,如何封装

1. JavaBean中的属性是一个User类型的
public class Account implements Serializable {private String username;private String password;private Double money;private User user; //维护着另一个JavaBean的引用//get set 方法略...}public class User {private String uname;private Integer age;//get set 方法略}2.JSP页面中表单的写法<form action="${pageContext.request.contextPath}/param/getform" method="post">姓名:<input type="text" name="username" /><br />密码:<input type="text" name="password" /><br />金额:<input type="text" name="money" /><br /><%--这里user是Account类中的属性名uname和age是User类中的属性名--%>用户姓名:<input type="text" name="user.uname" /><br />用户年龄:<input type="text" name="user.age" /><br /><input type="submit" value="提交" /></form>3.处理表单请求的方法的形参还是Account类型即可@Controller
@RequestMapping("/param")
public class ParamDemo {@RequestMapping("/getform")public String getParam(Account account){System.out.println(account);return "success";}
}

4.解决表单提交数据是post请求方式时,中文会乱码的情况

1.当表单提交方式是get时中文不会乱码,但是post请求时中文会乱码,如何处理?我们需要在web.xml中配置一个SpringMVC提供的一个过滤器CharacterEncodingFilter
2.web.xml中配置如下:<filter><filter-name>encodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><!--指定字符集 encoding这个属性可以在CharacterEncodingFilter类中找到--><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>

5.如果JavaBean中的属性是一个List类型或Map类型,如何封装请求参数

1.JavaBean中属性的类型是List类型或Map类型
​
public class Account implements Serializable {private String username;private String password;private Double money;private List<User> list;//集合里面装的是User类型private Map<String,User> map; //键是String类型,值时User类型//get set 方法略...}2. 前台页面的写法<form action="${pageContext.request.contextPath}/param/getform" method="post">姓名:<input type="text" name="username" /><br />密码:<input type="text" name="password" /><br />金额:<input type="text" name="money" /><br /><%--list是Account类中的属性名 而[0]是索引--%>用户姓名:<input type="text" name="list[0].uname" /><br />用户年龄:<input type="text" name="list[0].age" /><br /><%--map是Account类中的属性名  而['one'] one是自己指定一个键名--%>用户姓名:<input type="text" name="map['one'].uname" /><br />用户年龄:<input type="text" name="map['one'].age" /><br /><input type="submit" value="提交" /></form>
3. 后台处理前台请求的方法形参还是一个Account类型即可
@Controller
@RequestMapping("/param")
public class ParamDemo {@RequestMapping("/getform")public String getParam(Account account){System.out.println(account);return "success";}
}

6.如果JavaBean中的一个属性是Date日期类型,如何封装

1.如果一个JavaBean中有一个属性是Date类型,那么前台提交时他写的日期字符串格式是 2019/08/01 也就是用 /分割那么SpringMVC是可以把日期字符串转换成日类型,但是如果我们不用/分割想要自己定义日期字符串的格式,那么就需要使用一个转换器来进行转换
2.我们提供一个Java类 提供一个日期类型的属性public class User {private String uname;private Integer age;private Date birthday; //日期类型的属性//get set 方法省略...}
3.前台页面<form action="${pageContext.request.contextPath}/param/getform" method="post">用户姓名:<input type="text" name="uname" /><br />用户年龄:<input type="text" name="age" /><br />用户生日:<input type="text" name="birthday" /><br /><input type="submit" value="提交" /></form>
4.后台处理请求的方法
@Controller
@RequestMapping("/param")
public class ParamDemo {@RequestMapping("/getform")public String getParam(User user){System.out.println(user);return "success";}
}
5.如果前台页面生日的表单填写 2017/03/05 这种个格式,是能自动封装进JavaBean中的
6.如果是自己要指定格式,那么首先我们自己定义一个类,实现一个SpringMVC的转换器接口Converterpublic class MyDateConverter implements Converter<String,Date> {@Overridepublic Date convert(String dateStr){Date date=null;if(dateStr!=null){try {date= new SimpleDateFormat("yyyy-MM-dd").parse(dateStr);} catch (ParseException e) {e.printStackTrace();}}else{throw new RuntimeException("日期字符串为空");}return date;}
}
7. 注册自定义类型转换器,在springmvc.xml配置文件中编写配置<!--注册我们的自定义日期转换器--><bean class="org.springframework.context.support.ConversionServiceFactoryBean" id="conversionServiceFactoryBean"><property name="converters"><set><bean class="org.westos.domain.MyDateConverter"></bean></set></property></bean>8. 记得在开启Spring对MVC注解的支持的配置中加上ConversionServiceFactoryBean对象<!--开启springmvc的注解驱动--><mvc:annotation-driven conversion-service="conversionServiceFactoryBean"></mvc:annotation-driven>
​

在控制器中使用原生的Servlet API对象

1. 只需要在控制器的方法参数定义HttpServletRequest和HttpServletResponse对象
​@RequestMapping("/demo")public String getServletAPI(HttpServletRequest request, HttpServletResponse response,HttpSession session){System.out.println(request);HttpSession session = request.getSession();ServletContext servletContext = session.getServletContext();System.out.println(response);return "success";}

SpringMVC 常用注解

1.RequestParam注解

** 作用:把请求中的指定名称的参数传递给控制器中的形参赋值,此注解用在形参上。
** 属性1. value:请求参数中的名称 或者使用name属性 两个一样2. required:请求参数中是否必须提供此参数,默认值是true,必须提供3. defaultValue = "lisi" 参数的默认值
我们在请求后台时携带的请求参数名和我们后台处理请求的方法上的形参名保持一致,我们就可以把请求参数的值封装给形参,我们一直也是这么做的,但是如果我们请求的参数名就是和方法的形参名不保持一致,怎么办?
那么我们就可以使用 RequestParam注解 来解决
前台请求参数名是 uname
<a href="${pageContext.request.contextPath}/anno/testRequestParam?uname=zhangsan">请求后台</a>
​
后台示例如下:
@Controller
@RequestMapping("/anno")
public class AnnotationDemo {@RequestMapping("/testRequestParam")public String testRequestParam(@RequestParam(value = "uname") String username){System.out.println(username);return "success";}
}
​
注意:required属性默认是true 也就是说 请求连接中参数必须要有一个uname, 名字不对,或没有请求参数都不行
​

2.RequestBody注解

** 作用:用于获取请求体的内容(注意:get方法不可以,因为get请求没有请求体),此注解用在方法的形参上
** 属性1. required:是否必须有请求体,默认值是true前台代码 post请求
<form action="${pageContext.request.contextPath}/anno/testRequestBody" method="post">用户姓名:<input type="text" name="uname" /><br />用户年龄:<input type="text" name="age" /><br/><input type="submit" value="提交" />
</form>
​
后台获取请求体内容
@Controller
@RequestMapping("/anno")
public class AnnotationDemo {@RequestMapping("/testRequestBody")public String testRequestBody(@RequestBody String body){System.out.println(body);return "success";}
}
输出的请求体内容是  uname=zhangsan&age=123456
那如果这样拿请求参数还得自己截取字符串,我们肯定不这么做。
我们之所以用@RequestBody这个注解,获取请求参数,是针对如果前台用的是Ajax请求,那么会向后台
提交的是JSON字符串,所以我们就得通过@RequestBody 来获取到JSON字符串,然后解析JSON字符串
​

3.PathVariable注解

** 作用:拥有绑定url中的占位符的。例如:url中有/delete/{id},{id}就是占位符
** 属性1. value:指定url中的占位符名称
** Restful风格的URL1. 请求路径一样,可以根据不同的请求方式去执行后台的不同方法
** restful风格的URL优点1. 结构清晰2. 符合标准3. 易于理解4. 扩展方便

什么是restful?

Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
​
资源:互联网所有的事物都可以被抽象为资源
资源操作:使用POST、DELETE、PUT、GET,使用不同方法对资源进行操作。分别对应 添加、 删除、修改、查询。
传统方式操作资源
http://127.0.0.1/item/queryItem?id=1&name=zhangsan  查询,GET
http://127.0.0.1/item/saveItem          新增,POST
http://127.0.0.1/item/updateItem        更新,POST
http://127.0.0.1/item/deleteItem?id=1   删除,GET或POST
​
使用RESTful操作资源
http://127.0.0.1/item/1     查询,GET
http://127.0.0.1/item       新增,POST
http://127.0.0.1/item       更新,PUT
http://127.0.0.1/item/1     删除,DELETE
​

PathVariable注解演示

1.传统方式前台页面有个get请求,且携带有请求参数 uid=1
<a href="${pageContext.request.contextPath}/anno/testPathVariable?uid=1">请求后台</a>
​
2.后台获取uid的值
@Controller
@RequestMapping("/anno")
public class AnnotationDemo {@RequestMapping("/testPathVariable")public String testPathVariable(String uid){//形参名和请求参数名保持一致System.out.println(uid);return "success";}
}
​
3.采用Restful风格的请求URL如下
<a href="${pageContext.request.contextPath}/anno/testPathVariable/1">请求后台</a>
​
4.后台需要使用@PathVariable这个注解来拿到 1 这个值,并设置给形参
@Controller
@RequestMapping("/anno")
public class AnnotationDemo {@RequestMapping("/testPathVariable/{uid}") //{uid}请求参数占位符//value="uid" 中的uid跟占位符uid名称保持一致,就会取出请求URL中的1设置给形参uidpublic String testPathVariable(@PathVariable(value = "uid") String uid){System.out.println(uid);return "success";}
}
5.注意:当然如果方法形参的名称和{uid}占位符的名称一样,那么@PathVariable的value属性值可以不写
@Controller
@RequestMapping("/anno")
public class AnnotationDemo {@RequestMapping("/testPathVariable/{uid}") //{uid}请求参数占位符//如果形参的名称和占位符的名称一样,可以省略@PathVariable注解的value属性public String testPathVariable(@PathVariable String uid){System.out.println(uid);return "success";}
}
​
​

RequestHeader注解(了解)

**作用:获取指定请求头的值
** 属性1. value:请求头的名称2.前台请求:
<a href="${pageContext.request.contextPath}/anno/testRequestHeader">请求后台</a>3.后台代码:
@Controller
@RequestMapping("/anno")
public class AnnotationDemo {@RequestMapping("/testRequestHeader")//@RequestHeader(value = "cookie")获取cookie请求头的值,设置给形参public String testPathVariable(@RequestHeader(value = "cookie") String cookieValue){System.out.println(cookieValue);return "success";}
}

CookieValue注解(了解)

** 作用:用于获取指定cookie的名称的值
** 属性
1. value:cookie的名称
​
2.前台代码
<a href="${pageContext.request.contextPath}/anno/testCookieValue">请求后台</a>
​
3.后台代码:
​
@Controller
@RequestMapping("/anno")
public class AnnotationDemo {@RequestMapping("/testCookieValue")//获取JSESSIONID这个cookie名的值public String testPathVariable(@CookieValue(value = "JSESSIONID") String jsessionIDValue){System.out.println(jsessionIDValue);return "success";}
}

ModelAttribute注解(了解)

** 作用1. 出现在方法上:表示当前方法会在控制器方法执行前先执行。2. 出现在参数上:获取指定的数据给参数赋值。
**应用场景1. 当提交表单数据不是完整的实体数据时,保证没有提交的字段使用数据库原来的数据。
演示:
1.前台代码:表单中,我只提交了两个选项uname和age,但是我User实体类中有三个属性
<form action="${pageContext.request.contextPath}/anno/testModelAttribute" method="post">用户姓名:<input type="text" name="uname" /><br />用户年龄:<input type="text" name="age" /><br/><input type="submit" value="提交" /></form>2.User 实体类有三个属性public class User {private String uname;private Integer age;private Date birthday; //日期类型的属性 get set 方法 略}3.那么我后台一封装,肯定birthday属性是没有值的 
@Controller
@RequestMapping("/anno")
public class AnnotationDemo {@RequestMapping("/testModelAttribute")public String testModelAttribute(User user){System.out.println(user);//user对象中birthday属性没有值,因为前台没有提交这个数据return "success";}
}
4.那我可以不可以从数据库中通过前台表单提交的uname的值,然后从数据库查出一个User对象,把这个User对象返回给testModelAttribute(User user)这个方法中的user对象来使用。答案是可以,那就得需要提供一个方法,然后在这个方法上添加@ModelAttribute注解那么这个方法,就可以优先testModelAttribute(User user)方法执行@ModelAttribute //加了此注解,findUserByName这个方法就优先于testModelAttribute()方法执行public User findUserByName(String uname){//根据这个uname去数据库查询出一个User对象,返回//那我这边,就new一个User对象,来模拟这个对象,是从数据库查出来的User user = new User();user.setUname(uname);user.setAge(100);user.setBirthday(new Date());
​return user;}@RequestMapping("/testModelAttribute")public String testModelAttribute(User user){System.out.println(user);//现在user对象中birthday属性就有值了,用的是findUserByName()方法,返回的User对象中的birthday属性的值return "success";}
​
​
//用法2 @ModelAttribute 加在形参前面  通过map集合中的键来获取对象设置给方法的形参
@GetMapping("/add")public String saveAccont(@ModelAttribute(value = "myData") Account account) {System.out.println("保存账户");System.out.println(account);return "success";}
​// @ModelAttribute 在你请求接口之前会执行@ModelAttributepublic void init(String name, double money, Map<String, Object> map) {//根据账户名,从数据库中查询账户的就信息System.out.println("init方法执行");Account account = new Account();account.setName(name);account.setMoney(money);account.setDesc("数据库中查出的");//把对象放到map集合里面map.put("myData", account);}
//浏览器测试
http://localhost:8080/springmvc_demo2_war/add?name=zhangsan&money=6666

SessionAttributes注解(了解)

** 作用:用于多次执行控制器方法间的参数共享
** 属性 value/names 意思一样  作用在类上
1. value:指定存入属性的名称
​
2.前台代码<a href="${pageContext.request.contextPath}/anno/testSessionAttributes">请求后台</a>
3.后台代码
@Controller
@RequestMapping("/anno")
@SessionAttributes(value = "msg") //把request域中的数据存到Session域中
public class AnnotationDemo {@RequestMapping("/testSessionAttributes")public String testSessionAttributes(Model model){//Model 是SringMVC给我们提供的一个接口,可以把数据存到request域中model.addAttribute("msg","林青霞");//我们在request域中先存一份,然后在类上加了@SessionAttributes(value = "msg")这个注解,就可以在session域中再存了一份return "success"; //跳转到success页面后,我们可以从页面中取出request域中的数据}}
​
4.我们可以在另一个方法里面取出Session域中的数据 取的话,可以使用ModelMap这个类(他是Model的子类)<a href="${pageContext.request.contextPath}/anno/getSessionAttributes">请求后台</a>@RequestMapping("/getSessionAttributes")public String getSessionAttributes(ModelMap model) {//使用ModelMap中的get方法,取出域中的数据Object msg = model.get("msg");System.out.println(msg);return "success"; //跳转到success页面后,我们可以从页面中取出request域中的数据}注意:看效果的时候,先存一下,再取5.清除Seesion域中的数据我们使用一个 SessionStatus类中的方法,来清除
​@RequestMapping("/delSessionAttributes")public String delSessionAttributes(SessionStatus sessionStatus) {sessionStatus.setComplete();return "success"; }
注意测试的时候:先存,然后清除,然后获取看一下

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/76996.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux修改系统语言

sudo dpkg-reconfigure locales 按pagedown键&#xff0c;移动红色光标到 zh_CN.UTF-8 UTF-8&#xff0c;空格标记*号&#xff08;没标记下一页没有这一项&#xff09;&#xff0c;回车。 下一页选择 zh_CN.UTF-8。 如果找不到 dpkg-reconfigure whereis dpkg-reconfigure …

Java的变量与常量

目录 变量 声明变量 变量的声明类型 变量的声明方式&#xff1a;变量名 变量名的标识符 初始化变量 常量 关键字final 类常量 总结 变量和常量都是用来存储值和数据的基本数据类型存储方式&#xff0c;但二者之间有一些关键差别。 变量 在Java中&#xff0c;每个变…

深入理解TCP三次握手:连接可靠性与安全风险

目录 导言TCP简介和工作原理的回顾TCP三次握手的目的和步骤TCP三次握手过程中可能出现的问题和安全风险为什么TCP三次握手是必要的&#xff1f;是否可以增加或减少三次握手的次数&#xff1f;TCP四次挥手与三次握手的异同点 导言 在网络通信中&#xff0c;TCP&#xff08;Tra…

sqoop

一、bg 可以在关系型数据库和hdfs、hive、hbase之间导数 导入&#xff1a;从RDBMS到hdfs、hive、hbase 导出&#xff1a;相反 sqoop1 和sqoop2 (1.99.x)不兼容&#xff0c;sqoop2 并没有生产的稳定版本&#xff0c; Sqoop1 import原理(导入) 从传统数据库获取元数据信息&…

8.5day06 框架基础--反射+注解

文章目录 反射获取类的各种信息获取类的字节码文件 注解元注解 复习redis两道算法题 摆烂了&#xff0c;不想学啦&#xff01;&#xff01;&#xff01; 反射 反射主要用来做框架; 学习内容 获取类的各种信息 第一步 加载类&#xff0c;获取类的字节码文件 第二步 获取类的…

Matlab的信号频谱分析——FFT变换

Matlab的信号频谱分析——FFT变换 Matlab的信号频谱分析 FFT是离散傅立叶变换的快速算法&#xff0c;可以将一个时域信号变换到频域。 有些信号在时域上是很难看出什么特征的。但是如果变换到频域之后&#xff0c;就很容易看出特征了。 这就是很多信号分析采用FFT变换的原因…

巨人网络宣布与华为达成鸿蒙生态合作,2024年发布原始征途手游

巨人网络宣布与华为达成鸿蒙生态合作&#xff0c;官方公众号发布的消息确认。 巨人网络与华为宣布战略合作&#xff0c;旨在实现技术互补、成果共享和商业共赢。 巨人网络将利用基于HarmonyOS的核心特性&#xff0c;如“可分可合、自由流转、一次开发多端部署”&#xff0c;创…

如何在终端设置代理(设置jupyter notebook同理)

设置代理 在终端(我用的gitbash)下执行 set HTTP_PROXYhttp://<user>:<password><proxy server>:<proxy port> set HTTPS_PROXYhttp://<user>:<password><proxy server>:<proxy port>其中&#xff1a; user、password&#…

300个智商测试FLASH智商游戏ACCESS数据库

最近在找IQ测试方面的数据&#xff0c;网上大多只留传着33道题这种类型&#xff0c;其他的又因各种条件&#xff08;比如图片含水印等&#xff09;不能弄&#xff0c;这是从测智网下载的一些测试智商的游戏数据&#xff0c;游戏文件是FLASH的&#xff0c;扩展名是SWF。 数据包总…

android studio 实用插件推荐

本文字数&#xff1a;&#xff1a;2352字 预计阅读时间&#xff1a;8分钟 背景 现在做安卓开发的同学基本都是用 Android Studio 了吧&#xff0c;它具有强大的开放性&#xff0c;可以让用户根据自己的需求开发或使用一些插件辅助自己搬砖&#xff0c;当然开发插件我们可能还没…

[oeasy]python0079_控制序列_光标位置设置_ESC_逃逸字符_CSI

光标位置 回忆上次内容 上次我们研究的比较杂 类型转化进制转化捕获异常版本控制生成帮助文档变量的常用类型变量的生命周期控制 数据类型主要研究了两个 字符串 str 整型数字 int 字符串型 和 整型数字型变量 是可以相互转化的 加法运算逻辑 会根据操作变量的不同 而不同…

vue el-input 使用 回车键会刷新页面的问题

场景&#xff1a; vue项目中 在输入框输入字符并按下回车键搜索时&#xff0c;不会进行搜索&#xff0c; 而是会刷新页面 原因&#xff1a; 当form表单中只有一个input时&#xff0c;按下回车建会自动触发页面的提交功能&#xff0c; 产生刷新页面的行为 解决&#xff1a; 在…

idea 2023 新版ui中git的相关操作

前两个月换了新电脑&#xff0c;下了最新版的idea发现可以切换一套新的ui了 切换新ui肯定不太习惯&#xff0c;很多操作都得重新摸索一下 在这里记录几个git相关的操作 忽略我下面截图中当前项目是js的后端项目…… 切换ui 首先说一下怎么切换新旧版ui&#xff0c;我这里就…

机器学习和深度学习简述

一、人工智能、机器学习、深度学习的关系 近些年人工智能、机器学习和深度学习的概念十分火热&#xff0c;但很多从业者却很难说清它们之间的关系&#xff0c;外行人更是雾里看花。概括来说&#xff0c;人工智能、机器学习和深度学习覆盖的技术范畴是逐层递减的&#xff0c;三…

酷开系统 | 酷开科技,让数据变得更有价值!

身处信息时代&#xff0c;我们每个人时刻都在生成、传递和应用数据&#xff0c;数据已经成为了现代社会中宝贵的资源之一&#xff0c;而在人工智能领域&#xff0c;数据更是被称为人工智能的“燃料”。 而在AI的发展中&#xff0c;只有拥有高质量、多样性且充分代表性的数据集…

图解java.util.concurrent并发包源码系列——深入理解ReentrantLock,看完可以吊打面试官

图解java.util.concurrent并发包源码系列——深入理解ReentrantLock&#xff0c;看完可以吊打面试官 ReentrantLock是什么&#xff0c;有什么作用ReentrantLock的使用ReentrantLock源码解析ReentrantLock#lock方法FairSync#tryAcquire方法NonfairSync#tryAcquire方法 Reentrant…

微信小程序iconfont真机渲染失败

解决方法&#xff1a; 1.将下载的.woff文件在transfonter转为base64&#xff0c; 2.打开网站&#xff0c;导入文件&#xff0c;开启base64按钮&#xff0c;下载转换后的文件 3. 在下载解压后的文件夹中找到stylesheet.css&#xff0c;并复制其中的base64 4. 修改index.wxss文…

Jmeter +Maven+jenkins 接口性能全自动化测试

背景&#xff1a; 首先用jmeter录制或者书写性能测试的脚本&#xff0c;用maven添加相关依赖&#xff0c;把性能测试的代码提交到github&#xff0c;在jenkins配置git下载性能测试的代码&#xff0c;配置运行脚本和测试报告&#xff0c;配置运行失败自动发邮件通知&#xff0c…

高项V4.高级PM.项目集set+项目组合portfolio+组织级OPM+量化项目管理+实践模型

PMI &#xff0c; ITSS 、CMMI 和PRINCE2 等为各类信息系统项目管理提供了最佳实践&#xff0c;井提供了对组织的项目管理能力进行持续改进和评估的方法。 第一部分 项目集--《项目集管理标准>> (第4 版) ---实现项目11>2的更大效益 由项目管理协会(PMI) 出版的《…

快速制作美容行业预约小程序

随着科技的不断进步&#xff0c;移动互联网的快速发展&#xff0c;小程序成为了很多行业迅速发展的利器。对于美容行业来说&#xff0c;一款美容预约小程序不仅可以方便用户进行预约&#xff0c;还可以提升美容店铺的服务质量和管理效率。下面&#xff0c;我们来介绍一下如何快…