SpringMVC2~~~

目录

数据格式化

基本数据类型可以和字符串自动转换

特殊数据类型和字符串间的转换

验证及国际化

自定义验证错误信息

 细节

数据类型转换校验核心类DataBinder

工作机制

取消某个属性的绑定

中文乱码处理

处理json和HttpMessageConverter

处理Json-@ResponseBody

 处理Json-@ResquestBody

细节

HttpMessageConverter 

文件下载-ResponseEntity

文件上传

自定义拦截器

​拦截器与过滤器的区别​编辑 

异常处理

局部异常

执行流程

全局异常

自定义异常

统一处理异常信息SimpleMappingExceptionResolver

对未知异常进行统一处理


数据格式化

提交数据(比如表单),对提交的数据进行转换和处理

基本数据类型可以和字符串自动转换

<a href="<%=request.getContextPath()%>/addMonsterUI">添加妖怪</a>
@Controller
@Scope(value = "prototype")
public class MonsterHandler {
    @RequestMapping(value = "/addMonsterUI")
    public String addMonsterUI(Map<String, Object> map) {
        map.put("monster", new Monster());
        return "datavalid/monster_addUI";
    }

    @RequestMapping(value = "/save")
    public String save(Monster monster) {
        System.out.println("----monster---" + monster);
        return "datavalid/success";
    }
}

 return "datavalid/monster_addUI";配置文件写了前缀后缀

<form:form action="save" method="post" modelAttribute="monster">
    妖怪名字: <form:input path="name"/> <form:errors path="name"/>  <br><br>
    妖怪年龄~: <form:input path="age"/> <form:errors path="age"/> <br><br>
    电子邮件: <form:input path="email"/> <form:errors path="email"/>  <br><br>
    <input type="submit" value="添加妖怪"/>
</form:form>

1. 使用springMVC的标签来完成
2. SpringMVC 表单标签在显示之前必须在 request 中有一个 bean, 该 bean 的属性和表单标签的字段要对应!
3. SpringMVC 的 form:form 标签的 action 属性值中的 / 不代表 WEB 应用的根目录.
4. <form:form action="?" method="POST" modelAttribute="monster">
5. 当我们向map添加的数据时,会默认存放到request域 

特殊数据类型和字符串间的转换

特殊数据类型和字符串之间的转换使用注解(比如日期,规定格式的小数比如货币形式等)

日期@DateTimeFormat        货币@NumberFormat

public class Monster() {
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date birthday;

    @NumberFormat(pattern = "###,###.##")
    private Float salary;
}

@NumberFormat 只要能转成数字,1234.11也可以

@Controller
@Scope(value = "prototype")
public class MonsterHandler {
    @RequestMapping(value = "/addMonsterUI")
    public String addMonsterUI(Map<String, Object> map) {
        map.put("monster", new Monster());
        return "datavalid/monster_addUI";
    }

    @RequestMapping(value = "/save")
    public String save(Monster monster) {
        System.out.println("----monster---" + monster);
        return "datavalid/success";
    }
}
<form:form action="save" method="post" modelAttribute="monster">
    妖怪生日: <form:input path="birthday"/> <form:errors path="birthday"/> <br>
    妖怪薪水: <form:input path="salary"/> <form:errors path="salary"/> <br>
    <input type="submit" value="添加妖怪"/>
</form:form>

验证及国际化

JSR 303 是 Java 为 Bean 数据合法性校验提供的标准框架,它已经包含在JavaEE中
JSR 303 通过在 Bean 属性上标注类似于 @NotNull、@Max 等标准的注解指定校验规则

HibernateValidator 扩展注解

public class Monster {
    private Integer id;
    
    @NotEmpty
    private String email;

    @NotNull(message = "age不能为空")
    @Range(min = 1,max = 100)
    private Integer age;
    @NotEmpty
    private String name;

    @NotNull(message = "生日不能为空")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date birthday;

    @NotNull(message = "薪水不能为空")
    @NumberFormat(pattern = "###,###.##")
    private Float salary;
}

1、 @Valid 对 monster 数据按照注解进行验证

