springMVC(数据格式化+验证以及国际化+中文乱码处理+处理 json 和 HttpMessageConverter<T>+SpringMVC 文件上传+自定义拦截器+异常处理)

2023-10-26

目录

一.数据格式化 

1.基本介绍

2.基本数据类型和字符串自动转换

2.1总结:

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

二.验证以及国际化

1.概述

1.1 概述

2.JSR 303 验证框架

1.1Hibernate Validator 扩展注解  

1.2实例 

1.3自定义验证错误信息

1.4细节说明和注意事项

2.注解的结合使用

3.数据类型转换校验核心类-DataBinder

3.1DataBinder 工作机制-了解

4.取消某个属性的绑定

4.1 使用实例

三.中文乱码处理

1.自定义中文乱码过滤器

 配置处理中文乱码的过滤器

2.Spring 提供的过滤器处理中文乱码

修改web,也不要在写过滤器

四.处理 json 和 HttpMessageConverter

1.处理 JSON-@ResponseBody

2.处理 JSON-@RequestBody

应用案例

2.2@RequestBody和@ResponseBody的区别

3.处理 JSON-注意事项和细节

4.HttpMessageConverter

4.1基本说明

4.2 工作机制简图

4.3处理 JSON-底层实现(HttpMessageConverter)

5.文件下载-ResponseEntity

5.1说明:

5.2代码

五.SpringMVC 文件上传

1. 基本介绍

 六.自定义拦截器

1.什么是拦截器

1.1 说明

1.2. 自定义的拦截器必须实现 HandlerInterceptor 接口

2.自定义拦截器执行

3.自定义拦截器应用实例

3.1快速入门在 springDispatcherServlet-servlet.xml

3.2注意事项和细节

3.3执行过程解析

4.多个拦截器

4.1多个拦截器执行流程示意图​编辑

4.2海绵hong的总结

4.3代码

4.4注意事项和细节

七.异常处理

1 异常处理-基本介绍

2.局部异常

2.1 应用实例

2.2代码演示

3.全局异常

异常处理时:局部异常 优先级高于 全局异常

4.自定义异常

5.统一处理异常信息--SimpleMappingExceptionResolver

5.1 基本说明

5.2 应用实例

5.3 对未知异常进行统一处理

5.4 异常处理的优先级梳理


一.数据格式化 

1.基本介绍

说明 : 在我们提交数据 ( 比如表单时 )SpringMVC 怎样对提交的数据进行转换和处理的
1. 基本数据类型可以和字符串之间自动完成转换,比如 :
Spring MVC 上下文中内建了很多转换器,可完成大多数 Java 类型的转换工作。

2.基本数据类型和字符串自动转换

2.1总结:

这个基本数据类型和字符串会进行自动转换,也没有啥好实例的,简单来说:就像我们使用年龄这个属性的时候,当我们在页面输入18,他就会自动转化为“18”,但是当我们在后台去获取的时候他又会是我们定义的Interage类型的18.这个就是基本数据类型和字符串的自动转

这些都是springmvc帮你去转化的 

java.lang.Boolean
-> java.lang.String : org.springframework.core.convert.support.ObjectToStringConverter@f874ca
java.lang.Character -> java.lang.Number : CharacterToNumberFactory@f004c9
java.lang.Character -> java.lang.String : ObjectToStringConverter@68a961
java.lang.Enum -> java.lang.String : EnumToStringConverter@12f060a 韩顺平 Java 工程师
java.lang.Number -> java.lang.Character : NumberToCharacterConverter@1482ac5
java.lang.Number -> java.lang.Number : NumberToNumberConverterFactory@126c6f
java.lang.Number -> java.lang.String : ObjectToStringConverter@14888e8
java.lang.String -> java.lang.Boolean : StringToBooleanConverter@1ca6626
java.lang.String -> java.lang.Character : StringToCharacterConverter@1143800
java.lang.String -> java.lang.Enum : StringToEnumConverterFactory@1bba86e
java.lang.String -> java.lang.Number : StringToNumberConverterFactory@18d2c12
java.lang.String -> java.util.Locale : StringToLocaleConverter@3598e1
java.lang.String -> java.util.Properties : StringToPropertiesConverter@c90828
java.lang.String -> java.util.UUID : StringToUUIDConverter@a42f23
java.util.Locale -> java.lang.String : ObjectToStringConverter@c7e20a
java.util.Properties -> java.lang.String : PropertiesToStringConverter@367a7f
java.util.UUID -> java.lang.String : ObjectToStringConverter@112b07f ……

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

1. 特殊数据类型和字符串之间的转换使用注解 ( 比如日期,规定格式的小数比如货币形式
)
2. 对于日期和货币可以使用 @DateTimeFormat @NumberFormat 注解 . 把这两个注
解标记在字段上即可
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date birthday;
@NumberFormat(pattern="###,###.##")
private float salary;

二.验证以及国际化

1.概述

1.1 概述

1. 对输入的数据 ( 比如表单数据 ) ,进行必要的验证,并给出相应的提示信息。
2. 对于验证表单数据, springMVC 提供了很多实用的注解 , 这些注解由 JSR 303 验证框架提
.

2.JSR 303 验证框架

1. JSR 303 Java Bean 数据合法性校验提供的标准框架,它已经包含在 JavaEE
2. JSR 303 通过在 Bean 属性上标注类似于 @NotNull @Max 等标准的注解指定校验规则,
并通过标准的验证接口对 Bean 进行验证
3. JSR 303 提供的基本验证注解有 :

1.1Hibernate Validator 扩展注解  

1. Hibernate Validator Hibernate 没有关系,只是 JSR 303 实现的一个扩展 .
2. Hibernate Validator JSR 303 的一个参考实现,除支持所有标准的校验注解外,它还支
持以下的扩展注解 :
3. 扩展注解有如下

