msbSpringMVC-1

SpringMVC介绍

springmvc不是一个单独的框架,是spring框架的其中一个模块。

原始mvc处理过程

Model指和数据和行为,包括dao层和service层。

View是页面。Controller是控制器负责与前端交互,controller层。

最经典的mvc就是javabean+jsp+servlet,这种模式是tomcat容器里有许多个servlet,还有一个wen.xml,当前端有请求过来,就会根据web.xml中的映射,找到请求路径对应的servlet,servlet执行完自己的逻辑把结果响应给前端。

SpringMVC处理过程

springmvc采取的模式是,tomcat容器中只有一个servlet,就是图中的FrontController,是一个DispatcherServlet类对象,所有请求都送到DispatcherServlet,然后它再根据路径找不同的Controller处理,这样一来Controller就可以自己定义,不需要继承HttpServlet,实现了解藕。

DispatcherServlet从Controller那里拿到处理的结果和view的名称,再去找到对应的View,跟数据融合返回一个完整的页面视图给前端。

PS:转发和重定向

转发是客户端请求aaa路径,服务端收到请求后,可能在服务端内部进行多次跳转,跳转了多个处理器终于处理完了,把结果响应给客户端。表现出来就是路径不变。

重定向是客户端请求aaa路径,服务端收到请求后,返回了bbb的请求

配置文件+注解

准备

新建EE项目,pom文件导包:

导了这两个就已经包括了spring-context了。

web.xml文件

配置前端控制器:唯一的servlet:DispatcherServlet:

servlet-name:标识(随便起),

servlet-class:对应的Servlet类,

url-pattern:这个servlet要接收什么请求。

设置初始化参数,指定默认的springmvc配置文件路径:

spring.xml文件

指定注解的扫描路径:

controller

视图

 

运行

如果报错:实例化Servlet类[....DispatcherServlet]异常,是找不到这个类:

配置试图解析器,指定前缀后缀:

springmvc.xml:

视图:

注意

1、@RequestMapping用来匹配当前方法要处理的请求,其中/可写可不写,一般推荐写。

2、可以不手动在web.xml中指定springmvc.xml的路径,直接放到webapp/WEB-INF/目录下,命名必须为(DispatcherServlet的servlet-name)-servlet.xml。

3、springmvc处理过程:

        浏览器发送请求http://localhost:8080/msbssm/hello,交给tomcat容器,

        web.xml中配置了DispatcherServlet类,此时会由当前的DispatcherServlet来接受请求,

        接受请求之后扫描注解@Controller,到controller中寻找@RequestMapping匹配的方法,

        执行方法逻辑,返回一个前端页面名称,由视图处理器根据名称映射到对应的jsp页面路径,

        DispatcherServlet拿到路径之后把文件返回给浏览器。