2、Errors errors 表示如果校验出现错误,将校验的错误信息保存 errors
3、Map<String, Object> map  表示如果校验出现错误, 将校验的错误信息保存 map 同时保存monster对象
4、校验发生的时机: 在springmvc底层,反射调用目标方法时,会接收到http请求的数据,然后根据注解来进行验证

@RequestMapping(value = "/save")
    public String save(@Valid Monster monster, Errors errors, Map<String, Object> map) {
        System.out.println("----monster---" + monster);
        //我们为了看到验证的情况,我们输出map 和 errors
        System.out.println("===== map ======");
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            System.out.println("key= " + entry.getKey() + " value=" + entry.getValue());
        }

        System.out.println("===== errors ======");
        if (errors.hasErrors()) {//判断是否有错误
            List<ObjectError> allErrors = errors.getAllErrors();
            for (ObjectError error : allErrors) {
                System.out.println("error=" + error);
            }
            return "datavalid/monster_addUI";
        }
        return "datavalid/success";
    }

map会输出对象信息,并且会显示有几个错误,输出错误信息(跟Errors功能一样)

Errors输出错误信息

如果没有错误,map也会输出对象信息

回显错误信息 

<form:form action="save" method="post" modelAttribute="monster">
    妖怪名字: <form:input path="name"/> <form:errors path="name"/>  <br><br>
    妖怪年龄~: <form:input path="age"/> <form:errors path="age"/> <br><br>
    电子邮件: <form:input path="email"/> <form:errors path="email"/>  <br><br>
    妖怪生日: <form:input path="birthday"/> <form:errors path="birthday"/> <br>
    妖怪薪水: <form:input path="salary"/> <form:errors path="salary"/> <br>
    <input type="submit" value="添加妖怪"/>
</form:form>

自定义验证错误信息

在springDispatcherServlet-servlet.xml配置

   <!-- 配置国际化错误信息的资源处理bean -->
    <bean id="messageSource" class=
            "org.springframework.context.support.ResourceBundleMessageSource">
        <!-- 配置国际化文件名字
            表示messageSource回到 src/i18nXXX.properties去读取错误信息
         -->
        <property name="basename" value="i18n"></property>
    </bean>

 i18n.properties

NotEmpty.monster.name=\u7528\u6237\u540d\u4e0d\u80fd\u4e3a\u7a7a
typeMismatch.monster.age=\u5e74\u9f84\u8981\u6c42\u5728\u0031\u002d\u0031\u0035\u0030\u4e4b\u95f4
typeMismatch.monster.birthday=\u751f\u65e5\u683c\u5f0f\u4e0d\u6b63\u786e
typeMismatch.monster.salary=\u85aa\u6c34\u683c\u5f0f\u4e0d\u6b63\u786e

只加@Range,如果不在范围,会显示 需要在 x - x 之间,可以指定message

如果在国际化文件写了Range.monster.age,优先自定义信息

@NotNull会显示不能为null

@NotEmpty会显示不能为空

 

Range.monster.age=\u8fd9\u662f\u65b0\u7684\u9a8c\u8bc1\u9519\u8bef\u4fe1\u606f-\u5e74\u9f84\u57281-100\u4e4b\u95f4

 细节

Bean字段加验证注解
目标方法,在Bean类型的参数前加@Valid注解,之后添加Errors或BindingResult类型参数
表单回显错误信息
配置文件,中文需要Unicode编码,使用工具转码
格式:验证规则.表单modelAttribute值.属性名=消息信息

@NotEmpty,String、colletcion、map、array不为null,不为empty
@NotNull,可以接收任何类型,不为null

数据类型转换校验核心类DataBinder

工作机制

SpringMVC 通过反射机制对目标方法进行解析,将请求消息绑定到处理方法的入参中。

数据绑定的核心部件是 DataBinder

在数据校验前也会发生错误(比如数据类型转换/格式化),会放在BindingResult中

public class DataBinder implements PropertyEditorRegistry, TypeConverter {
    @Nullable
    private ConversionService conversionService;//用于数据转换
    private final List<Validator> validators;//校验器封装到集合
    @Nullable
    private AbstractPropertyBindingResult bindingResult;//存放校验错误的结果


    public void validate() {
        Object target = this.getTarget();
        Assert.state(target != null, "No target to validate");
        BindingResult bindingResult = this.getBindingResult();
        Iterator var3 = this.getValidators().iterator();

        while(var3.hasNext()) {
            Validator validator = (Validator)var3.next();
            validator.validate(target, bindingResult);
        }

    }
}