1.2实例 

记住需要jar包 

   @NotEmpty//必须非空
    private String email;

    //@Range(min = 1,max = 100)
    //表示接收的age值,在 1-100之间

    @Range(min = 1,max = 100)
    private Integer age;
    //@NotEmpty 表示name不能为空
    //Asserts that the annotated string, collection, map or array is not {@code null} or empty.
    @NotEmpty
    private String name;

    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date birthday;

    @NumberFormat(pattern = "###,###.##")
    private Float salary;
 /**
     * 编写方法,处理添加妖怪
     * 1. springmvc可以将提交的数据,按照参数名和对象的属性名匹配
     * 2. 直接封装到对象中->老师前面讲解模型数据时,讲过
     * String => Integer
     * 3. @Valid Monster monster :表示对monster接收的数据进行校验
     * 4. Errors errors 表示如果校验出现错误,将校验的错误信息保存 errors
     * 5. Map<String, Object> map  表示如果校验出现错误, 将校验的错误信息保存 map 同时保存monster对象
     * 6. 校验发生的时机: 在springmvc底层,反射调用目标方法时,会接收到http请求的数据,然后根据注解来进行验证
     * , 在验证过程中,如果出现了错误,就把错误信息填充errors 和 map
     *
     * @param monster
     * @return
     */
    @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";
    }

1.3自定义验证错误信息

为何会需要自定义那,因为在我们前面如果输入错误后面的错误信息会是如下图这样:

所以我们需要自己设置一个自定义验证错误信息,也好让我们更加直观的看出来错误

1.5.1. 配置国际化文件 springDispatcherServlet-servlet.xml

<bean class="org.springframework.web.servlet.view.BeanNameViewResolver">
<property name="order" value="99"></property>
</bean>
<!-- 配置国际化错误信息的资源处理 bean -->
<bean id="messageSource" class=
"org.springframework.context.support.ResourceBundleMessageSource">
<!-- 配置国际化文件名字
如果你这样配的话,表示 messageSource 回到 src/i18nXXX.properties 去读取错误
信息
-->
<property name="basename" value="i18n"></property>
</bean>

1.5.2创建国际化文件 D:\idea_java_projects\springmvc\src\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

1.5.3修改 monster_addUI.jsp , 回显错误信息

<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="birthday"/> <form:errors path="birthday"/> 要求
以"9999-11-11"的形式<br><br>
妖 怪 工 资 : <form:input path="salary"/> <form:errors path="salary"/> 要 求 以
"123,890.12"的形式<br><br>
电子邮件: <form:input path="email"/><br><br>
<input type="submit" value="添加妖怪"/>
</form:form>

1.4细节说明和注意事项

        1. 在需要验证的 Javabean/POJO 的字段上加上相应的验证注解 .
        2. 目标方法上 , JavaBean/POJO 类型的参数前 , 添加 @Valid 注解 . 告知 SpringMVC
bean 是需要验证的
        3. 在 @Valid 注解之后 , 添加一个 Errors BindingResult 类型的参数 , 可以获取到验证
的错误信息
        4. 需要使用 <form:errors path="email"></form:errors> 标签来显示错误消息 , 这个标签,
需要写在 <form:form> 标签内生效 .
        5. 错误消息的国际化文件 i18n.properties , 中文需要是 Unicode 编码,使用工具转码 .
格式 : 验证规则 . 表单 modelAttribute . 属性名 = 消息信息
√ NotEmpty.monster.name=\u540D\u5B57\u4E0D\u80FD\u4E3A\u7A7A
√ typeMismatch.monster.age=\u7C7B\u578B\u4E0D\u5339\u914D
        6. 注解 @NotNull @NotEmpty 的区别说明
1) 查看源码可以知道 : @NotEmpty Asserts that the annotated string, collection, map
or array is not {@code null} or empty.
2) 查看源码可以知道 : @NotNull * The annotated element must not be {@code null}.
Accepts any type .
3) 解读:如果是字符串验证空 , 建议使用 @NotEmpty
        7. SpingMVC 验证时,会根据不同的验证错误 , 返回对应的信息

2.注解的结合使用

先看一个问题
问题提出 , age 没有 , 是空的,提交确是成功了

解决问题
1. 使用 @NotNull + @Range 组合使用解决

 //email是string,使用@NotEmpty
    @NotEmpty//必须非空
    private String email;

    //@Range(min = 1,max = 100)
    //表示接收的age值,在 1-100之间

    @NotNull(message = "age不能为空")
    @Range(min = 1,max = 100)
    private Integer age;
    //@NotEmpty 表示name不能为空
    //Asserts that the annotated string, collection, map or array is not {@code null} or empty.
    @NotEmpty
    private String name;

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

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

3.数据类型转换校验核心类-DataBinder

3.1DataBinder 工作机制-了解

图例 Spring MVC 通过 反射机制对目标方法进行解析 ,将请求消息绑定到处理方法的入参中。
数据绑定的核心部件是 DataBinder ,运行机制如下

4.取消某个属性的绑定

4.1 使用实例

说明
在默认情况下,表单提交的数据都会和 pojo 类型的 javabean 属性绑定,如果
程序员在开发中,希望取消某个属性的绑定,也就是说, 不希望接收到某个表单对应的属
性的值 ,则可以通过 @InitBinder 注解取消绑定 .
1. 编写一个方法 , 使用 @InitBinder 标识的该方法,可以对 WebDataBinder 对象进行初始
化。 WebDataBinder DataBinder 的子类,用于完成由表单字段到 JavaBean 属性的绑
2. @InitBinder 方法不能有返回值,它必须声明为 void
3. @InitBinder 方法的参数通常是是 WebDataBinder

