文章整理自孙哥说SpringMVC,相关课程联系孙哥学习谢谢。
- 第一章:编码开发
- 一:思路分析
- 二:SpringMVC程序编码
- 三:控制器提供多个服务方法
- 四:注意事项
- 第二章:细节分析
- 一:控制器创建次数
- 二:@RequestMapping注解
- 1:路径分隔符/可省略
- 2:一个控制器方法上指定多个注解
- 3:类上的@RequestMapping
- 第三章:请求方式
- 一:回顾请求方式
- 二:Post和Get请求的区别
- 1:两种请求提交数据的区别
- 2:两种请求发起方式的区别
- 三:@RequestMapping限定用户请求方式
- 1:默认支持所有请求方式
- 2:限定固定请求方式
- 3:同时限定多种请求方式
- 4:发起不支持的请求方式
- 三:@RequestMapping限定其他请求方式
- 1:Http协议提供了其他请求方式
- 2:@RequestMapping也支持其他请求方式
- 3:浏览器对于其他请求方式的支持
- 4:其他请求方式的响应形式
第一章:编码开发
一:思路分析
作为SpringMVC来讲他的核心就是控制器。控制器在之前我们了解过Servlet,我们现在通过Servlet的开发推导出SringMVC的开发。
我们编写一个类,这个类需要extends HttpServlet继承之后,我们重写其中的service方法,方法的参数时request和response。然后我们在其中进行接收请求参数、业务处理、页面跳转等操作。这就是我们需要编码的细节。
代码写完之后,我们需要在web.xml当中配置一个servlet标签:
servlet-name:当中起一个名字,唯一就行。
servlet-class:带包带类,实际上就是类的限定名称。
与之对应的我们还需要配置一个servlet-mapping标签,作用就是对外暴露我们这个Servlet对应的URL。
servlet-name:跟上边保持一致
url-pattern:一个URL
http://localhost:8989/basic/firstServlet
这是一个请求的完成的URL,我们在地址栏当中输入这个路径之后,基于ip+端口+应用名。后边的/firstServlet找到对应的url-pattern,进而找到对应的servlet-name进而找到对应的servlet-class。这就是我们servlet开发的开发方式。
对于SpringMVC来讲,他所提供的控制器就是为了替换原生Servlet的,他们在开发过程中主题思想是保持一致的。SpringMVC的控制器一定会简化现有的MVC的开发的。
SpringMVC的控制器在开发过程当中,是不需要继承父类或者实现接口这样的要求,只需要在类上边添加一个@Controller注解(上述图右)注解可以起到接口这样约定性的作用,继承父类或者实现接口这样的方式被注解取代掉了。这就是二者在开发类上边的区别关系。
在Servlet当中我们只能写Service方法,但是在SpringMVC当中对应的名字,他的方法名字是可以随便写的。对于SpringMVC的方法的返回值不再是void了,而是Spring就是跳转路径。
作为SpringMVC来中的Controller来将他如何指定他的URL呢,只需要在方法上加一个注解@RequestMapping即可。这个注解当中的路径就是他对应的URI用户在通过地址栏访问的时候就是在方法上写的地址的内容。
这个和Basic是一致的。举例来讲:Http:localhost:8989/spring-mvc1/firstController即可。
基本开发流程:
1:开发一个类在类上加Controller注解
2:提供一个控制器方法。参数是:HttpServletRequest,HttpServletResponse,返回值是String的,同事加入@RequestMapping注解定义请求路径。
3:在控制方法中,完成核心开发功能,把对应的JSP页面的路径作为返回值返回。
二:SpringMVC程序编码
在我们的IDEA当中我把相关的内容关掉。
后端代码:
@Controller
public class FirstController {
public FirstController() {
System.out.println("FirstController.FirstController");
}
@RequestMapping("/first")
//方位这个控制器方法的路径是first
public String first(HttpServletRequest request, HttpServletResponse response){
System.out.println("FirstController.first");
//跳转到根下边的这个jsp
return "/result.jsp";
}
}
JSP代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Result</title>
</head>
<body>
<h1>this is result jsp</h1>
</body>
</html>
浏览器访问地址:
http://localhost:8989/basic/first
注意:必须要进行@Controller注解的扫描。
三:控制器提供多个服务方法
作为控制器来讲,Servlet当中是不允许一个控制器提供多个服务方法的。在Servlet当中一个控制器只能提供一个方法。这是因为在Servlet当中必须实现接口规定的service(HttpServletRequest,HttpServletResponse)方法,一个类中只能实现一次,所以一个类当中只能有一个服务方法。在Servlet想要提供服务就之能写Servlet接口提供的规定。所以,我们基于Servlet只能基于以下的代码结构:
作为SpringMVC的控制器一个类当红中可以提供多个对外服务的方法的。究其原因是因为SpringMVC控制器当中的服务方法对于方法名是没有任何要求的:
@Controller
public class FirstController {
public FirstController() {
System.out.println("FirstController.FirstController");
}
@RequestMapping("/first")
public String first(HttpServletRequest request, HttpServletResponse response){
System.out.println("FirstController.first");
return "/result.jsp";
}
// http://localhost:8989/basic/suns/second
@RequestMapping(value="suns/second")
public String second(HttpServletRequest request,HttpServletResponse response){
System.out.println("FirstController.second");
return "/result.jsp";
}
}
我们写Value等于这种形式没啥区别,如果注解当中只写一个属性,且属性为value,则value可省略。
四:注意事项
SpringMVC开发过程中习惯上把控制器称之为Controller,SpringMVC内部也把开发的控制器也叫做Handler因为后续我们查看源码的过程当中经常看到Handler…等等各种各样的说法。
第二章:细节分析
一:控制器创建次数
作为Servlet来讲,他对应的控制器被创建的次数是几次呢?一中Servlet只会被Tomcat创建一次。请求过来之后,Tomcat只会创建一次这个对象。所以我们常说:Servlet是单实例的(注意这个不是单例设计模式)
SpringMVC的控制器被Spring创建的次数是尊询Spring的规则,可以只创建一次,也可以创建多次。默认可以创建一次,也可以去创建多次。如果想创建多次,我们可以加一个@Scope注解来设定。如果是@Scope是prototype的话,那么一次请求就会对应创建一个Controller对象。
默认SpringMVC的Controller只会被创建一次,存在线程安全的问题。如果这里边有成员变量,并且这里边成员变量是线程不安全的话,就会有问题。
二:@RequestMapping注解
该注解核心作用就是为控制器方法提供外部访问的URI路径。服务器就可以将用户URL当中的URL同注解当中的路径进行匹配来让客户访问对应的服务。这个工作是由RequestMappingHandlerMapping来处理的,对方法上添加这个注解的服务进行一一扫描,来进行服务注册。
1:路径分隔符/可省略
SpringMVC当中“/first”当中的/是可以省略的。如果是多级路径,第一个/是可以省略的。
2:一个控制器方法上指定多个注解
@Controller
//@Scope("singleton")
//@Scope("prototype")
public class FirstController {
public FirstController() {
System.out.println("FirstController.FirstController");
}
//@RequestMapping("/first")
//@RequestMapping("first")
@RequestMapping(value = {"/first","/third"})
public String first(HttpServletRequest request, HttpServletResponse response){
System.out.println("FirstController.first");
return "/result.jsp";
}
// http://localhost:8989/basic/suns/second
@RequestMapping(value="suns/second")
public String second(HttpServletRequest request,HttpServletResponse response){
System.out.println("FirstController.second");
return "/result.jsp";
}
}
3:类上的@RequestMapping
可以在类上加注解,这就让URL上多加一个层级而已。
http://localhost:8989/basid/user/addUser
http://localhost:8989/basid/user/deteleUser
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/addUser")
public String addUser() {
System.out.println("UserController.addUser");
return "/result.jsp";
}
@RequestMapping("/deleteUser")
public String deleteUser() {
System.out.println("UserController.deleteUser");
return "/result.jsp";
}
}
类上@RequestMapping设计意图:
为什么SpringMVC设计的过程当中让我们在类上加这样的一个注解呢?
为了统一服务,我们在使用的过程中,会把一组相关的操作放到同一个控制器当中。用户Controller负责用户的事,账户Controller负责账户的事。采用了这样的设计之后,用户的URL就会很规范,在访问的路径上也能体现出模块化。
第三章:请求方式
一:回顾请求方式
所谓的请求方式就是JavaWeb当中讲的get和post请求等等。
二:Post和Get请求的区别
1:两种请求提交数据的区别
1:Get请求通过请求行地址栏提交数据,数据明文提交(QueryString),不安全提交的数据量小不能超过2048个字节(2MB),这是上线,具体多少还得看
2:Post请求:通过请求体提交数据,密文提交,这里不是说会加密,而是说一般用户不可见,相对安全,理论上是没有大小限制的。
1:GET请求:通过请求行(地址栏)提交数据(QueryString),明文数据提交,不安全,提交的数据量小(不能超过2048字节),当然我们所说的2048字节是上限值,最终多少还得看浏览器的实现。
http://localhost:8989/basic/user/queryuser?name=sunshuai&password=123456
上述就是使用Get请求提交的一个形式,我们会在URL后边打一个问号,问号后边的都是QueryString这个也都是我们提交的明文数据。
2:POST请求:通过请求体提交数据,密文提交(不是加密,指的是一般用户不可见),相对安全,这个是走请求体提交数据,提交数据量大(理论上没有限制)
原来我们解决中文字符集乱码的问题的时候GET和Post解决方式是不一致的,因为提交数据的位置不一样。
2:两种请求发起方式的区别
三:@RequestMapping限定用户请求方式
1:默认支持所有请求方式
默认情况下:@RequestMapping注解,接受所有请求方式的访问 (Post,Get,…)
2:限定固定请求方式
通过@RequestMapping注解可以限定,某个控制器方法只接受特定的请求方式
@RequestMapping(method={RequestMethod.POST})
public String xxx(HttpServletRequest,HttpServletResponse)
@RequestMapping(method={RequestMethod.GET))
public String xxx(HttpServletRequest,HttpServletResponse)
3:同时限定多种请求方式
@RequestMapping注解可以同时限定多种请求方式的访问
@RequestMapping(method={RequestMethod.GET,RequestMethod.POST))
public String xxx(HttpServletRequest,HttpServletResponse)
4:发起不支持的请求方式
当用户发起了@RequestMapping不支持的请求操作
SpringMVC在服务器端抛出一个405错误 Method Not Allowed
三:@RequestMapping限定其他请求方式
1:Http协议提供了其他请求方式
除常规的POST,GET请求外Http协议还提供了其他的请求方式PUT、DELETE、OPTIONS
2:@RequestMapping也支持其他请求方式
@RequestMapping注解,默认情况下也支持其他请求方式的访问,同时也可以根据需要进行限定@RequestMapping(method={RequestMethod.DELETE)
public String xxx(HttpServletRequest,HttpServletResponse)
3:浏览器对于其他请求方式的支持
除Post,Get这2种请求方式外,其他的请求方式浏览器支持的不好,可以使用专属工具或者库进行测试
4:其他请求方式的响应形式
其他的请求方式,大多数不支持响应视图技术 (JSP,Thymeleaf),只能返回简单字符串或者JSON数据。