因为加了@Valid注解,需要对Bean实例进行校验

target就是表单提交的Bean实例数据

bindingResult的运行类型是BeanPropertyBindingResult,就是errors

如果在Bean字段加了@DateTimeFormat、@NumberFormat会进行数据类型转换/格式化,出错直接存放在bindingResult中,跳过数据校验这个步骤

拿到校验器进行遍历,如果Bean实例没通过校验,就会将错误放在bindingResult中

取消某个属性的绑定

使用@InitBinder注解标识方法,对WebDataBinder对象进行初始化

WebDataBinder对象是DataBinder的子类,用于完成由表单字段到Bean属性的绑定

@InitBinder方法的参数通常是WebDataBinder,返回必须是void

机制:springmvc 在底层通过反射调用目标方法时, 接收到http请求的参数和值,使用反射+注解技术取消对指定属性的填充
setDisallowedFields支持可变参数,可以填写多个字段
如果我们取消某个属性绑定,验证无意义,把验证的注解去掉, name属性会使用默认值null

    @InitBinder
    public void initBinder(WebDataBinder webDataBinder) {
        webDataBinder.setDisallowedFields("name","age");
    }

中文乱码处理

表单(POST)提交数据为中文时,会出现乱码,GET不会出现乱码

web.xml 自定义过滤器

    <filter>
        <filter-name>MyCharacterFilter</filter-name>
        <filter-class>com.hspedu.web.filter.MyCharacterFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>MyCharacterFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
public class MyCharacterFilter implements Filter {
    public void init(FilterConfig filterConfig) throws ServletException {}

    public void doFilter(ServletRequest servletRequest,
                         ServletResponse servletResponse,
                         FilterChain filterChain) throws IOException, ServletException {
        servletRequest.setCharacterEncoding("utf-8");
        //放行请求
        filterChain.doFilter(servletRequest, servletResponse);
    }
    public void destroy() {}
}

Spring提供过滤器

放在所有过滤器之前,只需要配置xml,不再写过滤器

设置为true,保证按照指定格式转换 

第一个参数:设置encoding编码的值

第二个参数:强制请求对象(HttpServletRequest)使用encoding编码的值

第三个参数:强制应答对象(HttpServletResponse)使用encoding编码的值

web.xml 

    <filter>
        <filter-name>CharacterEncodingFilter</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>
        <init-param>
            <param-name>forceRequestEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>forceResponseEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

处理json和HttpMessageConverter<T>

处理Json-@ResponseBody

目标方法 @ResponseBody,返回的数据是json格式

控制台返回Json数据 

@Data
public class Dog {
    private String name;
    private String address;
}
@Controller
public class JsonHandler {
    @RequestMapping(value = "/json/dog")
    @ResponseBody
    public Dog getJson() {
        //返回对象
        //springmvc会根据你的设置,转成json格式数据返回
        Dog dog = new Dog();
        dog.setName("大黄狗");
        dog.setAddress("小新的家");
        return dog;
    }
}
<html>
<head>
    <title>json提交</title>
    <script type="text/javascript" src="script/jquery-3.6.0.min.js"></script>
    <script type="text/javascript">
        $(function () {
            //给id="getJson"绑定点击事件
            $("#getJson").click(function () {
                var url = this.href;
                var args = {"time": new Date};//为了防止页面缓存
                $.post(
                    url,
                    args,
                    function (data) {//data 就是返回的数据,是json格式=>如果是多个json数据,可以遍历
                        console.log("dataa= ", data);
                        console.log("dog.name=", data.name)
                        console.log("dog.addresss=", data.address)
                    },
                    "json"
                );
                return false;//这里我们返回false,就不使用href默认机制
            })
        })
    </script>
</head>
<body>
<h1>请求一个json数据</h1>
<a href="<%=request.getContextPath()%>/json/dog" id="getJson">点击获取json数据</a>
</body>
</html>

 处理Json-@ResquestBody

以前通过 表单(POST) 或者 URL请求携带参数名=参数值(GET) 把数据提交给目标方法