案例 - 不希望接收怪物的名字属性
    //取消绑定 monster的name表单提交的值给monster.name属性
    @InitBinder
    public void initBinder(WebDataBinder webDataBinder) {
        /**
         * 解读
         * 1. 方法上需要标注 @InitBinder  springmvc底层会初始化 WebDataBinder
         * 2. 调用 webDataBinder.setDisallowedFields("name") 表示取消指定属性的绑定
         *    即:当表单提交字段为 name时, 就不在把接收到的name值,填充到model数据monster的name属性
         * 3. 机制:springmvc 在底层通过反射调用目标方法时, 接收到http请求的参数和值,使用反射+注解技术
         *    取消对指定属性的填充
         * 4. setDisallowedFields支持可变参数,可以填写多个字段
         * 5. 如果我们取消某个属性绑定,验证就没有意义了,应当把验证的注解去掉, name属性会使用默认值null
         *  //@NotEmpty
         *  private String name;
         *
         */
        //webDataBinder.setDisallowedFields("name");
    }
* 解读
* 1. 方法上需要标注 @InitBinder  springmvc底层会初始化 WebDataBinder
* 2. 调用 webDataBinder.setDisallowedFields("name") 表示取消指定属性的绑定
*    即:当表单提交字段为 name时, 就不在把接收到的name值,填充到model数据monster的name属性
* 3. 机制:springmvc 在底层通过反射调用目标方法时, 接收到http请求的参数和值,使用反射+注解技术
*    取消对指定属性的填充
* 4. setDisallowedFields支持可变参数,可以填写多个字段
* 5. 如果我们取消某个属性绑定,验证就没有意义了,应当把验证的注解去掉, name属性会使用默认值null
*  //@NotEmpty
*  private String name;本身就拿不到数据了,就没有必要去验证了

三.中文乱码处理

1.自定义中文乱码过滤器

说明
当表单提交数据为中文时,会出现乱码,我们来解决一下


/**
 * @author 海绵hong
 * @version 1.0
 * 编写过滤器,处理中文乱码
 */
public class MyCharacterFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest,
                         ServletResponse servletResponse,
                         FilterChain filterChain) throws IOException, ServletException {
        //这里加入对编码的处理
        servletRequest.setCharacterEncoding("utf-8");
        //放行请求,这个规则和前面讲过的java web的过滤器一样
        filterChain.doFilter(servletRequest, servletResponse);

    }

    @Override
    public void destroy() {

    }
}

 配置处理中文乱码的过滤器

  <!--配置处理中文乱码的过滤器
    拦截所有请求,处理编码, 提醒,把过滤器配置到web.xml前面
    -->
    <filter>
        <filter-name>MyCharacterFilter</filter-name>
        <filter-class>com.hong.web.filter.MyCharacterFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>MyCharacterFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

2.Spring 提供的过滤器处理中文乱码

我们使用Spring 提供的过滤器处理中文乱码,那样的话我们就会发现我们之前所使用的自定义过滤器需要定义utf-8这个固定的编码格式,但是我们也不知道何时需要,那么我们还要在init()中读取内容,单手Spring 提供的过滤器处理中文乱码就可以很灵活。

修改web,也不要在写过滤器

<!--配置处理中文乱码的过滤器
    拦截所有请求,处理编码, 提醒,把过滤器配置到web.xml前面
    -->
<!--    <filter>-->
<!--        <filter-name>MyCharacterFilter</filter-name>-->
<!--        <filter-class>com.hong.web.filter.MyCharacterFilter</filter-class>-->
<!--    </filter>-->
<!--    <filter-mapping>-->
<!--        <filter-name>MyCharacterFilter</filter-name>-->
<!--        <url-pattern>/*</url-pattern>-->
<!--    </filter-mapping>-->


    <!--配置Spring提供的过滤器,解决中文乱码问题-->

    <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>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

四.处理 json HttpMessageConverter<T>

1.处理 JSON-@ResponseBody

说明 :
项目开发中,我们往往需要服务器返回的数据格式是按照 json 来返回的 , 我们看一下
SpringMVC 是如何处理的 , 功能示意图, 下面是老韩要完成的效果
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>json提交</title>
    <!-- 引入jquery -->
    <script type="text/javascript" src="script/jquery-3.6.0.min.js"></script>

    <!-- 编写jquery代码和ajax请求 -->
    <script type="text/javascript">
        $(function () {
            //给id="getJson"绑定点击事件
            $("#getJson").click(function () {
                //console.log("ok ....")

                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默认机制
            })

            //绑定按钮点击事件, 提交json数据
            //springmvc 可以在在台將json轉成對象
            $("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>
<%--老师处理
1.当用户点击超链接时,我们发出一个ajax请求
2. 接收到请求后,我们查看这个数据
3. 使用前面讲过的jquery发出ajax请求知识
--%>
<a href="<%=request.getContextPath()%>/json/dog" id="getJson">点击获取json数据</a>

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

<h1>下载文件的测试 </h1>
<a href="<%=request.getContextPath()%>/downFile">点击下载文件</a>
</body>
</html>

javabean--Dog

。。。。。

Handler

@Controller
public class JsonHandler {
 /**
     * 解读
     * 1. 目标方法 @ResponseBody,表返回的数据是json格式
     * 2. springmvc底层根据目标方法@ResponseBody, 返回指定格式, 根据的http请求来进行处理
     * 3. 底层原理我们在前面自定义@ResponseBody讲过, 这里原生的springmvc使用转换器
     * 4. HttpMessageConverter [一会debug]
     *
     * @return
     */
