一:SpringMVC执行流程
1:一共有四大组件
中央管理器
处理器映射器
处理器适配器
视图解析器
2:描述流程
- 用户向服务端发送一次请求,这个请求会先到中央控制器DispatcherServlet
- DispatcherServlet接收到请求后会调用HandlerMapping处理器映射器。由此得知,该请求该由哪个Controller来处理(并未调用Controller,只是得知)。
- DispatcherServlet调用HandlerAdapter处理器适配器,告诉处理器适配器应该要去执行哪个Controller。
- HandlerAdapter处理器适配器去执行Controller并得到ModelAndView(数据和视图),并层层返回给DispatcherServlet。
- DispatcherServlet将ModelAndView交给ViewReslover视图解析器解析,返回真正的视图。
- DispatcherServlet将模型数据填充到视图
- DispatcherServlet将结果响应给用户
3:图片描述
二:SpringMVC搭建
1:引入jar包
<!-- spring web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.2.4.RELEASE</version>
</dependency>
<!-- spring mvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.4.RELEASE</version>
</dependency>
<!-- web servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<!-- 添加json 依赖jar包 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.10.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.10.0</version>
</dependency>
2:配置web.xml
<display-name>Archetype Created Web Application</display-name>
<!-- 过滤顺序:谁的写在上面,谁先被过滤 -->
<filter>
<description>自带的编码过滤器,设置一下即可[这个标签只是注释作用]</description>
<filter-name>FilterTest01</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>FilterTest01</filter-name>
<url-pattern>/*</url-pattern> <!-- 过滤所有 -->
</filter-mapping>
<!-- 配置MVC的DispatcherServlet中央控制器 -->
<servlet>
<servlet-name>springMvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 表示是在配置前端控制器时候,初始化加载spring.xml,classpath表示在resoutces目录下,如果不写,默认在WEB-INF目录下【并且文件名为spring-servlet.xml】-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml</param-value>
</init-param>
<!-- 表示启动容器时初始化该Servlet -->
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 配置MVC需要拦截的路径-->
<servlet-mapping>
<servlet-name>springMvc</servlet-name>
<!-- 这是拦截请求, "/"代表拦截所有请求,"*.do"拦截所有.do请求 -->
<url-pattern>/</url-pattern>
<!-- <url-pattern>*.do</url-pattern>-->
</servlet-mapping>
3:配置spring.xml
路径:resources/spring.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">
<!-- 开启扫描器,IOC控制对象创建【可以使用@Repository...注解】,这里路径设置为整个项目所在的路径 -->
<context:component-scan base-package="com.wangyuan"/>
<!-- 开启注解驱动-->
<mvc:annotation-driven/>
<!-- 使用默认的 Servlet 来响应静态文件:表示web.xml中配置的springMvc拦截器,不拦截静态资源 -->
<mvc:default-servlet-handler/>
<!-- mvc 请求映射 处理器与适配器配置 -->
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter" />
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
</mvc:message-converters>
</mvc:annotation-driven>
<!-- 配置视图解析器:返回的页面名称,默认拼筹为: /XXX.jsp -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
<!-- 前缀:在WEB-INF目录下的jsp目录下 -->
<property name="prefix" value="/"/>
<!-- 后缀:以.jsp结尾的资源 -->
<property name="suffix" value=".jsp"/>
</bean>
</beans>
4:编写一个jsp
路径webapp/hello.jsp
<html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<body>
<h2>Hello Message</h2>
</body>
</html>
5:编写测试类
@Controller
public class HelloController {
// 测试MVC环境搭建
@RequestMapping("/hello.do")
public String sayHello(){
return "hello";
}
}
6:启动项目测试
在浏览器输入:http://localhost:8080/mvc【这是你的项目名称】/hello.do
完成搭建,恭喜你,如有问题请留言
三:SpringMVC映射URL,设置访问路径
通过注解设置@RequestMapping
1:映射单个url
路径开头是否加 斜杠"/" 均可【@RequestMapping("/请求路径") 与 @RequestMapping(“请求路径”)均可】
·建议加上·
@Controller
public class HelloController {
@RequestMapping("/hello.do")
public String sayHello(){
return "hello";
}
}
2:映射多个rul路径
// 设置多个访问路径
@RequestMapping({"/more1.do","/more2.do"})
public String sayMoreUrl(){
return "hello";
}
3:设置在类上设置访问路径
//访问路径:http://IP:端口/项目名/wangyuan/more1.do
@Controller
//设置父级访问路径,在访问时需要加 /wangyuan
@RequestMapping(value = "/wangyuan")
public class ControllerDemo {
@RequestMapping({"/more1.do","/more2.do"})
public String sayMoreUrl(){
return "hello";
}
}
4:设置URL请求方式
//只能POST方式访问
@RequestMapping(value = "/test",method = RequestMethod.POST)
//只能GET方式访问
@RequestMapping(value = "/test",method = RequestMethod.GET)
5:通过参数设置URL访问路径
通过params 参数设置
// 路径为test1,参数包含parmas01,进这里
@RequestMapping(value = "/test1.do",params = {"parmas01"})
@ResponseBody
public void getParmas01(String parmas01){
System.out.println("getParmas01"+parmas01);
}
// 路径为test1,参数不包含parmas01,进这里
@RequestMapping(value = "/test1.do",params = {"!parmas01"})
@ResponseBody
public void getParmas02(String parmas01){
System.out.println("getParmas02"+parmas01);
}
四:参数绑定
0:@RequestParam
设置参数的默认值 defaultValue
设置参数的参数名(别名) name
1:正常数据类型绑定
//基本数据类型绑定,直接获取参数
@RequestMapping(value = "/test02")
public ModelAndView test02(int age,double money,String name){
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("age",age);
modelAndView.addObject("money",money);
modelAndView.addObject("name",name);
modelAndView.setViewName("controllerDemo");
return modelAndView;
}
2:数组类型数据绑定
//传参格式:arrs=1&arrs=2&arrs=3
@RequestMapping("/test03")
public void test03(String[] arrs){
for(String arr: arrs){
System.out.println(arr);
}
}
3:javaBean类型数据绑定
javaBean
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {
private Integer age;
private String name;
}
//http://localhost:8080/mvc/wangyuan/test3.do?age=18&name=张三
//传参格式:参数名和javaBean字段名一致
@RequestMapping("/test04")
public void test03(User user){
System.out.println(user);
}
4:集合类型数据绑定【list,set,map】
实体类
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {
private Integer age;
private String name;
private List<String> lists;
private Set<String> sets;
private Map<Integer,String> maps;
}
前台提交
<form action="/mvc/wangyuan/test05" method="post">
<input name="lists[0]" value="123456" />
<input name="lists[1]" value="4576" />
<input name="sets" value="sets01" />
<input name="sets" value="sets02" />
<input name="maps[0]" value="maps01" />
<input name="maps[1]" value="maps02" />
<button type="submit"> 提交</button>
</form>
后台接收
//传递list,set,map
@RequestMapping("/test05")
@ResponseBody
public User test05(User user){
System.out.println("----------LIST-----=--");
user.getLists().forEach(System.out::println);
System.out.println("----------SET--------");
user.getSets().forEach(System.out::println);
System.out.println("----------MAP-------");
Set<Integer> integers = user.getMaps().keySet();
integers.forEach(System.out::println);
Collection<String> values = user.getMaps().values();
values.forEach(System.out::println);
return user;
}
五:重定向和请求转发
1:重定向
关键字:redirect:目标路径
//重定向
@RequestMapping("/test06")
public ModelAndView test06(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("redirect:http://www.baidu.com");
return modelAndView;
// return new ModelAndView(new RedirectView("http://www.baidu.com"));
}
2:请求转发
关键字:forward:目标路径
//请求转发
@RequestMapping("/test07")
public ModelAndView test07(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("msg","这是test07转发过来的 ");
modelAndView.setViewName("forward:/index.jsp");
return modelAndView;
}
六:使用JSON开发
1:@ResponseBody
表示返回的不是视图,而是json
2:@RequestBody
表示参数接受的不是字符串【是将: 符合json格式的字符串放进java对象中】
3:添加json依赖
<!-- 添加json 依赖jar包 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.10.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.10.0</version>
</dependency>
4:修改SpringMVC的配置文件【添加处理器适配器配置】
<!-- mvc 请求映射 处理器与适配器配置 -->
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter" />
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
</mvc:message-converters>
</mvc:annotation-driven>
七:SpringMVC拦截器
1:拦截器和过滤器区别
- 拦截器是基于java的反射机制的,而过滤器是基于函数回调。
- 拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
- 拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
- 拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
- 在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
2:拦截器的使用
支持多个拦截器同时存在,行成拦截链
两种模式:
实现接口:org.springframework.web.servlet.HandlerInterceptor
继承适配器org.springframework.web.servlet.handler.HandlerInterceptorAdapter
2.1:实现接口 方式一
编写拦截器java类
//实现接口,重写三个方法
public class Interceptor_HandlerInterceptor implements HandlerInterceptor {
//在 目标Handler(方法)执行前 执行
//返回 true:执行handler方法 false:阻止目标handler方法执行
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("我是拦截器,在用户访问前执行,此时用户正在访问路径"+request.getRequestURL());
return HandlerInterceptor.super.preHandle(request, response, handler);
}
//目标Handler(方法)执行后,视图生成前 执行
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
String ipAddr = getIpAddr(request);
System.out.println(ipAddr+"访问完毕"+request.getServletPath());
}
//在目标Handler(方法)执行后,视图生成后 执行
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println(getIpAddr(request)+"访问"+request.getServletPath()+"成功!");
}
//获取用户ip方法
public static String getIpAddr(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
}
2.2:配置SpringMVC配置文件
<!-- 配置拦截器-->
<mvc:interceptors>
<!-- 这种配置方式,表示拦截所有内容,不建议使用-->
<!-- <bean class="com.wangyuan.interceptor.Interceptor_HandlerInterceptor"></bean>-->
<mvc:interceptor>
<!-- 拦截路径-->
<mvc:mapping path="/**"/>
<!-- 放行路径:不拦截的路径-->
<!-- <mvc:exclude-mapping path="/"/>-->
<!-- 拦截器对象-->
<bean class="com.wangyuan.interceptor.Interceptor_HandlerInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
2.3:继承类 方式二
//实际上最终还是 HandlerInterceptor 接口实现
//继承 HandlerInterceptorAdapter
public class Interceptor_HandlerInterceptorAdapter extends HandlerInterceptorAdapter {
//在 目标Handler(方法)执行前 执行
//返回 true:执行handler方法 false:阻止目标handler方法执行
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle");
return true;
}
//目标Handler(方法)执行后,视图生成前 执行
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle");
}
//在目标Handler(方法)执行后,视图生成后 执行
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion");
}
}
2.4:配置SpringMVC配置文件
<!-- 配置拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<!-- 拦截路径-->
<mvc:mapping path="/**"/>
<!-- 放行路径:不拦截的路径-->
<!-- <mvc:exclude-mapping path="/"/>-->
<!-- 拦截器对象-->
<bean class="com.wangyuan.interceptor.Interceptor_HandlerInterceptorAdapter"></bean>
</mvc:interceptor>
</mvc:interceptors>
八:文件上传
1:配置依赖
<!-- 添加 commons-fileupload 依赖 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.2</version>
</dependency>
2:配置SpringMVC配置文件
<!-- 文件上传 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 允许文件上传的最大尺寸 -->
<property name="maxUploadSize">
<value>104857600</value>
</property>
<!-- 设置文件放入临时文件夹的最大大小限制。 此值是阈值,低于此值,则保存在内存中,如高于此值,则生成硬盘上的临时文件。 -->
<property name="maxInMemorySize">
<value>4096</value>
</property>
</bean>
3:页面表单
input 的type设置为file
form 表单的method设为post,
form 表单的enctype设置为multipart/form-data,以二进制的形式传输数据
3.1:测试页面
<h2>单个文件上传</h2>
<form action="ploadFile" method="post" enctype="multipart/form-data">
<input type="file" name="file" />
<button type="submit"> 提交</button>
</form>
<h2>多个文件上传</h2>
<form action="ploadFiles" method="post" enctype="multipart/form-data">
<input type="file" name="files" />
<input type="file" name="files" />
<input type="file" name="files" />
<button type="submit"> 提交</button>
</form>
3.2:跳转显示页面
此页面名称:result.jsp
<body>
文件是否上传成功:${msg }
</body>
4:后台代码
/**
* 文件上传
*/
@Controller
public class fileUpload {
@RequestMapping("ploadFile")
public String uploadFile(@RequestParam("file") MultipartFile file, HttpServletRequest request,HttpServletResponse response){
saveFile(file,request,response);
return "result";
}
@RequestMapping("ploadFiles")
public String uploadFiles(@RequestParam("files") List<MultipartFile> files, HttpServletRequest request,HttpServletResponse response) {
// 判断文件集合是否为空
if (files != null && files.size() > 0) {
// 循环上传
for (MultipartFile file:files) {
// 上传文件
saveFile(file, request,response);
}
}
return "result";
}
/**
* 上传单个file文件
*/
public void saveFile(MultipartFile file, HttpServletRequest request, HttpServletResponse response) {
// 判断文件是否为空,如果不为空进行对应的文件上传操作
if (!file.isEmpty()) {
try {
// 获取项目的所在的路径 (绝对路径)
String path = request.getServletContext().getRealPath("/");
System.out.println(path);
// 设置上传的文件存放的目录
File uploadFile = new File(path + "/upload");
// 判断文件目录是否存在,不存在则新建目录
if (!uploadFile.exists()) {
// 新建目录
uploadFile.mkdir();
}
// 获取上传文件的原文件名
String originalName = file.getOriginalFilename();
// 获取上传的文件的后缀
String suffix = originalName.substring(originalName.lastIndexOf("."));
// 通过系统当前时间的毫秒数,生成随机文件名 (避免上传的文件名重复)
String fileName = System.currentTimeMillis() + suffix;
// 上传文件 (转存文件到指定目录)
file.transferTo(new File(uploadFile, fileName));
// 设置成功的域对象
request.setAttribute("msg","文件上传成功!");
} catch (IOException e) {
e.printStackTrace();
// 如果报错,设置的域对象
request.setAttribute("msg","文件上传失败!");
}
} else {
// 上传文件不存在,设置的域对象
request.setAttribute("msg","文件不存在,上传失败!");
}
}
}
九:异常处理实现
全局异常实现方式 Spring MVC 处理异常有 3 种方式:
- 使用 Spring MVC 提供的简单异常处理器 SimpleMappingExceptionResolver
- 实现 Spring 的异常处理接口 HandlerExceptionResolver 自定义自己的异常处理器
- 使用 @ExceptionHandler 注解实现异常处理
1:准备内容
1.1:编写自定义异常
/**
* 自定义异常
*/
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class BusinessException extends RuntimeException{
private Integer code=400;
private String msg="业务异常!";
public BusinessException(int code){
this.code=code;
}
public BusinessException(String msg){
this.msg=msg;
}
}
/**
* 自定义异常
*/
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class ParamsException extends RuntimeException{
private Integer code = 300;
private String msg = "参数异常!";
public ParamsException(int code){
this.code=code;
}
public ParamsException(String msg){
this.msg=msg;
}
}
1.2:编写异常页面
error_bus.jsp
${ex }<br>
${ex.code } <br>
${ex.msg }
error_par.jsp
${ex }
2:实现方式1:SimpleMappingExceptionResolver
1.1:配置异常处理对象
<!-- 配置全局异常统一处理的 Bean (简单异常处理器) -->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<!-- 页面在转发时出现异常,设置默认的错误页面 (error代表的是一个视图) -->
<property name="defaultErrorView" value="error"></property>
<!-- 异常发生时,设置异常的变量名 -->
<property name="exceptionAttribute" value="ex"></property>
<!-- 设置自定义异常与页面的映射 -->
<property name="exceptionMappings">
<props>
<!-- key:自定义异常对象的路径; 标签中设置具体的处理页面的视图名-->
<prop key="com.wangyuan.myException.BusinessException">error_bus</prop>
<prop key="com.wangyuan.myException.ParamsException">error_par</prop>
</props>
</property>
</bean>
1.2:设置controller测试
@RequestMapping("/test08.do")
public ModelAndView test08(){
ModelAndView modelAndView=new ModelAndView();
if(1==1){
throw new BusinessException();
}
modelAndView.setViewName("index");
return modelAndView;
}
@RequestMapping("/test09.do")
public ModelAndView test09(){
ModelAndView modelAndView=new ModelAndView();
if(1==1){
throw new ParamsException();
}
modelAndView.setViewName("index");
return modelAndView;
}
3:实现方式2:实现HandlerExceptionResolver 【推荐使用】
/**
* 全局异常处理
*/
@Component
public class GlobalExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
ModelAndView modelAndView = new ModelAndView();
// 默认异常页面
modelAndView.setViewName("error");
modelAndView.addObject("ex","默认系统错误");
// 判断是否是自定义异常
if (e instanceof ParamsException) {
modelAndView.setViewName("error_par");
ParamsException ee = (ParamsException) e;
modelAndView.addObject("ex", ee);
}
if (e instanceof BusinessException) {
modelAndView.setViewName("error_bus");
BusinessException ee = (BusinessException) e;
modelAndView.addObject("ex", ee);
}
return modelAndView;
}
}
2.2:设置controller测试
@RequestMapping("/test08.do")
public ModelAndView test08(){
ModelAndView modelAndView=new ModelAndView();
if(1==1){
throw new BusinessException();
}
modelAndView.setViewName("index");
return modelAndView;
}
@RequestMapping("/test09.do")
public ModelAndView test09(){
ModelAndView modelAndView=new ModelAndView();
if(1==1){
throw new ParamsException();
}
modelAndView.setViewName("index");
return modelAndView;
}
4:实现方式3:继承异常处理
//此类表示异常处理方式,需要按照此方式处理的controller或者其他类需要继承这个类
//
public class BaseController {
@ExceptionHandler
public String exc(HttpServletRequest request, HttpServletResponse response, Exception ex){
request.setAttribute("ex", ex);
if(ex instanceof ParamsException){
return "error_par";
}
if(ex instanceof BusinessException){
return "error_bus";
}
return "error";
}
}
3.2:设置controller测试
@RequestMapping(value = "/wangyuan")
//这里继承刚写的异常处理方式类
public class ControllerDemo extends BaseController {
@RequestMapping("/test08.do")
public ModelAndView test08(){
ModelAndView modelAndView=new ModelAndView();
if(1==1){
throw new BusinessException();
}
modelAndView.setViewName("index");
return modelAndView;
}
@RequestMapping("/test09.do")
public ModelAndView test09(){
ModelAndView modelAndView=new ModelAndView();
if(1==1){
throw new ParamsException();
}
modelAndView.setViewName("index");
return modelAndView;
}
}
5:捕获页面异常处理方式【404,500…】
在web.xmnl中配置相关信息
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/500.jsp</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/404.jsp</location>
</error-page>