使用SpringMVC的 @RequestBody 将客户端提交的json数据,封装成JavaBean对象,再把这个javabean以json对象形式返回

@Data
public class User {
    private String userName;
    private Integer age;
}

@RequestBody User user 在形参指定了 @RequestBody
springmvc就会将提交的json字符串数据填充给指定Javabean  

@Controller
public class JsonHandler {
    @RequestMapping(value = "/save2")
    @ResponseBody
    public User save2(@RequestBody User user) {
        //将前台传过来的数据 以json的格式相应回浏览器
        System.out.println("user~= " + user);
        return user;
    }

}
<html>
<head>
    <script type="text/javascript" src="script/jquery-3.6.0.min.js"></script>
    <script type="text/javascript">
        $(function () {
            $("button[name='butt1']").click(function () {
                //目标:将userName 和 age 封装成json字符串,发送给目标方法
                var url = "/springmvc/save2";
                var userName = $("#userName").val();
                var age = $("#age").val();
                //将json对象转成json字符串
                var args = JSON.stringify({"userName": userName, "age": age});
                $.ajax({
                    url: url,
                    data: args,
                    type: "POST",
                    success: function (data) {
                        console.log("返回的data= ", data);
                    },
                    //下面这个contentType参数,是指定发送数据的编码和格式
                    contentType: "application/json;charset=utf-8"
                })
            })
        })
    </script>

</head>
<body>
<h1>发出一个json数据</h1>
u:<input id="userName" type="text"><br/>
a:<input id="age" type="text"><br/>
<button name="butt1">添加用户</button>
</body>
</html>

细节

@ResponseBody可以返回一个对象,也可以是集合

    @RequestMapping(value = "/json/dogs")
    @ResponseBody
    public List<Dog> getJsons() {
        List<Dog> dogs = new ArrayList<>();
        dogs.add(new Dog("大黄狗", "小新的家"));
        dogs.add(new Dog("大黄狗2", "小新2的家"));
        dogs.add(new Dog("大黄狗3", "小新3的家"));
        return dogs;
    }

@ResponseBody可以直接写在controller上,对所有的方法生效
@ResponseBody + @Controller 可以直接写成 @RestController

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
    @AliasFor(
        annotation = Controller.class
    )
    String value() default "";
}

HttpMessageConverter<T> 

SpringMVC 处理 JSON-底层实现是依靠HttpMessageConverter来进行转换的

根据消息头来查找对应的实现子类,再去找到对应的转换器,在转换器中封装,传给SpringMVC,再根据@ResponseBody、HttpEntity<T>等信息找到对应转换器 

1、到达转换器进行转换,有两个参数

inputMessage封装了请求头和请求数据

javaType,Bean的全路径

2、指定字符集(application/json;charset=utf-8)

3、ObjectMapper处理Json数据

把请求数据封装到javaType指定的对象中,inputMessage封装了目标方法

返回给SpringMVC的目标方法

最后return user还要经过转换器进行回送
回送的数据格式根据@ResponseBody等自动选择

文件下载-ResponseEntity<T>

<body>
<h1>下载文件的测试 </h1>
<a href="<%=request.getContextPath()%>/downFile">点击下载文件</a>
</body>
    @RequestMapping(value = "/downFile")
    public ResponseEntity<byte[]> downFile(HttpSession session)
            throws Exception {
        //1. 先获取到下载文件的inputStream
        InputStream resourceAsStream =
                session.getServletContext().getResourceAsStream("/img/2.jpg");

        //2. 开辟一个存放文件的byte数组, byte[] 是可以支持二进制数据(图片,视频。)
        byte[] bytes = new byte[resourceAsStream.available()];
        //3. 将下载文件的数据,读入到byte[]
        resourceAsStream.read(bytes);

        //public ResponseEntity(@Nullable T body, @Nullable MultiValueMap<String, String> headers, HttpStatus status) {}
        //4. 创建返回的HttpStatus
        HttpStatus httpStatus = HttpStatus.OK;
        //5. 创建 headers
        HttpHeaders headers = new HttpHeaders();
        //指定返回的数据,客户端应当以附件形式处理
        headers.add("Content-Disposition", "attachment;filename=2.jpg");

        //构建一个ResponseEntity 对象1. 的http响应头headers 2. http响应状态 3. 下载的文件数据
        ResponseEntity<byte[]> responseEntity =
                new ResponseEntity<>(bytes, headers, httpStatus);
        //如果出现找不到文件,解决方法 rebuild project -> 重启tomcat
        return responseEntity;
    }