@RequestMapping(value = "/getJson")
//指定返回的数据格式 json ,靠这个@ResponseBody
@ResponseBody
public Dog getJson() {
//创建一只狗
Dog dog = new Dog();
dog.setName("大黄狗");
dog.setAddress("北京八达岭~");
return dog;
}
}

2.处理 JSON-@RequestBody

应用案例

- 前面给大家讲解的是通过表单 , 或者 url 请求携带 参数名 = 参数值 把数据提交给目
标方法
1) 给大家举例客户端发送 json 字符串数据
2) 使用 SpringMVC @RequestBody 将客户端提交的 json 数据,封装成 JavaBean 对象
3) 再把这个 javabean json 对象形式返回

2.2@RequestBody和@ResponseBody的区别

@RequestBody
用法:一般放在controller层的具体请求方法的入参中。比如:

@PostMapping("/url")
public urlBo getUrlByPhoneNumber(@RequestBody String json,HttpServetRequest request){
    UrlBo ub=new Gson().fromJson(json,UrlBo.class);
    ....//其他处理逻辑
}

这里的@RequestBody用于读取Http请求的body部分数据——就是我们的请求数据。比如json或者xml。然后把数据绑定到 controller中方法的参数上,这里就是String json这个入参啦~。

使用时要注意能不能用@RequestBody把request请求的数据解析,并赋给我们定义的参数上是由请求头的Content-Type的值来决定的。

当我们用get/post方式提交请求后, Content-Type的值有以下几种,分别对应能不能解析数据如下:

1.application/x-www-form-urlencoded, 可选(即非必须,因为这种情况的数据@RequestParam, @ModelAttribute也可以处理,当然@RequestBody也能处理)
2.multipart/form-data, 不能处理(即使用@RequestBody不能处理这种格式的数据)
3.其他格式(其他格式包括application/json, application/xml等),这些格式的数据,必须使用@RequestBody来处理

说明:request的body部分的数据编码格式由header部分的Content-Type指定。

@ReponseBody
用法:放在controller层的方法上,将Controller的方法返回的对象,SpringMVC会根据返回值类型(Map、Llist)找到可以处理的消息转换器,并确定结果的MediaType。返回对象、map和List结果将由MappingJackson2HttpMessageConverter处理,并且MediaType为:application/json。后面写入到Response对象的body数据区。
使用时机:
当我们想让页面知道我们返回的数据不是按照html标签的页面来解析,而是其他某种格式的数据解析时(如json、xml等)使用。
例如:

@RequestMapping("/getList")
@ResponseBody
public Map<String,Object> getStudentList(HtppServletRequest request){
    Map<String,Object> map=new HashMap<String,Object>();
    Dto dto=getParamAsDto(request);
    List li=studentAction.getList(dto.get("age"));
    map.put("studentInfo",li);
}

3.处理 JSON-注意事项和细节

1. 目标方法正常返回 JSON 需要的数据 , 可以是一个对象 , 也可以是一个集合 [ 举例 ]
2. 前面我讲解的是返回一个 Dog 对象 -> 转成 Json 数据格式返回
3. @ResponseBody 可以直接写在 controller 上,这样对所有方法生效
4. @ResponseBody + @Controller 可以直接写成 @RestController ,

4.HttpMessageConverter<T>

4.1基本说明

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

4.2 工作机制简图

4.3处理 JSON-底层实现(HttpMessageConverter<T>)

 1. 使用 HttpMessageConverter<T> 将请求信息转化并绑定到处理方法的入参中, 或将响应结果转为对应类型的响应信息,Spring 提供了两种途径:

√ 使用 @RequestBody / @ResponseBody 对目标方法进行标注

使用 HttpEntity<T> / ResponseEntity<T> 作为目标方法的入参或返回值
2. 当 控 制 器 处 理 方 法 使 用 到 @RequestBody/@ResponseBody 或HttpEntity<T>/ResponseEntity<T> 时 , Spring 首先根据请求头或响应头的 Accept 属性选择 匹配 的 HttpMessageConverter, 进而 根据参 数类型 或泛型 类型的 过滤得 到匹配 的 HttpMessageConverter, 若找不到可用的 HttpMessageConverter 将报错

5.文件下载-ResponseEntity<T>

5.1说明:

SpringMVC 中,通过返回 ResponseEntity<T> 的类型,可以实现文件下载的功能

5.2代码

<h1>下载文件的测试 </h1>
<a href="<%=request.getContextPath()%>/downFile">点击下载文件</a>
  //响应用户下载文件的请求
    @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");
//        文件下载响应头的设置
//        content-type 指示响应内容的格式
//        content-disposition 指示如何处理响应内容。
//        一般有两种方式:
//        inline:直接在页面显示
//        attchment:以附件形式下载

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

五.SpringMVC 文件上传

1. 基本介绍

基本介绍
1. Spring MVC 为 文 件 上 传 提 供 了 直 接 的 支 持 , 这 种 支 持 是 通 过 即 插 即 用 的
MultipartResolver 实 现 的 。 Spring Jakarta Commons FileUpload 技 术 实 现 了 一 个
MultipartResolver 实现类: CommonsMultipartResovler
2. Spring MVC 上下文中默认没有装配 MultipartResovler ,因此默认情况下不能处理文件的
上传工作,如果想使用 Spring 的文件上传功能,需现在上下文中配置 MultipartResolver


/**
 * @author 海绵hong
 * @version 1.0
 * 处理文件上传的handler
 */
@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";

    }

 六.自定义拦截器

1.什么是拦截器

1.1 说明

1. Spring MVC 也可以使用拦截器对请求进行拦截处理,用户可以自定义拦截器来实现特定
的功能 .

1.2. 自定义的拦截器必须实现 HandlerInterceptor 接口