4、/和/*的区别

        都是用来匹配所有请求,/放行jsp文件,/*啥也不放行,通通拦截。

        也就是说,用/的话除了jsp文件都经过DispatcherServlet,都要去匹配RequestMapping,用/的话全部请求都经过DispatcherServlet,都要去匹配RequestMapping。

        为什么:因为项目web.xml要继承tomcat的web.xml,后者先配置了/匹配DefaultServlet,又配置了jsp文件匹配JspServlet,前者配置了/匹配DispatcherServlet,覆盖了父web.xml,最后得到web.xml是jsp文件匹配JspServlet,/匹配DispatcherServlet。

静态资源放行

配置/虽然能放行jsp文件,但是不能放行html和其他静态文件:

请求html文件也会去匹配@RequestMapping,而我们没有对应的controller,匹配不到所以报错。

只需要在sprignmvc.xml中加一句:

图片也可以请求:

貌似不用写项目虚拟路径也行:

不行:如果项目虚拟路径是/,那/img/bg.png的确会被认为是相对于根路径下的,而如果项目虚拟路径是/aaa,那/img/bg.png会被认为是相对于当前页面路径下的,如果页面路径/aaa/index.jsp,图片路径/img/ccc.jpg,那么在页面中请求该图片,写/img/ccc.jpg,那么请求的是/aaa/img/ccc.jpg

如果访问不到,要检查发布路径中有没有该资源,没有就复制过去:

@RequestMapping注意

1、类上配置该注解,表示在所有方法的注解上加一段路径。

2、参数:

                

不写参数名默认是value。

Controller获取数据

获取路径中的参数

与controller方法的参数同名就能获取到:

不同名也可以获取到:

RequestParam其他属性:

value和name属性是一样的;required表示是否必须的参数;defaultValue默认值;另外方法里获取参数跟路径中参数的顺序无关,只要有就能获取。

捕获请求头中的信息

@RequestHeader的value要按这个写:

获取Cookie里面的信息

之前Servlet的方式: 

controller里用servlet原生对象

捕获路径中的值作为参数

注意:如果路径中捕获的名称和方法参数名称相同,@PathVariable就不需要写("名称"),但最好写上。

这种方式适合用来做REST风格。

REST风格

原始:

增:.../user/save,请求体传数据,

删:.../user/delete?id=1,

改:.../user/update?id=1,请求体传数据,

查:.../user/query?id=1。

rest:

增:.../user,post请求方式,

删:.../user/1,delete请求方式,1是id,

改:.../user/1,put请求方式,

查:.../user/1,get请求方式。

怎样实现:通过一个过滤器Filter,过滤所有请求,提交表单时根据隐藏域的_method变量的值来变更请求方式:

前端表单:

只不过jsp只能通过get/post请求,put和delete可能需要转发/重定向一下。

delete和put请求通过Filter过滤,post正常通过表单提交,get一般通过a标签,避免在url中出现表单信息。

封装pojo类对象

controller方法参数是pojxo类对象,且前端传来的参数和pojo类属性名相同,就能自动封装。

原理:反射调用set、get方法。

封装带有内部对象的对象

只需要在form表单的上修改一下name:

把内部对象的属性对应的字段name,改成内部对象名.属性名。

@ModelAttribute注解用法

注意到上面的username是null,因为我们不允许用户修改username。

这个场景我们应该先查出用户的完整信息,回写到前端,前端更新了允许更新的数据后,提交到后端的是完整的用户数据。也就是说,在方法里传入一个参数User,他会new一个User,再把前端返回的数据赋值上,现在我们需要提前封装一个数据库里的user,根据前端修改对这个User进行修改。

只需要加一个@ModelAttribute,他会先于pojoPlus这个方法执行,用于初始化一个User:

 这回,username不是null了:

过滤器设置解码方式

web.xml:

过滤器过滤的请求不是拦截丢掉,而是识别到然后对他附加一些功能。

打开页面,请求了一次,为什么会执行两遍encoding filter:请求图标也会经过过滤器。

注意:如果设置后依然乱码,确认以下两点:

web.xml中设置编码的Filter要放在第一个;tomcat的web.xml文件要添加URIEncoging=utf-8

使用springmvc提供的编码Filter:(也要放在第一个)

controller向jsp中回写数据

四种回写方式

前三种是一样的,有一子类,继承了前三个类,参数传入三个类都是会转换成子类BindingAwareModelMap,因此效果一样。

第四种,是把上面说的子类放到ModelAndView中。

四种方式都是把数据写到request域中,再在jsp中使用。

controller向session中写数据

在类名上加注解@SessionAttributes,属性名不写的话默认是value,value是字符串或字符串数组,表示要向session中写的变量名:

注意是Attributes加s。除了value还有个types,表示这个类型的数据都写入session,value和types不是联合判断,是互相独立的。 

方法中,用Model向request域写入变量:

@SessionAttributes工作原理是,把写入request域中的数据顺便也写到session域一份。 

运行结果:

写入request中并且@SessionAttributes标注了的变量,会写到session中;写入request中但没在@SessionAttributes标注的变量,会不写到session中。

转发和重定向

转发forward

只需要在return的时候添加一个forward:转向另一个controller:

或最后一个return不用转发直接return字符串

前端的效果是url不变:

重定向redirect

和转发的区别只在于把forward改成redirect。

前端的效果是url会变:

 

数据合法性校验

导包:

需要验证的属性,加注解:

controller方法,参数pojo类对象前加@Valid注解,加一个BindingResult参数,如果有error,就把字段名和错误信息存到map里,最后把map加到reqyest域中:

前端显示错误信息:

请求form表单页面:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值