文件上传

<h1>文件上传的演示</h1>
<form action="<%=request.getContextPath()%>/fileUpload" method="post" enctype="multipart/form-data">
    <%--
        在handler的形参加上字段就可以获取到introduce
        中文乱码使用过滤器来处理
    --%>
    文件介绍:<input type="text" name="introduce"><br>
    选择文件:<input type="file" name="file"><br>
    <input type="submit" value="上传文件">
</form>
    <!--配置文件上传需要的bean-->
    <!--这里的id不能乱写,底层通过父接口id来查找-->
    <bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver"
          id="multipartResolver"/>
@Controller
public class FileUploadHandler {
    //编写方法,处理文件上传的请求
    @RequestMapping(value = "/fileUpload")
    public String fileUpload(@RequestParam(value = "file") MultipartFile file,
                             HttpServletRequest request, String introduce) throws IOException {
        //接收到提交的文件名
        String originalFilename = file.getOriginalFilename();
        System.out.println("你上传的文件名= " + originalFilename);
        System.out.println("introduce=" + introduce);
        //得到要把上传文件保存到哪个路径[全路径:包括文件名]
        String fileFullPath =
                request.getServletContext().getRealPath("/img/" + originalFilename);
        //创建文件
        File saveToFile = new File(fileFullPath);
        //将上传的文件,转存到saveToFile
        file.transferTo(saveToFile);
        return "success";

    }
}

自定义拦截器

 如果用户提交的数据有禁用词,在第一个拦截器就返回,不执行目标方法

@Component
public class MyInterceptor01 implements HandlerInterceptor {