自定义拦截器的三个方法
1. preHandle() :这个方法在业务处理器处理请求之前被调用,在该方法中对用户请求
request 进行处理。
2. postHandle() :这个方法在目标方法处理完请求后执行
3. afterCompletion() :这个方法在完全处理完请求后被调用,可以在该方法中进行一些资源
清理的操作。

2.自定义拦截器执行

自定义拦截器执行流程说明
1. 如果 preHandle 方法 返回 false, 则不再执行目标方法 , 可以在此指定返回页面
2. postHandle 在目标方法被执行后执行 . 可以在方法中访问到目标方法返回的 ModelAndView 对象
3. preHandle 返回 true, afterCompletion 方法 在渲染视图之后被执行 .
4. preHandle 返回 false, afterCompletion 方法不会被调用
5. 在配置拦截器时,可以指定该拦截器对哪些请求生效,哪些请求不生效

3.自定义拦截器应用实例

3.1快速入门在 springDispatcherServlet-servlet.xml

应用实例需求
完成一个自定义拦截器,学习一下如何配置拦截器和拦截器的运行流程
应用实例 - 代码实现

配置自定义拦截器

    <!--配置自定义拦截器-spring配置文件-->
    <mvc:interceptors>
        <!--
        解读
        1. 第一种配置方式
        2. 使用ref 引用到对应的myInterceptor01
        3. 这种方式,会拦截所有的目标方法
        -->
        <!--<ref bean="myInterceptor01"/>-->

        <!--解读
        1. 第二种配置方式
        2. mvc:mapping path="/hi" 指定要拦截的路径
        3. ref bean="myInterceptor01" 指定对哪个拦截器进行配置
        -->
        <!--<mvc:interceptor>-->
        <!--    <mvc:mapping path="/hi"/>-->
        <!--    <ref bean="myInterceptor01"/>-->
        <!--</mvc:interceptor>-->

        <!--解读
        1. 第3种配置方式
        2. mvc:mapping path="/h*" 通配符方式 表示拦截 /h 打头的路径
        3. mvc:exclude-mapping path="/hello" /hello不拦截
        4. ref bean="myInterceptor01" 指定对哪个拦截器配置
        -->
        <mvc:interceptor>
            <mvc:mapping path="/h*"/>
            <mvc:exclude-mapping path="/hello"/>
            <ref bean="myInterceptor01"/>
        </mvc:interceptor>

自定义过滤器


@Component
public class MyInterceptor01 implements HandlerInterceptor {

    /**
     * 解读
     * 1. preHandle() 在目标方法执行前被执行
     * 2. 如果preHandle() 返回false , 不再执行目标方法
     * 3. 该方法可以获取到request, response, handler
     * 4. 这里根据业务,可以进行拦截,并指定跳转到哪个页面
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @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对象
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("--MyInterceptor01--postHandle()--");
    }

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

    @RequestMapping(value = "/hi")
    public String hi(User user) {

        System.out.println("---FurnHandler--hi()---");
        return "success";
    }

    @RequestMapping(value = "/hello")
    public String hello() {
        System.out.println("---FurnHandler--hello()---");
        return "success";
    }

    @RequestMapping(value = "/ok")
    public String ok() {
        System.out.println("---FurnHandler--ok()---");
        return "success";
    }
}

3.2注意事项和细节

1 、默认配置是都所有的目标方法都进行拦截 , 也可以指定拦截目标方法 , 比如只是拦截 hi(用这个拦截器myInterceptor01)
<mvc:interceptor>
    <mvc:mapping path="/hi"/>
    <ref bean="myInterceptor01"/>
</mvc:interceptor>
2 mvc:mapping 支持通配符 , 同时指定不对哪些目标方法进行拦截
<mvc:interceptor>
    <mvc:mapping path="/h*"/>
    <mvc:exclude-mapping path="/hello"/>
    <ref bean="myInterceptor01"/>
</mvc:interceptor>
3 、拦截器需要配置才生效,不配置是不生效的 .
4 、如果 preHandler() 方法返回了 false, 就不会执行目标方法 ( 前提是你的目标方法被拦截
), 程序员可以在这里根据业务需要指定跳转页面 .

3.3执行过程解析

先去配置文件中寻找拦截的页面,然后进入到preHandle(),接着到目标方法,并在这个时间将对象填充到目标方法,在之后就是postHandle()方法,这个时候该方法里面的modelAndView中存储着之前的对象(换句话说就是在这个地方你可以去改变你的值),在之后就是执行资源清理工作的afterCompletion()登场了

4.多个拦截器

4.1多个拦截器执行流程示意图

4.2海绵hong的总结

根据配置顺序,先配置那个就先执行那个 。如果有有一个方法在执行的时候,有两个拦截器。

这个我就叫hong(),拦截器有a,b两个,a在前。

当有请求需要这个拦截器的时候,会先去执行a的preHandle()如果为true就继续执行b的preHandle(),当执行目标方法之后就会继续去执行b的post()方法,然后再就是a的post。然后就会继续渲染视图(因为这两个方法a,b已经把modelAndView进行了二次渲染,这个时候需要的话也可以进行二次修改)在之后就是执行b的after()最后才是a的after()。就是挑明说a配置顺序在前所以第一个就是它,但之后全部都是b先执行

4.3代码

再建立一个拦截器

@Component
public class MyInterceptor02 implements HandlerInterceptor {}

配置文件配置顺序(在第一个的后面接上的)

   <!--解读
          1.配置的第二个拦截器
          2.多个拦截器在执行时,是顺序执行
          -->
<mvc:interceptor>
        <mvc:mapping path="/h*"/>
        <ref bean="myInterceptor02"/>
    </mvc:interceptor>
</mvc:interceptors>

4.4注意事项和细节

1. 如果第 1 个拦截器的 preHandle() 返回 false , 后面都不在执行
2. 如 果 第 2 个 拦 截 器 的 preHandle() 返 回 false , 就 直 接 执 行 第 1 个 拦 截 器 的
afterCompletion() 方法 , 如果拦截器更多,规则类似
3. 说明 : 前面说的规则,都是目标方法被拦截的前提

七.异常处理

1 异常处理-基本介绍

基本介绍
1. Spring MVC 通过 HandlerExceptionResolver 处理程序的异常,包括 Handler 映射、数据
绑定以及目标方法执行时发生的异常。
2. 主要处理 Handler 中用 @ExceptionHandler 注解定义的方法。
3. ExceptionHandlerMethodResolver 内部若找不到 @ExceptionHandler 注解的话,会找
@ControllerAdvice 类的 @ExceptionHandler 注解方法 , 这样就相当于一个全局异常处理器

2.局部异常

2.1 应用实例

应用实例需求
演示局部异常处理机制
- 如果不处理异常 , 非常的不友好

2.2代码演示

基本步骤:

先执行页面请求,在页面中有handler之后,会去执行handler当我们的handler出现我们自定义的异常之后@ExceptionHandler(),这个框号中有的异常。我们就会去去执行这个注解下面的方法。

    /**
     * 解读
     * 1. localException 方法处理局部异常
     * 2. 这里处理ArithmeticException.class,NullPointerException.class异常
     * 3. Exception ex: 生成的异常对象,会传递给ex, 通过ex可以得到相关的信息
     *    , 这里程序员可以加入自己的业务逻辑
     * @return
     */
    @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";
    }

