SpringMVC2~~~

news2024/10/4 10:13:10

数据格式化

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

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

<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");
    }

中文乱码处理

表单提交数据为中文时,会出现乱码

自定义过滤器

    <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,保证按照指定格式转换 

    <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 {

    /**
     * 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="/hi"/>
        <ref bean="myInterceptor01"/>
    </mvc:interceptor>
</mvc:interceptors>

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

<mvc:interceptors>        
    <mvc:interceptor>
        <mvc:mapping path="/h*"/>
        <mvc:exclude-mapping path="/hello"/>
        <ref bean="myInterceptor01"/>
    </mvc:interceptor>
</mvc:interceptors> 

多个拦截器执行流程

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

异常处理

局部异常

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>

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

spring揭秘25-springmvc03-其他组件(文件上传+拦截器+处理器适配器+异常统一处理)

文章目录 【README】【1】文件上传与MultipartResolver【1.1】使用MultipartResolver进行文件上传【1.2】springmvc处理multipart多部件请求流程【1.3】使用springmvc上传文件代码实现&#xff08;springmvc6.10版本&#xff09;&#xff1a; 【2】Handler与HandlerAdaptor&…

遮罩解决图片悬浮操作看不到的情况

未悬浮效果 悬浮效果 如果仅仅是添加绝对定位&#xff0c;那么遇到白色图片&#xff0c;就会看不到白色字体。通过遮罩&#xff08;绝对定位透明度&#xff09;就可以解决这个问题。 <script setup> </script><template><div class"box"><…

protobuf 讲解

一、序列化概念回顾 二、什么是PB 将结构化数据进行序列化的一种方式 三、PB的特点 语言无关、平台无关&#xff1a;即PB支持Java&#xff0c;C、Python等多种语言。支持多个平台 高效&#xff1a;即比XML更小&#xff0c;更快&#xff0c;更为简单。 扩展性、兼容性好&am…

MATLAB使用眼图分析QPSK通信系统接收端匹配滤波后的信号

文章目录 前言一、MATLAB仿真代码二、仿真结果 前言 本文完成以下内容&#xff1a; &#xff08;1&#xff09;建立一个QPSK传输系统&#xff0c;并引入EsNo20dB&#xff08;SNR0dB&#xff09;的噪声&#xff0c;接收端对带噪信号进行匹配滤波。 &#xff08;2&#xff09;分…

Python并发编程挑战与解决方案

Python并发编程挑战与解决方案 并发编程是现代软件开发中的一项核心能力&#xff0c;它允许多个任务同时运行&#xff0c;提高程序的性能和响应速度。Python因其易用性和灵活性而广受欢迎&#xff0c;但其全局解释器锁&#xff08;GIL&#xff09;以及其他特性给并发编程带来了…

CSS实现服务卡片

CSS实现服务卡片 效果展示 CSS 知识点 回顾整体CSS知识点灵活运用CSS知识点 页面整体布局 <div class"container"><div class"card"><div class"box"><div class"icon"><ion-icon name"color-pal…

python集合set

1、集合是无序的&#xff0c;所以集合不支持下标访问索引 2、集合的常见操作 3、集合内不允许重复元素 4、注意

若依cloud升级mybaits-plus方法

1、在主pom文件中引入依赖 <!-- mybatis-plus 增强CRUD --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.1</version></dependency> 2、在ruoyi-comm…

基于大数据的Python+Django电影票房数据可视化分析系统设计与实现

目录 1 引言 2 系统需求分析 3 技术选型 4 系统架构设计 5 关键技术实现 6 系统实现 7 总结与展望 1 引言 随着数字媒体技术的发展&#xff0c;电影产业已经成为全球经济文化不可或缺的一部分。电影不仅是艺术表达的形式&#xff0c;更是大众娱乐的重要来源。在这个背景…

Java 每日一刊(第20期):I/O 流

文章目录 前言流的起源及概念Java I/O 流概述字节流字符流转换流缓冲流对象流与序列化NIO&#xff08;New I/O&#xff09;流的关闭与资源管理本期小知识 前言 这里是分享 Java 相关内容的专刊&#xff0c;每日一更。 本期将为大家带来以下内容&#xff1a; 流的起源及概念J…

各省-城镇化率(2001-2022年)

数据收集各省-城镇化率&#xff08;2001-2022年&#xff09;.zip资源-CSDN文库https://download.csdn.net/download/2401_84585615/89465885 相关指标&#xff1a; 包括省份、年份、年末总人口数(万人)、年末城镇人口数(万人)、城镇化率等。 数据集构建&#xff1a; 数据集通…

(7)MATLAB:QPSK理论误符号率和理论误比特率

文章目录 前言一、QPSK系统的平均误码率二、QPSK系统的平均误比特率1.根据误码率计算从QPSK符号&#xff08;四进制&#xff09;译为比特串的比特错误率。2.使用最佳接收的误比特率计算公式。 三、MATLAB代码实现与结果1.代码实现2.性能曲线画图 总结参考资料 前言 本文给出QP…

YOLOv8改进,YOLOv8改进主干网络为GhostNetV2(华为的轻量化架构)

摘要 摘要:轻量级卷积神经网络(CNN)专为移动设备上的应用而设计,具有更快的推理速度。卷积操作只能在窗口区域内捕捉局部信息,这限制了性能的进一步提升。将自注意力引入卷积可以很好地捕捉全局信息,但会极大地拖累实际速度。本文提出了一种硬件友好的注意力机制(称为 D…

[深度学习][python]yolov11+deepsort+pyqt5实现目标追踪

【算法介绍】 YOLOv11、DeepSORT和PyQt5的组合为实现高效目标追踪提供了一个强大的解决方案。 YOLOv11是YOLO系列的最新版本&#xff0c;它在保持高检测速度的同时&#xff0c;通过改进网络结构、优化损失函数等方式&#xff0c;提高了检测精度&#xff0c;能够同时处理多个尺…

系统架构设计师④:计算机网络

系统架构设计师④&#xff1a;计算机网络 TCP/IP协议族 模型如下&#xff1a; 常用的协议及端口号&#xff1a; 各个协议能力介绍&#xff1a; TCP与UDP的对比&#xff1a; DNS协议 DSN&#xff1a;域名系统( Domain Name System) 支持两种查询方式 &#xff1a; ①递…

MATLAB中qmr函数用法

目录 语法 说明 示例 线性系统的迭代解 使用指定了预条件子的 qmr 提供初始估计值 使用函数句柄代替数值矩阵 qmr函数的功能是求解线性系统 - 拟最小残差法。 语法 x qmr(A,b) x qmr(A,b,tol) x qmr(A,b,tol,maxit) x qmr(A,b,tol,maxit,M) x qmr(A,b,tol,maxit,…

蓝桥杯【物联网】零基础到国奖之路:十八. 扩展模块之光敏和AS312

蓝桥杯【物联网】零基础到国奖之路:十八.扩展模块之光敏和AS312 第一节 硬件解读第二节 CubeMX配置第二节 代码 第一节 硬件解读 光敏和AS312如下图&#xff1a; 光敏电阻接到了扩展模块的5号引脚&#xff0c;5号引脚接了2个电阻&#xff0c;R8和光敏电阻。我们通过ADC读取这…

RNN:我们一直忽略的宝藏?揭开递归神经网络的真正潜力

说到AI,我们第一个想到的可能是ChatGPT、Transformer这些大名鼎鼎的技术。但你有没有想过,其实我们“遗忘”的RNN(递归神经网络)可能才是真正的宝藏?最近有一篇论文提到一个耐人寻味的问题:“RNN真的是我们唯一需要的技术吗?” 这个问题不仅让我陷入深思,也引发了对RNN…

SpringSession;基于Redis的SpringSession实现;实现session共享的三种方式

一&#xff0c;SpringSession简介 是SpringCloud下管理session的框架&#xff0c;在微服务架构中&#xff0c;由于应用了分布式的思想&#xff0c;session无法做到内存中互通&#xff0c;需要一个框架来实现各个微服务中session数据共享&#xff0c;SpringSession解决了这个问题…

Unity 3D 游戏发布一口气讲完!(o-ωq)).oO 困

Unity 3D PC平台发布 PC 是最常见的游戏运行平台。 随着欧美游戏的崛起&#xff0c;PC 平台随之发生游戏登陆大潮。 在 PC 平台上发布游戏的步骤&#xff1a; 打开要发布的 Unity 3D 工程&#xff0c;执行 File → Build Settings 菜单命令。 在 Platform 列表框中选择 PC&a…