    /**
     * handler被拦截的控制器对象
     * 1. preHandle() 在目标方法执行前被执行
     * 2. 如果preHandle() 返回false , 不再执行目标方法
     * 3. 该方法可以获取到request, response, handler
     * 4. 这里根据业务,可以进行拦截,并指定跳转到哪个页面
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("--MyInterceptor01--preHandle()---");
        //获取到用户提交的关键字
        String keyword = request.getParameter("keyword");
        if("病毒".equals(keyword)) {
            //请求转发到warning
            request.getRequestDispatcher("/WEB-INF/pages/warning.jsp")
                    .forward(request,response);

            return false;
        }
        System.out.println("得到到keyword= "+ keyword);
        return true;
    }

    /**
     * 1. 在目标方法执行后,会执行postHandle
     * 2. 该方法可以获取到 目标方法,返回的ModelAndView对象
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("--MyInterceptor01--postHandle()--");
    }

    /**
     * afterCompletion() 在视图渲染后被执行, 这里可以进行资源清理工作
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("--MyInterceptor01--afterCompletion()--");
    }
}

配置拦截器 

1. 创建实现 HandlerInterceptor 接口的 bean
2. 在 mvc:interceptors 中配置拦截器

 第一种:自己在interceptors配置一个引用指向你需要使用的拦截器,对所有的请求都拦截

<mvc:interceptors>
     <ref bean="myInterceptor01"/>
</mvc:interceptors>

第二种:指定拦截目标方法

<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/monster"/>
        //拦截器对象
        <ref bean="myInterceptor01"/>或<ref class="拦截器全路径">
    </mvc:interceptor>
</mvc:interceptors>

第三种:支持通配符,同时指定不对哪些目标方法进行拦截 

<mvc:interceptors>        
    <mvc:interceptor>
        //**表示任意的字符,文件或多级目录和目录中的文件
        //   /**拦截所有请求
        <!-- <mvc:mapping path="/user/**"/> -->
        <mvc:mapping path="/h*"/>
        <mvc:exclude-mapping path="/hello"/>
        <ref bean="myInterceptor01"/>
    </mvc:interceptor>
</mvc:interceptors> 

多个拦截器执行流程

按配置顺序执行放入ArrayList
如果A的pre方法返回false,直接返回
如果B的pre方法返回false,执行A的after方法


拦截器与过滤器的区别 

异常处理

局部异常

@ExceptionHandler

1. localException 方法处理局部异常
2. 这里处理ArithmeticException.class,NullPointerException.class
3. Exception ex: 生成的异常对象,会传递给ex, 通过ex可以得到相关的信息

@Controller
public class MyExceptionHandler{

    @ExceptionHandler({ArithmeticException.class,NullPointerException.class})
    public String localException(Exception ex, HttpServletRequest request){
        System.out.println("局部异常信息是-" + ex.getMessage());
        //将异常的信息带到下一个页面.
        request.setAttribute("reason", ex.getMessage());
        return "exception_mes";
    }

    @RequestMapping(value = "/testException01")
    public String test01(Integer num) {
        int i = 9 / num;
        return "success";
    }
}
<body>
<h1>朋友, 程序发生了异常...</h1>
异常信息- ${requestScope.reason}
</body>

执行流程

ExceptionHandlerMethodResolver先找到对应异常.class,然后拿到方法名

全局异常

1. 全局异常就不管是哪个Handler抛出的异常,都可以捕获

    @ExceptionHandler({异常类型})
2. 这里的全局异常是NumberFormatException.class,ClassCastException.class
3. Exception ex 接收抛出的异常对象

@ControllerAdvice
public class MyGlobalException {
    @ExceptionHandler({NumberFormatException.class, ClassCastException.class, AgeException.class})
    public String globalException(Exception ex, HttpServletRequest request) {
        System.out.println("全局异常处理-" + ex.getMessage());
        //将异常的信息带到下一个页面.
        request.setAttribute("reason", ex.getMessage());
        return "exception_mes";
    }
}
@Controller
public class MyExceptionHandler {
    @ExceptionHandler({ArithmeticException.class,NullPointerException.class,NumberFormatException.class})
    public String localException(Exception ex, HttpServletRequest request){
        System.out.println("局部异常信息是-" + ex.getMessage());
        request.setAttribute("reason", ex.getMessage());
        return "exception_mes";
    }

    @RequestMapping(value = "/testGlobalException")
    public String global(){
        //1. 模拟了一个异常 NumberFormatException
        //2. 该异常没有在局部异常处理,按照异常处理机制,就会交给全局异常处理类处理
        int num = Integer.parseInt("hello");
        return "success";
    }
}
局部异常 > 全局异常 > SimpleMappingExceptionResolver > tomcat默认机制

自定义异常

@ResponseStatus

@ResponseStatus(reason = "年龄需要在1-120之间", value = HttpStatus.BAD_REQUEST)
public class AgeException extends RuntimeException {

    public AgeException() {
    }

    public AgeException(String message) {
        super(message);
    }
}
@Controller
public class MyExceptionHandler {

    @RequestMapping(value = "/testException02")
    public String test02(){
        throw new AgeException("年龄必须在1-120之间~~~");
    }
}

@ResponseStatus的内容在tomcat默认页面展示出来,并没有传给getMessage()

使用构造器就可以把内容传给getMessage()

可以被全局异常接管,@ExceptionHandler添加自定义异常类名.class即可

@ControllerAdvice
public class MyGlobalException {
    @ExceptionHandler({ClassCastException.class, AgeException.class})
    public String globalException(Exception ex, HttpServletRequest request) {
        System.out.println("全局异常处理-" + ex.getMessage());
        request.setAttribute("reason", ex.getMessage());
        return "exception_mes";
    }
}

统一处理异常信息SimpleMappingExceptionResolver

没有设置局部异常和全局异常

key是异常的全类名,根据视图解析器,指定对应的页面名

   <!--配置统一处理异常Bean-->
    <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
        <property name="exceptionMappings">
            <props>
                <prop key="java.lang.ArrayIndexOutOfBoundsException">arrEx</prop>
            </props>
        </property>
    </bean>
@Controller
public class MyExceptionHandler {
    @RequestMapping(value = "/testException03")
    public String test03(){
        int[] arr = new int[]{3,9,10,190};
        //抛出一个数组越界的异常 ArrayIndexOutOfBoundsException
        System.out.println(arr[90]);
        return "success";
    }
}

对未知异常进行统一处理

对发生了没有归类的异常,可以给出统一提示页面

<prop key="java.lang.Exception">allEx</prop>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/889899.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

go开发环境设置-安装与交叉编译(二)

1. 引言 Go语言&#xff0c;又称Golang&#xff0c;是Google开发的一门编程语言&#xff0c;以其高效、简洁和并发编程的优势受到广泛欢迎。作为一门静态类型、编译型语言&#xff0c;Go在构建网络服务器、微服务和命令行工具方面表现突出。 在开发过程中&#xff0c;开发者常…

吸毛效果好的宠物空气净化器分享,希喂、霍尼韦尔、米家实测

说起宠物空气净化器&#xff0c;几年前我可能会一脸鄙夷&#xff1a;为啥要花这种智商税冤枉钱&#xff1f; 直到之前养了一只猫&#xff0c;被家中乱飞的浮毛和滂臭的异味搞到头晕&#xff0c;于是作为i一个养宠的家电测评博主&#xff0c;索性对宠物空气净化器这玩意做了超级…

前端继承:原理、实现方式与应用场景

目录 一、定义 二、语法和实现方式 1.原型链继承 2.构造函数继承 3.组合继承 4.ES6类继承 三、使用方式 四、优点 五、缺点 六、适用场景 一、定义 前端继承是指在面向对象编程中&#xff0c;一个对象可以继承另一个对象的属性和方法。在前端领域&#xff0c;通常是指…

OpenCV高级图形用户界面(1)创建滑动条函数createTrackbar()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 创建一个滑动条并将其附加到指定的窗口。 该函数 createTrackbar 创建一个具有指定名称和范围的滑动条&#xff08;滑块或范围控制&#xff09;…

C语言之扫雷小游戏(完整代码版)

说起扫雷游戏&#xff0c;这应该是很多人童年的回忆吧&#xff0c;中小学电脑课最常玩的必有扫雷游戏&#xff0c;那么大家知道它是如何开发出来的吗&#xff0c;扫雷游戏背后的原理是什么呢&#xff1f;今天就让我们一探究竟&#xff01; 扫雷游戏介绍 如下图&#xff0c;简…

使用3080ti配置安装blip2

使用3080ti运行blip2的案例 本机环境&#xff08;大家主要看GPU&#xff0c;ubuntu版本和cuda版本即可&#xff09;&#xff1a;安装流程我最后安装的所有包的信息&#xff08;python 3.9 &#xff09;以供参考&#xff08;environment.yml&#xff09;&#xff1a; 本机环境&a…

【python实操】python小程序之计算对象个数、游戏更新分数

引言 python小程序之计算对象个数、游戏更新分数 文章目录 引言一、计算对象个数1.1 题目1.2 代码1.3 代码解释1.3.1 代码结构1.3.2 模块解释1.3.3 解释输出 二、游戏更新分数2.1 题目2.2 代码2.3 代码解释2.3.1 定义 Game 类2.3.2 创建 Game 实例并调用方法 三、思考3.1 计算对…

安卓13禁止锁屏 关闭锁屏 android13禁止锁屏 关闭锁屏

总纲 android13 rom 开发总纲说明 文章目录 1.前言2.问题分析3.代码分析4.代码修改5.彩蛋1.前言 设置 =》安全 =》屏幕锁定 =》 无。 我们通过修改系统屏幕锁定配置,来达到设置屏幕不锁屏的配置。像网上好多文章都只写了在哪里改,改什么东西,但是实际上并未写明为什么要改那…

RabbitMQ 高级特性——死信队列

文章目录 前言死信队列什么是死信常见面试题死信队列的概念&#xff1a;死信的来源&#xff08;造成死信的原因有哪些&#xff09;死信队列的应用场景 前言 前面我们学习了为消息和队列设置 TTL 过期时间&#xff0c;这样可以保证消息的积压&#xff0c;那么对于这些过期了的消…

数据结构-4.6.KMP算法(旧版下)-朴素模式匹配算法的优化

一.绪论&#xff1a; 当主串字符和模式串字符不匹配时会执行jnext[j]来改变模式串的指针&#xff0c;但主串的指针不变。 二.求模式串的next数组&#xff1a; 1.例一&#xff1a; 如模式串abcabd&#xff0c;当第六个字符d匹配失败时&#xff0c;此时主串中前五个字符abcab都…

连锁店线下线上一体化收银系统源码

近年来线下线上一体化已经成为很多连锁门店追求的方向。其中&#xff0c;线下门店能够赋予品牌发展的价值依然不可小觑。在线下门店中&#xff0c;收银系统可以说是运营管理的关键工具&#xff0c;好的收银系统能够为品牌门店赋能。对于连锁品牌而言&#xff0c;对收银系统的要…

软媒市场新蓝海:软文媒体自助发布与自助发稿的崛起

在信息时代的浪潮中,软媒市场以其独特的魅力和无限的潜力,成为了企业营销的新宠。随着互联网的飞速发展,软文媒体自助发布平台应运而生,为企业提供了更加高效、便捷的营销方式。而自助发稿功能的加入,更是让软媒市场的蓝海变得更加广阔。 软媒市场的独特价值 软媒市场之所以能…

Android Studio Koala中Kotlin引入序列化Parcelable

找了一堆资料没有新构建序列化的方法&#xff0c;踩坑经历如下&#xff1a; 前提是使用Kotlin创建的项目 之前的build.gradle版本写法如下&#xff1a; 但是新版Android Studio Koala使用序列化模式发生了改变&#xff0c;如下&#xff1a; 测试成功如下&#xff1a; 发出来…

【万字长文】Word2Vec计算详解(三)分层Softmax与负采样

【万字长文】Word2Vec计算详解&#xff08;三&#xff09;分层Softmax与负采样 写在前面 第三部分介绍Word2Vec模型的两种优化方案。 【万字长文】Word2Vec计算详解&#xff08;一&#xff09;CBOW模型 markdown行 9000 【万字长文】Word2Vec计算详解&#xff08;二&#xff0…

PyCharm+ssh跳板机+服务器

PyCharmssh跳板机服务器 文章目录 PyCharmssh跳板机服务器准备工作登录服务器查看CUDA查看conda创建虚拟环境 前言配置ssh免密登录设置ssh隧道配置pycharm测试第一种第二种 传输数据 准备工作 登录服务器 直接ssh连接就行,在终端(命令行)直接输入下面命令: 跳板机&#xff1…

windows系统更新升级node指定版本【避坑篇!!!亲测有效】(附带各版本node下载链接)一定看到最后!不用删旧版!

Node.js 是一个开源、跨平台的 JavaScript 运行时环境&#xff0c;广泛应用于服务器端和网络应用的开发。随着 Node.js 版本的不断更新&#xff0c;我们可能需要升级到特定版本以满足项目需求或修复安全漏洞。又或者是学习开发另外一个新项目&#xff0c;新项目对Node版本要求更…

数学建模算法与应用 第12章 现代优化算法

目录 12.1 粒子群优化算法 Matlab代码示例&#xff1a;粒子群优化算法求解函数最小值 12.2 遗传算法 Matlab代码示例&#xff1a;遗传算法求解函数最小值 12.3 蚁群算法 Matlab代码示例&#xff1a;蚁群算法求解旅行商问题 12.4 Matlab 遗传算法工具 使用遗传算法工具箱…

基于Python+sqlite3实现(Web)图书管理系统

项目名称&#xff1a;LibraryManagementSystem 一、系统目标 使用了Python作为语言,以django为后台&#xff0c;sqlite3作为数据库&#xff0c;UI基于bootstrap的图书管理系统&#xff0c;模拟图书管理的真实场景&#xff0c;考虑客观需求&#xff0c;界面简洁、操作方便&…

Android Studio实现安卓图书管理系统

获取源码请点击文章末尾QQ名片联系&#xff0c;源码不免费&#xff0c;尊重创作&#xff0c;尊重劳动 171安卓小说 1.开发环境 android stuido3.6 jak1.8 2.功能介绍 安卓端&#xff1a; 1.注册登录 2.图书列表 3.图书借阅 4.借阅列表 3.系统截图

Go编译为可执行文件

在window下打包成其他系统可运行的文件 1.在window下打包成window下可执行文件 在项目main.go同级目录下&#xff0c;逐条执行以下命令 set CGO_ENABLED0 set GOOSwindows set GOARCHamd64 go build -o main-windows.exe main.go 2.在window下打包成linux 在项目main.go同级目…