<%-- Created by IntelliJ IDEA.
User: 海绵hong
Version: 1.0
Filename: exception
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>异常提示信息</title>
</head>
<body>
<h1>朋友,发生异常,信息如下 :</h1>
${reason }
</body>
</html>

3.全局异常

         ExceptionHandlerMethodResolver 内 部 若 找 不 到 @ExceptionHandler 注解的话,会找 @ControllerAdvice 类的 @ExceptionHandler 注解方法 , 这样就相当于一个全局异常处理器

/**
 * 如果类上标注了@ControllerAdvice,就是一个全局异常处理类
 */
@ControllerAdvice
public class MyGlobalException {

    /**
     * 解读
     * 1. 全局异常就不管是哪个Handler抛出的异常,都可以捕获 , @ExceptionHandler({异常类型})
     * 2. 这里处理的全局异常是NumberFormatException.class,ClassCastException.class
     * 3. Exception ex 接收抛出的异常对象
     *
     * @return
     */
    //
    @ExceptionHandler({NumberFormatException.class, ClassCastException.class})
    public String globalException(Exception ex, HttpServletRequest request) {
        System.out.println("全局异常处理-" + ex.getMessage());
        //如何将异常的信息带到下一个页面.
        request.setAttribute("reason", ex.getMessage());
        return "exception";
    }

}

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

被@ControllerAdvice标注的类就是全局异常类。局部异常在handler中,但是全局异常在全局异常处理类

异常处理时:局部异常 优先级高于 全局异常

4.自定义异常

通过 @ResponseStatus 注解 , 可以自定义异常的说明

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

    public AgeException() {
    }

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

当然当我们将自定义异常写入全局异常也是可以被接管的

@ExceptionHandler({NumberFormatException.class, ClassCastException.class, AgeException.class})

5.统一处理异常信息--SimpleMappingExceptionResolver

5.1 基本说明

基本说明
1. 如果希望对所有异常进行统一处理,可以使用 SimpleMappingExceptionResolver
2. 它将异常类名映射为视图名,即发生异常时使用对应的视图报告异常
3. 需要在 ioc 容器中配置
​​​​​​​4.当局部和全局异常都没有的时候我们就会使用统一处理异常

5.2 应用实例

应用实例 - 需求
对数组越界异常进行统一处理,使用 SimpleMappingExceptionResolver
    @RequestMapping(value = "/testException03")
    public String test03(){
        int[] arr = new int[]{3,9,10,190};
        //抛出一个数组越界的异常 ArrayIndexOutOfBoundsException
        System.out.println(arr[90]);
        return "success";
    }
<bean>
class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
    <props>
        <prop key="java.lang.ArrayIndexOutOfBoundsException">arrEx</prop>
    </props>
</property>
</bean>
        <!-- 加入两个常规配置 -->
        <!-- 能支持 SpringMVC 高级功能,比如 JSR303 校验,映射动态请求 -->
<mvc:annotation-driven></mvc:annotation-driven>
        <!-- 将 SpringMVC 不能处理的请求交给 Tomcat, 比如请求 css,js 等-->
<mvc:default-servlet-handler/>

5.3 对未知异常进行统一处理

对未知异常进行统一处理,使用 SimpleMappingExceptionResolver
    //如果发生了没有归类的异常, 可以给出统一提示页面
    @RequestMapping(value = "/testException04")
    public String test04(){
        String str = "hello";
        //这里会抛出 StringIndexOutOfBoundsException
        char c = str.charAt(10);
        return "success";
    }
    <!-- 配置一个统一异常处理 -->
    <bean
            class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
        <property name="exceptionMappings">
            <props>
                <prop key="java.lang.ArrayIndexOutOfBoundsException">arrEx</prop>
                <prop key="java.lang.Exception">otherEx</prop>
            </props>
        </property>
    </bean>
Exception这个包括了所有异常,所有当前面三关都没有留着这个异常,那么这个就会发现

5.4 异常处理的优先级梳理

异常处理的优先级

局部异常 > 全局异常 > SimpleMappingExceptionResolver > tomcat 默认机制​​​​​​​
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

