11、统一处理异常、处理静态资源访问、项目中的绝对地址跟相对地址问题
一、项目中的相对地址和绝对地址问题
在jsp,html中使用的地址,都是在前端页面中的地址,都是相对地址
地址分类:
- 1.绝对地址 , 带有协议名称的是绝对地址, http://www.baidu.com , ftp://202.122.23.1
- 2.相对地址, 没有协议开头的, 例如 user/some.do , /user/some.do、相对地址不能独立使用,必须有一个参考地址。 通过参考地址+相对地址本身才能指定资源。
- 3.参考地址
1)在你的页面中的,访问地址不加"/"
访问的是: http://localhost:8080/ch06_path/index.jsp
路径: http://localhost:8080/ch06_path/
资源: index.jsp
index.jsp发起user/some.do请求,访问地址变为http://localhost:8080/ch06_path/user/some.do
当你的地址 没有斜杠开头,例如 user/some.do , 当你点击链接时, 访问地址是当前页面的地址加上链接的地址。http://localhost:8080/ch06_path/ + user/some.do
-------------------------------------------------------------
index.jsp 访问 user/some.do 返回后现在的地址: http://localhost:8080/ch06_path/user/some.do
http://localhost:8080/ch06_path/user/some.do
路径: http://localhost:8080/ch06_path/user/
资源: some.do
在index.jsp在 user/some.do ,就变为http://localhost:8080/ch06_path/user/user/some.do
解决方案:
1.加入${pageContext.request.contextPath}
2.加入一个base标签, 是html语言中的标签。 表示当前页面中访问地址的基地址。
你的页面中所有 没有“/”开头的地址,都是以base标签中的地址为参考地址
使用base中的地址 + user/some.do 组成访问地址
2)在你的页面中的,访问地址加 "/"
访问的是: http://localhost:8080/ch06_path/index.jsp
路径: http://localhost:8080/ch06_path/
资源: index.jsp
点击 /user/some.do, 访问地址变为 http://localhost:8080/user/some.do
参考地址是 你的服务器地址, 也就是 http://localhost:8080
如果你的资源不能访问: 加入${pageContext.request.contextPath}
<a href="${pageContext.request.contextPath}/user/some.do">发起user/some.do的get请求</a>
二、处理静态资源访问的两种方法:
说明:在url-pattern中配置的访问路径如果是“/”就需要处理静态资源访问问题、它不会匹配到.jsp等静态资源,只能够匹配到框架的请求,比如“/some”动态资源的请求。
应用:如果想要使用js、jquery……的功能,就必须配置项目能够正确的访问到静态资源!
第一种:在spring让servlet去处理静态资源
告诉mvc处理静态资源的事情交给servlet去做:<mvc:defaule-servlet-handler>
添加注解驱动:<mvc:annotation-driven>
原理:给程序内存中增加一个处理器对象,DefaultHtppRequestHandler,让这个对象处理静态资源的访问!
第二种:spring自己去处理静态资源
在Spring3.0版本后,Spring定义了专门用于处理静态资源访问请求的处理器.
ResourceHttpRequestHandler。并且添加了<mvc:resources/>标签,专门用于解决静态资源无法访问问题。需要在springmvc配置文件中添加如下形式的配置:
上面的可以将html、css、js文件都放在统一文件夹“static”目录下。
<mvc:resurces mapping=”/static/**” location=”/static/”>
三、统一处理异常
步骤:
- 1.新建maven web项目
- 2.加入依赖
- 3.新建一个自定义异常类 MyUserException , 再定义它的子类NameException ,AgeException
- 4.在controller抛出NameException , AgeException
- 5.创建一个普通类,作用全局异常处理类
- 1)在类的上面加入@ControllerAdvice
- 2) 在类中定义方法,方法的上面加入@ExceptionHandler
- 6.创建处理异常的视图页面
- 7.创建springmvc的配置文件
- 1)组件扫描器 ,扫描@Controller注解
- 2)组件扫描器,扫描@ControllerAdvice所在的包名
- 3)声明注解驱动
web.xml配置
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <servlet> <servlet-name>myweb</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!--自定义springmvc读取的配置文件的位置--> <init-param> <!--springmvc的配置文件的位置的属性--> <param-name>contextConfigLocation</param-name> <!--指定自定义文件的位置--> <param-value>classpath:springmvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>myweb</servlet-name> <!-- 使用框架的时候, url-pattern可以使用两种值 1. 使用扩展名方式, 语法 *.xxxx , xxxx是自定义的扩展名。 常用的方式 *.do, *.action, *.mvc等等 不能使用 *.jsp http://localhost:8080/myweb/some.do http://localhost:8080/myweb/other.do 2.使用斜杠 "/" --> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
springmvc配置文件:springmvc.xml
<?xml version="1.0" encoding="UTF-8"?> <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 https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!--声明组件扫描器--> <context:component-scan base-package="com.zhixi.controller"/> <!--注解驱动--> <mvc:annotation-driven/> <!--处理需要的两步--> <context:component-scan base-package="com.zhixi.handler"/> <!--声明 springmvc框架中的视图解析器, 帮助开发人员设置视图文件的路径--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!--前缀:视图文件的路径--> <property name="prefix" value="/WEB-INF/jsp/"/> <!--后缀:视图文件的扩展名--> <property name="suffix" value=".jsp"/> </bean> </beans>
定义异常类:exception/
MyUserException:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.zhixi.exception; 2 3 public class MyUserException extends Exception { 4 public MyUserException() { 5 super(); 6 } 7 8 public MyUserException(String message) { 9 super(message); 10 } 11 }
AgeException:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package com.zhixi.exception; //当年龄有问题时,抛出的异常 public class AgeException extends MyUserException { public AgeException() { super(); } public AgeException(String message) { super(message); } }
NameException:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package com.zhixi.exception; //表示当用户的姓名有异常,抛出NameException public class NameException extends MyUserException { public NameException() { super(); } public NameException(String message) { super(message); } }
controller进行异常的抛出:controller/
MyController:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package com.zhixi.controller; import com.zhixi.exception.AgeException; import com.zhixi.exception.MyUserException; import com.zhixi.exception.NameException; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; /** * @RequestMapping: value : 所有请求地址的公共部分,叫做模块名称 * 位置: 放在类的上面 */ @Controller public class MyController { @RequestMapping(value = "/some") public String doSome(String name, Integer age, Model model) throws MyUserException { //根据请求参数抛出异常 if (!"zs".equals(name)) { throw new NameException("姓名不正确!!!"); } if (age == null || age > 80) { throw new AgeException("年龄比较大!!!"); } model.addAttribute("myname", name); model.addAttribute("myage", age); return "show"; } }
handler负责处理异常:handler/
GlobalExceptionHandler:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package com.zhixi.handler; import com.zhixi.exception.AgeException; import com.zhixi.exception.NameException; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RequestMapping; /** * @ControllerAdvice : 控制器增强(也就是说给控制器类增加功能--异常处理功能) * 位置:在类的上面。 * 特点:必须让框架知道这个注解所在的包名,需要在springmvc配置文件声明组件扫描器。 * 指定@ControllerAdvice所在的包名 */ @ControllerAdvice public class GlobalExceptionHandler { //定义方法,处理发生的异常 /* 处理异常的方法和控制器方法的定义一样, 可以有多个参数,可以有ModelAndView, String, void,对象类型的返回值 形参:Exception,表示Controller中抛出的异常对象。 通过形参可以获取发生的异常信息。 @ExceptionHandler(异常的class):表示异常的类型,当发生此类型异常时, 由当前方法处理 */ @RequestMapping @ExceptionHandler(value = NameException.class) public String doNameException(Exception exception, Model model){ //处理NameException的异常。 /* 异常发生处理逻辑: 1.需要把异常记录下来, 记录到数据库,日志文件。 记录日志发生的时间,哪个方法发生的,异常错误内容。 2.发送通知,把异常的信息通过邮件,短信,微信发送给相关人员。 3.给用户友好的提示。 */ model.addAttribute("msg","姓名必须是zs,其它用户不能访问"); model.addAttribute("ex",exception); return "nameError"; } //处理AgeException @RequestMapping @ExceptionHandler(value = AgeException.class) public String doAgeException(Exception exception,Model model){ //处理AgeException的异常。 /* 异常发生处理逻辑: 1.需要把异常记录下来, 记录到数据库,日志文件。 记录日志发生的时间,哪个方法发生的,异常错误内容。 2.发送通知,把异常的信息通过邮件,短信,微信发送给相关人员。 3.给用户友好的提示。 */ model.addAttribute("msg","你的年龄不能大于80"); model.addAttribute("ex",exception); return "ageError"; } //处理其它异常, NameException, AgeException以外,不知类型的异常 @ExceptionHandler public String doOtherException(Exception exception,Model model){ //处理其它异常 model.addAttribute("msg","你的年龄不能大于80"); model.addAttribute("ex",exception); return "defaultError"; } }
视图层jsp:/WEB-INF/jsp/
ageError.jsp(年龄异常)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> ageError.jsp <br/> 提示信息:${msg} <br/> 系统异常消息:${ex.message} </body> </html>
nameError(名字异常)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> nameError.jsp <br/> 提示信息:${msg} <br/> 系统异常消息:${ex.message} </body> </html>
defaultError(其他异常)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> defaultError.jsp <br/> 提示信息:${msg} <br/> 系统异常消息:${ex.message} </body> </html>
show.jsp(获取数据)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h3>/WEB-INF/view/show.jsp从request作用域获取数据</h3><br/> <h3>myname数据:${myname}</h3><br/> <h3>myage数据:${myage}</h3> </body> </html>