springmvc访问不了jsp页面

文章内容输出来源:拉勾教育Java高薪训练营
本篇文章会对记录对SpringMVC基本的研究,将会分为下面几个部分进行阐述
- 快速创建SpringMVC
- SpringMVC绑定参数研究
- SpringMVC Rest风格参数绑定
- 前端AJAX请求
- SpringMVC拦截器
- SpringMVC上传文件
- SpringMVC 全局异常捕获
- SpringMVC 重定向参数传递
1、创建WebApp项目工程

补全目录建立完整

2、配置Pom文件
<?xml version="1.0" encoding="UTF-8"?>
3、配置前端控制器 Web.Xml
url-pattern 标签说明
- 方式一:带后缀,比如*.action *.do *.aaa 该种方式比较精确、方便
- 方式二:/ 不会拦截 .jsp
- 方式三:/* 拦截所有,包括.jsp
contextConfigLocation 配置说明:指定程序启动时,加载哪个配置文件
<!DOCTYPE web-app PUBLIC
4、新增控制器 DemoController
注解说明:
- @Controller 说明:这是一个控制器
- @RequestMapping 说明:路由映射
ModelAndView说明:
- ModelAndView 封装了数据和页面信息
- addObject方法 其实是向请求域中request.setAttribute("date",date);
- setViewName有两种方式
- 物理视图名 "/WEB-INFO/jsp/success.jsp"
- 逻辑视图名 success【需要在配置文件中,配置前缀后缀】
package
5、配置文件 springmvc.xml
标签说明:
- context:component-scan 指定程序去哪里扫描控制器
- InternalResourceViewResolver springmvc的视图解析器,配置好前缀后缀
- mvc:annotation-driven 系统自动选择最合适的 处理器映射器,处理器适配器
<?xml version="1.0" encoding="UTF-8"?>
6、新建JSP页面
<%
整体目录为:

7、运行测试
访问 http://localhost:8080/demo/handle01

刚刚的配置文件中,我们在Web.Xml里面,配置了url请求的拦截匹配规则

在项目中添加一个test.html

然后在浏览器中访问这个HTML,http://localhost:8080/test.html 会发现直接404

然后发现后台报错了:

那么这里是怎么回事呢?
其实我们在使用tomcat时,默认就有一个web.xml文件,我们自己写的web.xml就是继承于它的。

我们可以看到这里有,两个默认的映射配置

其中这个default映射器配置,配置成了<url-pattern>/</url-pattern>,默认就是拦截静态资源的

而Jsp映射器配置,拦截的是*.jsp

所以:我们这里配置成了 / 其实就是使用父级的配置,默认拦截所有静态资源,而jsp页面因为有别的映射器进行配置了,就直接交给tomcat了
解决方案一:
在springmvc.xml中,配置一个即可
<mvc:default-servlet-handler/>
原理:添加该标签配置之后,会在SpringMVC上下文中定义一个DefaultServletHttpRequestHandler对象,这个对象如同一个检查人员,对进入DispatcherServlet的url请求进行过滤筛查,如果发现是一个静态资源请求,那么会把请求转由web应用服务器(tomcat)默认的DefaultServlet来处理,如果不是静态资源请求,那么继续由,SpringMVC框架处理。
缺陷:不能放在Web-Info,Resource目录下
解决方案二:
如果当前test.html文件放在了resources目录下面,如果想要访问,则需要在springmvc.xml进行配置SpringMVC框架自己处理静态资源 http://localhost:8080/resources/test.html
- mapping:约定的静态资源的url规则
- location:指定的静态资源的存放位置
<mvc:resources

SpringMVC绑定参数研究

ModelMap,Model,Map的接收用法以及内部细节
/**
简单类,实体类,包装类的接收用法
/**
传入日期格式用法
http://localhost:8080/demo/handle06?birthday=2020-02-02
我们新建一个方法,直接传入日期数据类型
@RequestMapping
结果就返回400,客户端传入参数错误

后台显示的错误是:参数转换错误

解决方案:注册自定义类型转换器
1)新建一个类型转换器,出入字符串,转换成时间格式
public
2)springmvc.xml中 注册自定义类型转换器
<!--注册自定义类型转换器-->
3)配置使用自定义类型转换器
<!--
再次测试运行,发现值已经进来了

Spring Rest风格 参数绑定
准备好前端的工作页面
<div>
<h2>SpringMVC对Restful风格url的支持</h2>
<fieldset>
<p>测试用例:SpringMVC对Restful风格url的支持</p>
<a href="/demo/handle/15">rest_get测试</a>
<form method="post" action="/demo/handle">
<input type="text" name="username"/>
<input type="submit" value="提交rest_post请求"/>
</form>
<form method="post" action="/demo/handle/15/lisi">
<input type="hidden" name="_method" value="put"/>
<input type="submit" value="提交rest_put请求"/>
</form>
<form method="post" action="/demo/handle/15">
<input type="hidden" name="_method" value="delete"/>
<input type="submit" value="提交rest_delete请求"/>
</form>
</fieldset>
</div>
GET
1、get请求的Rest风格,如何从url中获取指定的参数?
@PathVariable 指定从URl路径中获取参数
- 路由形式为:/handle/{id}
- 注解用法为:@PathVariable("id")
/*
POST
2、post请求的Rest风格
前端请求页面,请求类型为Post,请求实体为username
<
后端中,针对这种情况无需特殊处理,直接在方法名上,声明即可
/*
但是在前端Post一个中文时,后端接收的参数却是乱码了,那么应该怎么办呢?


解决Post请求编码问题,配置Web.xml
1)配置一个过滤器,名字为encoding,类型为:CharacterEncodingFilter
<!--springmvc提供的针对post请求的编码过滤器-->
2)配置这个过滤器作用于所有的资源当中
3)再次测试,发现后端正确传入中文字符

PUT
下面来测试一下Put请求,我们在Html页面中,并没有Put参数类型,只有Post
<
后台控制器的这个接口,标记方法类型为Put类型
/*
点击提交rest_put请求,发现直接报错了

后端的控制台输出为:

说明如果使用Post去请求Put类型的方式,是不行的
解决方案:配置过滤器,转换当前的请求类型
1)在web.xml中,配置一个过滤器,类型为:HiddenHttpMethodFilter
<!--配置springmvc请求方式转换过滤器,会检查请求参数中是否有_method参数,如果有就按照指定的请求方式进行转换-->

为什么要配置这个类呢?HiddenHttpMethodFilter
因为浏览器当前仅支持GET和Post,如果想要转变成其他的类型,则需要在Post的时候,在请求体中,增加一个_method字段,标明当前想要请求的类型是什么
使用这个过滤器,目前仅仅支持PUT,DELETE,PATCH三种转换
Delete
同理,在提交删除方法的时候,增加一个_method的隐藏域
<
后端方法标记为Delete即可
/*
前端Ajax交互请求 【前端 -> 后端】
1)准备前端页面
<
2)在WEB-INF下面添加一个Js,根据之前的经验可以得知,这里是访问不到的,必须进行一定的配置才行

3)在SpringMVC中进行配置,指定Url中,获取JS相关的资源,应该去哪里找
<mvc:resources
4)准备好后端接收的方法
// 添加@ResponseBody之后,不再走视图解析器那个流程,而是等同于response直接输出数据
前端运行一下Ajax,发现报错了了


5)原来还差一步:配置Pom文件
<!--json数据交互所需jar,start-->
再来测试一下

前端Ajax交互请求 【后端-> 前端】
<
后端加一个注解@ResponseBody
@RequestMapping("/handle07")
// 添加@ResponseBody之后,不再走视图解析器那个流程,而是等同于response直接输出数据
public @ResponseBody User handle07(@RequestBody User user) {
// 业务逻辑处理,修改name为张三丰
user.setName("张三丰");
return user;
}
SpringMVC拦截器(一)
- Servlet 处理Request和Reponse相应
- 过滤器(Filter):作用在Servlet之前,如果配置为/** 可以对所有资源进行过滤处理
- 监听器(Listener):随着Web应用启动,初始化一次,知道web应用关闭
- 初始化工作
- 监听Web特定事件,如HttpSession,ServletRequest的创建和销毁
- 拦截器(Interceptor):是SpringMVC等表现层自己的,只会拦截控制器方法
- servlet,filter,listener是配置在web.xml中的
- interceptor是配置在springmvc.xml中

SpringMVC拦截器(二)
1)如修改pom文件,增加javax.servlet-api,添加拦截器时需要此包
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
2)先建立一个拦截器实现接口 org.springframework.web.servlet.HandlerInterceptor
public
3)配置拦截器
<mvc:interceptors>
4)测试

总结:
- 程序先执行preHandle()方法,如果该方法的返回值为true,则程序会继续向下执行处理器中的方法,否则将不再向下执行
- 在业务处理器(即控制器Controller类)处理完请求后,会执行postHandle()方法,然后会通过DispatcherServlet向客户端返回相应
- 在DispatcherServlet处理完请求后,才会执行afterCompletion方法。

SpringMVC拦截器(三)
在多个拦截器存在时,他们的执行顺序又是怎样的呢?
他们的preHandle()方法会按照配置文件中拦截器的配置顺序执行,而他们的PostHandler()方法和afterCompletion()方法则会按照配置顺序的反序执行

<mvc:interceptors>
SpringMVC 上传文件
1)配置Pom文件,文件上传jar包
<!--文件上传所需坐标-->
2)前端页面HTML
- method="post"
- enctype="multipart/form-data"
- type="file"
<
3)后端控制器
/**
尝试运行,直接报错


4)缺少重要一步:配置多元素解析器
<!--
再次测试:

SpringMVC异常捕获(一)
使用类型为:org.springframework.web.bind.annotation.ExceptionHandler的注解
@ExceptionHandler
当前注解声明在Demo控制器里面,所以只对当前的控制器有效
@Controller
SpringMVC异常捕获(二)
设置全局异常捕获
新建一个类:GlobalExceptionResolver
在类上标记为:@ControllerAdvice 针对Controller信息进行增强
类型为:org.springframework.web.bind.annotation.ControllerAdvice
// 可以让我们优雅的捕获所有Controller对象handler方法抛出的异常
SpringMVC异常捕获(三)
捕获异常,跳转到指定的JSP页面
@ControllerAdvice
新建一个error.jsp页面
<
SpringMVC 重定向参数传递
在控制器中,创建一个方法用于重定向
- 重定向的关键语句是:return"redirect:handle01";用于转发到哪个方法
- RedirectAttributes:用于存放数据,只能使用一次,在跳转到页面之后该属性销毁
/**
@ModelAttribute 放在参数列表中,表明我们从当前传递过来的上下文中,取出属性
/**
写在最后的总结
现在学习到了 第一阶段 开源框架源码剖析 ->模块三 -> 任务一。
在这个任务中,主要是对基础知识的回顾,相关知识点的讲解,为后续的深入探究打下基础,虽然对于大多数的小伙伴来说,这一章节没有什么深度,也没有源码解析,但是对于我来说,是至关重要的,因为之前并没有深入的去使用SpringMVC,很多的特性都是一知半解,要开发一个SpringMVC项目,都是磕磕碰碰的,当前任务帮我进行了知识点的扫盲。这个小章节,我觉得讲得挺好的,思路也是非常的清晰,我把上课讲的思路,沿途知识点,差不多都记录下来了,只要按照我的这个文档看一遍下来,相当于看完4个多小时视频。
之前也是看过B站的很多免费的视频,但是总是觉得有点啰嗦,扯了半天还是讲解一些基本的东西,在拉钩Java高薪训练营中根本就没有一句废话。每一分钟都是满满的干货,只要投入时间学习,就一定能有收获。这个训练营的学习强度相当的大,要求最短的时间学习最多的东西,我是2020年7月21号开班的,到现在才一个月不到,已经学完了Mybatis,Spring,到现在的SpringMVC开始部分,感觉自己的实力蹭蹭蹭的往上长。因为学习速度很快,如果不做笔记的话,很容易就忘记了,所以要边看视频(20%),边做实验(30%),还得边输出笔记(30%),回顾总结(20%),这样才能记得更加牢固。
作者:weixin_39756235
来源链接:https://blog.csdn.net/weixin_39756235/article/details/110204195