springMVC(数据格式化+验证以及国际化+中文乱码处理+处理 json 和 HttpMessageConverter<T>+SpringMVC 文件上传+自定义拦截器+异常处理) 的相关文章

  • Spring boot 404错误自定义错误响应ReST

    我正在使用 Spring boot 来托管 REST API 即使浏览器正在访问 URL 以及自定义数据结构 我也希望始终发送 JSON 响应 而不是使用标准错误响应 我可以使用 ControllerAdvice 和 ExceptionHa
  • 如何加载椭圆曲线 PEM 编码的私钥? [复制]

    这个问题在这里已经有答案了 我使用 OpenSSL 生成了椭圆曲线私钥 公钥对 私钥和公钥均采用 PEM 编码 我已经弄清楚如何加载公钥 感谢this https stackoverflow com a 40439081但是 我无法弄清楚如
  • 从 Java 启动外部进程:stdout 和 stderr

    我正在使用标准从 java 启动一个外部进程java lang Process 我试图弄清楚该过程的输出是什么 但是采用结合了两者的格式stdout and stderr 目前 我有Process getInputStream它提供了访问s
  • 平衡括号问题的优化解

    给定一个仅包含字符的字符串 and 判断输入字符串是否有效 输入字符串在以下情况下有效 左括号必须由相同类型的括号封闭 左括号必须按正确的顺序关闭 请注意 空字符串也被视为有效 示例1 Input Output true Example 2
  • 使用用户名进行 Java LDAP 身份验证

    好吧 这让我发疯 我正在尝试使用 Java 创建 LDAP 身份验证 如果我在 SECURITY PRINCIPAL 中使用我的名字和姓氏 一切都很好 这是我的代码 try Hashtable
  • JSF 错误 - IllegalStateException:PWC3999:提交响应后无法创建会话[重复]

    这个问题在这里已经有答案了 我是 JSF 新手 正在构建一个使用 Facelet 创建的应用程序 这是我的模板master xhtml
  • shell解析json并循环输出组合变量

    杰斯克喜欢我之前的话题 https stackoverflow com questions 74063588 shell parsing json contains spaces in string 我知道如何解析带有空格的简单 json
  • JavaFX 动画使用循环?

    我正在尝试制作一款类似太空侵略者的游戏 我画了一个正方形 我想通过使用循环逐步向下移动它thread sleep 然而 正方形立即被绘制出来 我知道有可以使用的动画路径 但我想保持低水平并仅使用坐标系 有没有办法使用这样的循环来制作时间轴动
  • Java中的运算符重载和覆盖

    运算符重载和运算符重写有什么区别 它们在继承和控制台程序中是否相同 Java 不支持运算符重载和重写 检查以下引用自的描述 http java sun com docs white langenv Simple doc2 html http
  • Android 上的自定义视图和窗口属性

    我想要做的是在我的应用程序顶部添加一个视图 该视图类似于过滤器视图 我想操纵屏幕的颜色 并且我还希望能够同时更改屏幕的亮度时间 这两件事似乎是分开起作用的 但不能一起起作用 这是我的代码 添加视图 colourView new Layer
  • 添加和完成 PHP 源代码文档的工具 [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我有几个已完成的较旧的 PHP 项目 其中有很多内容 我想以 javadoc phpDocumentor
  • 更改 Spring Web 应用程序的默认会话超时

    我必须测试一个由 spring 和 jsp 编写的 Web 应用程序 应用程序的默认会话超时为 30 分钟 我想减少会话超时 为此 我改变了web xml文件输入tomcatInstallationLocation conf 但这不起作用
  • 为什么 Cassandra 客户端在生产中没有 epoll 时会失败? [复制]

    这个问题在这里已经有答案了 当我在本地运行服务时 我收到一条警告 指出 epoll 不可用 因此它使用 NIO 很公平 当我将其部署到 Kubernetes 中时 我得到了以下信息 这导致服务无法运行 2017 03 29T19 09 22
  • JSF“总”变量类似于 JSTL 中的 c:set

    我不喜欢 JSF 但我需要用它来解决这个问题 我正在 纯 JSF 中工作 所以这就是我基本上需要的 但我不知道如何用 JSF 来实现它
  • 解析 SWIG 接口文件的结构属性

    这是我不久前问过的问题的延续 为通过参数返回的函数创建类型映射 https stackoverflow com questions 12793973 create a typemap for a function that returns
  • 使用 OpenNLP 获取句子的解析树。陷入困境。

    OpenNLP 是一个关于自然语言处理的 Apache 项目 NLP 程序的目标之一是解析一个句子 并给出其语法结构的树 例如 天空是蓝色的 这句话 可能会被解析为 S NP VP The sky is blue where S是句子 NP
  • JSF - 实施受限页面过滤器

    我正在关注 BalusC 的回答JSF 2 0 如何获取在浏览器地址栏中输入的 URL https stackoverflow com questions 4105263 jsf 2 0 how to get the url that is
  • 从 IntelliJ 运行 JavaFX 应用程序

    Versions openjdk版本 11 0 11 2021 04 20 OpenJDK 运行时环境 build 11 0 11 9 Ubuntu 0ubuntu2 20 10 OpenJDK 64 位服务器虚拟机 内部版本 11 0 1
  • 如何获取 res.drawable 文件夹的路径来复制文件?

    我正在编写我的应用程序AndroidStudio 我的里面有gif文件drawable gifs文件夹 我希望将该文件复制到MediaStore Images Media单击按钮后的文件夹 目前 即使使用发布的一些答案 我也无法获取我的 g
  • selenium 没有找到合适的方法,直到(ExpectedCondition)

    这是有线的问题 我导入的项目运行 100 几个月前 今天我已将其与依赖项一起导入 但存在问题WebDriverWait 这是我的代码 WebDriverWait driverWait new WebDriverWait driver 100

随机推荐

  • PTA 7-15 计算圆周率 (15 分)

    根据下面关系式 求圆周率的值 直到最后一项的值小于给定阈值 2 1 31 3 52 3 5 73 3 5 7 2n 1 n 输入格式 输入在一行中给出小于1的阈值 输出格式 在一行中输出满足阈值条件的近似圆周率 输出到小数点后6位 输入样例
  • 音视频基础(1)音视频处理流程

    文章目录 音视频基础 1 音视频处理流程 1 概要 2 音频处理流程 3 视频处理流程 4 直播客户端处理流程 5 音频数据流转 音视频基础 1 音视频处理流程 理解音频处理流程对我们做音视频开发至关重要 因为理解了这个处理流程之后 我们就
  • mysql用户授权

    mysql用户授权 1 grant授权 授权 添加用户并设置权限 命令格式 grant 权限列表 on 库名 表名 to 用户名 客户端地址 identified by 密码 with grant option with grant opt
  • draw.io环境搭建

    为什么80 的码农都做不了架构师 gt gt gt 前言 draw io是一款在github上的开源产品 由于需要构建在线文档 需要插入画图类型 对比多款开源产品 最终选择了draw io draw io图标资源非常的丰富 方便导入图标资源
  • Android——(高级控件下拉框与搜索框)

    1 高级控件与低级控件区别 是否使用适配器 2 适配器种类和作用 2 1 种类 数组适配器 ArrayAdapter new ArrayAdapter
  • MySQL - java链接mysql8 并兼容链接mysql5 亲测可用

    开始之前先去官网捋一遍 MySQL Connector J开发人员指南 看看官方的一些变动 和一些可能要注意的点 或者一些可能会踩到的坑 事先 我们要有一个使用mysql5 x的应用或者服务 需要修改的部分不算多 但是要想同时想兼容5 x和
  • java: cannot find symbol symbol: variable log

    使用Intellij idea的时候 编译项目始终报错java cannot find symbol symbol variable log 装Lombok Plugin 插件 设置 build execution deployment g
  • react-redux库

    安装react redux tnpm i react redux 未优化前 src components Count index tsx import React useState from react export default fun
  • UE4命令行打包项目

    RunUAT bat在ue安装路径找 1 Compiling the client 编译客户端的命令行代码 RunUAT BuildCookRun project full project path and project name upr
  • MySQL 命令环境变量设置方法

    安装完MySQL之后 大家可以直接打开MySQL的client输入命令 操作MySQL数据库 当然也可以使用dos窗口输入MySQL命令操作MySQL数据库 方法1 1 打开dos窗口 具体怎么打开 百度 2 定位到MySQL安装目录下的b
  • jmeter生成随机数

    打开函数助手 Random 写入随机范围的最小值 和最大值 name of variable in which to store the result 为变量名 写好后 点击生成 复制字符串 粘贴到需要的请求上即可
  • linux查看vlan命令,[转]linux VLAN配置(vconfig)

    1 安装vlan vconfig 和加载8021q模块 aptitude install vlan modprobe 8021q 2 使用linux vconfig命令配置vlan vconfig add eth0 100 vconfig
  • 网络安全——cobalt Strike 之office钓鱼

    一 office钓鱼 在无需交互 用户无感知的情况下 执行office文档中内嵌的恶意代码 例如宏 从远控地址中下载并运行恶意可执行程序 例如远控木马 勒索病毒等 cobalt strike office钓鱼原理 主要生成一段vba代码 然
  • 前端发送的form-data类型name=“carNumber“的参数后端怎么接收

    需求 前端将图片和其他信息一起已form data类型发送给后端 图片以二进制流的形式 其他信息以key value的键值对的形式 举例 具体荷载 后端controller层接收的方法 RequestMapping value upload
  • linux安装jdk8

    1 官网下载链接 Java Downloads Oracle 2 下载完成之后 我们打开linux 执行如下命令 最后通过rz命令将文件上传 root localhost local mkdir usr local java root lo
  • android imageloader 进度条,Android-Universal-Image-Loader使用介绍

    图片开源库是一个应用非常广泛的第三方库 几乎所有的应用都会使用 目前而言常见的图片库有 Android Universal Image Loader Picasso Fresco Glide等 下面是国内Top500Android应用分析报
  • Win10笔记本屏幕最低亮度依旧很亮?最高亮度依旧很暗?

    左下角搜索 显卡 打开 英特尔R显卡控制中心 点击 显示器 点击 颜色 里面有 全部颜色 在这里调节即可 嫌太亮 调低些 反之则反
  • 必刷算法题之排序篇(题目及代码)---C++

    前言 该篇博客记录了和排序有关的一些题目 差不多是逐级递增的难度 后续还会补充 有具体思路和代码 文章目录 第一题 排序 第二题 判断字符是否唯一 第三题 最小的k个数 第四题 单链表的排序 第五题 最大数 第六题 调整数组顺序使奇数位于偶
  • javaScript中Float精度计算

    在项目中做了一个计算统计值的部分 实现过程是通过 javaScript 进行累加的 在测试时出现了一个很乖的问题 在此记录一下 1 问题背景 项目中有一个表格字段 数据类型是float的 在数据库中均以Decimal 10 2 的格式保存
  • springMVC(数据格式化+验证以及国际化+中文乱码处理+处理 json 和 HttpMessageConverter<T>+SpringMVC 文件上传+自定义拦截器+异常处理)

    目录 一 数据格式化 1 基本介绍 2 基本数据类型和字符串自动转换 2 1总结 3 特殊数据类型和字符串间的转换 二 验证以及国际化 1 概述 1 1 概述 2 JSR 303 验证框架 1 1Hibernate Validator 扩展