SpringMVC自定义拦截器与异常处理

拦截器概念



拦截器代码演示

创建maven工程

pom.xml

<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>day02_SpringMVC_Interceptor</artifactId><version>1.0-SNAPSHOT</version><packaging>war</packaging><!--        版本锁定--><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target><spring.version>5.1.9.RELEASE</spring.version></properties><dependencies><!--        spring--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>${spring.version}</version></dependency><!-- servlet3.0规范的坐标 --><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope></dependency><!--jsp坐标--><dependency><groupId>javax.servlet.jsp</groupId><artifactId>jsp-api</artifactId><version>2.1</version><scope>provided</scope></dependency><!--    lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.12</version></dependency><!--json相关坐标3个--><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>2.9.0</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.9.0</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-annotations</artifactId><version>2.9.0</version></dependency></dependencies><build><plugins><!--tomcat插件--><plugin><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId><version>2.2</version><configuration><port>80</port><path>/</path><!--          配置tomcat插件编码,因为请求的数据会经过tomcat.所以在tomcat也要设置一下编码--><uriEncoding>UTF-8</uriEncoding></configuration></plugin></plugins></build>
</project>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"version="3.0"><!--springMVC程序启动流程1.tomcat启动首先加载web.xml2.保证DispatcherServlet能够正常加载配置文件3.spring配置文件必须扫描有spring注解的的包--><!--  配置调度服务器(前端控制器),配置后就能够去调度controller中的路径--><servlet><servlet-name>dispatcherServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><!--    初始化DispatcherServlet,初始化springIOC容器,读取类路径下的spring-mvc.xml配置文件(target/classes/就会有这个配置文件),扫描controller注解下的RequestMapping的路径--><param-name>contextConfigLocation</param-name>
<!--            <param-value>classpath:spring-mvc.xml</param-value>--><param-value>classpath:spring-mvc.xml</param-value></init-param><!--  配置load-on-startup元素表示这个servlet应该是在启动时加载(实例化并调用其init())的web应用程序。--><load-on-startup>1</load-on-startup></servlet><!--配置请求调度服务--><servlet-mapping><!--    配置调度服务--><servlet-name>dispatcherServlet</servlet-name><!--在spring中, / /*/ : 匹配所有的请求/* :匹配所有的请求,查询结果页面,都是以文本显示,不会做任何的渲染页面,包括jsp页面--><url-pattern>/</url-pattern></servlet-mapping><!-- 配置过滤器,来解决post请求乱码问题--><filter><filter-name>characterEncodingFilter</filter-name><!--        加载spring提供的过滤器--><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>forceEncoding</param-name><param-value>true</param-value></init-param></filter><!--     过滤所有请求--><filter-mapping><filter-name>characterEncodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>
</web-app>

spring-mvc.xml

注意在核心配置文件中配置自定义拦截器的bean

<?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"><!--    设置扫描spring注解的包--><context:component-scan base-package="com.fs.springmvc"/><!-- 静态资源加载,核心控制器拦截的是所有请求,需要对静态资源请求进行放行,通过配置放行资源实现下面这个配置是可以放行所有的普通资源调用让springMVC不处理静态资源,如 .css  .js  .html  .MP3 等--><mvc:default-servlet-handler/><!--  配置注解驱动的Spring MVC控制器编程模型.
一、mvc:annotation-driven的作用
Spring 3.0.x中使用了mvc:annotation-driven后,默认会帮我们注册默认处理请求,参数和返回值的类,其中最主要的两个类:DefaultAnnotationHandlerMapping 和 AnnotationMethodHandlerAdapter ,分别为HandlerMapping的实现类和HandlerAdapter的实现类,从3.1.x版本开始对应实现类改为了RequestMappingHandlerMapping和RequestMappingHandlerAdapter。HandlerMapping的实现类的作用
实现类RequestMappingHandlerMapping,它会处理@RequestMapping 注解,并将其注册到请求映射表中。HandlerAdapter的实现类的作用
实现类RequestMappingHandlerAdapter,则是处理请求的适配器,确定调用哪个类的哪个方法,并且构造方法参数,返回值。当配置了mvc:annotation-driven/后,Spring就知道了我们启用注解驱动。然后Spring通过context:component-scan/标签的配置,会自动为我们将扫描到的@Component,@Controller,@Service,@Repository等注解标记的组件注册到工厂中,来处理我们的请求。
--><mvc:annotation-driven/><!--        配置视图解析器,方便访问jsp页面,并交给spring管理--><bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--       视图解析前缀(访问前缀)--><property name="prefix" value="/WEB-INF/pages/"/>
<!--       视图解析后缀(访问后缀)--><property name="suffix" value=".jsp"/></bean><!--开启拦截器使用--><mvc:interceptors><!--开启具体的拦截器的使用,可以配置多个--><mvc:interceptor><!--设置拦截器的拦截路径,支持*通配--><!--/**         表示拦截所有映射--><!--/*          表示拦截所有/开头的映射--><!--/user/*     表示拦截所有/user/开头的映射--><!--/user/add*  表示拦截所有/user/开头,且具体映射名称以add开头的映射--><!--/user/*All  表示拦截所有/user/开头,且具体映射名称以All结尾的映射--><mvc:mapping path="/*"/><mvc:mapping path="/**"/><mvc:mapping path="/handleRun*"/><!--设置拦截排除的路径(配置不拦截的路径),配置/**或/*,达到快速配置的目的--><mvc:exclude-mapping path="/b*"/><!--指定具体的拦截器类--><bean class="com.fs.springmvc.interceptor.MyInterceptor"/></mvc:interceptor><!--配置多个拦截器,配置顺序即为最终运行顺序--><mvc:interceptor><mvc:mapping path="/*"/><bean class="com.fs.springmvc.interceptor.MyInterceptor2"/></mvc:interceptor><mvc:interceptor><mvc:mapping path="/*"/><bean class="com.fs.springmvc.interceptor.MyInterceptor3"/></mvc:interceptor></mvc:interceptors>
</beans>

创建自定义拦截器类(代码中注释有详细解释)

MyInterceptor

package com.fs.springmvc.interceptor;
/*
拦截器与过滤器有什么不同Interceptor拦截器是SpringMVC的技术,拦截控制的controller,拦截springIOC中的controllerfilter过滤器是tomcat中所有的接收到的请求都可以被拦截,包括spring中的controller//三个方法的运行顺序为    preHandle -> controller中被拦截的方法执行 ->postHandle -> afterCompletion//如果preHandle返回值为false,三个方法仅运行preHandle由HandlerInterceptor接口源码得知,方法被default修饰了(java8新特性)被默认实现了方法的,所以我们自定义拦截器没有强制我们重写接口中的方法所以我们需要自己重写接口中的方法实现自定义拦截器的具体功能HandlerInterceptor接口源码public interface HandlerInterceptor {default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {return true;}default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {}default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {}
}*/
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//自定义拦截器需要实现HandleInterceptor接口,实现这个接口没有被强制现实所有方法
//是因为HandlerInterceptor接口中的方法有默认的default实现方法,所以我们需要自己重写接口中的方法
public class MyInterceptor implements HandlerInterceptor {//处理器运行之前执行@Overridepublic boolean preHandle(HttpServletRequest request,//请求携带的requestHttpServletResponse response,//响应携带的Response//handler就是我们执行的controller方法路径Object handler) throws Exception {//下面打印的就是我们自己写的controller的方法,使用反射技术//public java.lang.String com.fs.springmvc.controller.InterceptorController.handleRun()///System.out.println(handler.toString());System.out.println("前置运行----a1");//返回值为false将拦截原始处理器的运行,访问的controller中的方法不会被执行,//而且后面的postHandle,afterCompletion也不会执行//如果配置多拦截器,返回值为false将终止当前拦截器后面配置的拦截器的运行return true;}//处理器运行之后执行@Overridepublic void postHandle(HttpServletRequest request,HttpServletResponse response,Object handler,//controller执行方法后要返回的视图ModelAndViewModelAndView modelAndView) throws Exception {System.out.println("后置运行----b1");}//所有拦截器的后置执行全部结束后,执行该操作@Overridepublic void afterCompletion(HttpServletRequest request,HttpServletResponse response,Object handler,//Exception ex) throws Exception {System.out.println("完成运行----c1");}//三个方法的运行顺序为    preHandle -> postHandle -> afterCompletion//如果preHandle返回值为false,三个方法仅运行preHandle
}

MyInterceptor2

package com.fs.springmvc.interceptor;import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class MyInterceptor2 implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request,HttpServletResponse response,Object handler) throws Exception {System.out.println("前置运行------a2");return true;}@Overridepublic void postHandle(HttpServletRequest request,HttpServletResponse response,Object handler,ModelAndView modelAndView) throws Exception {System.out.println("后置运行------b2");}@Overridepublic void afterCompletion(HttpServletRequest request,HttpServletResponse response,Object handler,Exception ex) throws Exception {System.out.println("完成运行------c2");}
}

MyInterceptor3

package com.fs.springmvc.interceptor;import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class MyInterceptor3 implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request,HttpServletResponse response,Object handler) throws Exception {System.out.println("前置运行--------a3");return true;}@Overridepublic void postHandle(HttpServletRequest request,HttpServletResponse response,Object handler,ModelAndView modelAndView) throws Exception {System.out.println("后置运行--------b3");}@Overridepublic void afterCompletion(HttpServletRequest request,HttpServletResponse response,Object handler,Exception ex) throws Exception {System.out.println("完成运行--------c3");}
}

controller

InterceptorController

package com.fs.springmvc.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;//@Controller
public class InterceptorController {@RequestMapping("/handleRun")public String handleRun() {System.out.println("controller业务处理器运行------------main");return "page";}
}

测试

输入地址访问:

控制台输出

拦截器执行流程

拦截器参数



核心配置文件中关于拦截器的配置

拦截器链配置

异常处理

我们在controller中调用业务层出现了异常,我们不可能给前端响应一大堆异常信息,所以,我们需要将我们的异常进行封装返回给前端,然后前端对异常进行友好的提示告知客户

HandlerExceptionResolver接口方式(异常处理器)

package com.fs.springmvc.exception;import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/*
自定义异常类,必须实现异常处理程序解析器HandlerExceptionResolver接口,重写resolveException()方法
自定义异常类(全局(IOC类)异常管理)@Component注解后spring发现这个类实现了HandlerExceptionResolver接口,就认定为异常处理的类,然后就会对所有的IOC管理的对象的方法进行异常处理,当IOC管理的类的方法执行出现异常了,就会到达异常处理类的resolveException()方法,执行里面的异常处理逻辑使用自定义异常类处理异常是在controller的方法加载参数后才会加载这个类,就会导致前端传递参数
的时候,SpringMVC将前端传递过来参数封装到方法的参数的时候出现类型转换异常,就不会对这个异常进行处理
所以争对这个问题,出现了注解方式处理异常.注解处理器就可以拦截Dao入参类型转换异常*/
@Component
public class ExceptionResolver implements HandlerExceptionResolver {@Overridepublic ModelAndView resolveException(HttpServletRequest request,HttpServletResponse response,Object handler,Exception ex) {System.out.println("自定义异常类正在运行 ...."+ex);ModelAndView modelAndView = new ModelAndView();//对异常类型进行判断使用instanceof关键字if( ex instanceof NullPointerException){//将异常数据返回给前端modelAndView.addObject("msg","空指针异常");}else if ( ex instanceof  ArithmeticException){//将异常数据返回给前端modelAndView.addObject("msg","算数运算异常");}else{//将异常数据返回给前端modelAndView.addObject("msg","未知的异常");}//然后跳转到异常页面展示modelAndView.setViewName("error.jsp");return modelAndView;}
}

@ControllerAdvice注解实现异常分类管理@ExceptionHandler(常用方式)

**注意:**要在核心配置文件中添加==< mvc:annotation-driven/>mvc的注解支持==

两种异常推荐使用注解,因为注解可以拦截到入参类型转换异常

注解代码

package com.fs.springmvc.exception;import com.fs.springmvc.domain.ResultMapper;
import com.fs.springmvc.domain.User;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
/*
注解的方式处理异常(常用)
@ControllerAdvice
声明该类是一个Controller的通知类,声明后该类就会被加载成异常处理器
使用注解异常处理器就可以拦截到入参类型转换异常
而非注解(实现HandlerExceptionResolver接口)就无法拦截到入参类型转换异常*/
@Component
//使用注解开发异常处理器
//声明该类是一个Controller的通知类,声明后该类就会被加载成异常处理器
@ControllerAdvice
public class ExceptionAdvice {/*//类中定义的方法携带@ExceptionHandler注解的会被作为异常处理器,后面添加实际处理的异常类型@ExceptionHandler(NullPointerException.class)@ResponseBodypublic String doNullException(Exception ex){return "空指针异常";}@ExceptionHandler(ArithmeticException.class)@ResponseBodypublic String doArithmeticException(Exception ex){return "ArithmeticException";}//处理大异常@ExceptionHandler(Exception.class)@ResponseBodypublic String doException(Exception ex){return "all";}*//*一般处理一个大异常就行了*///处理大异常,返回结果集对象,以json返回@ExceptionHandler(Exception.class)@ResponseBodypublic ResultMapper doExceptionTo(Exception ex){//给返回的结果集的数据准备User user = new User();user.setName("小付");user.setAge(18);ResultMapper resultMapper = new ResultMapper(500,false,"服务器繁忙~",user);return resultMapper;}//处理自定义异常,返回结果集对象,以json返回@ExceptionHandler(BusinessException.class)@ResponseBodypublic ResultMapper doExceptionToBusinessException(BusinessException ex){//给返回的结果集的数据准备User user = new User();user.setName("小花");user.setAge(18);ResultMapper resultMapper = new ResultMapper(500,false,ex.getMessage(),user);return resultMapper;}
}
ResultMapper对返回的结果进行封装
package com.fs.springmvc.domain;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;/*
返回的结果对象*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ResultMapper<T> {//状态码private Integer code;//是否成功private Boolean flag;//返回消息private String message;//返回的数据private T data;
}

自定义异常

自定义异常BusinessException

package com.fs.springmvc.exception;
//自定义异常继承RuntimeException,覆盖父类所有的构造方法
public class BusinessException extends RuntimeException {public BusinessException() {}public BusinessException(String message) {super(message);}public BusinessException(String message, Throwable cause) {super(message, cause);}public BusinessException(Throwable cause) {super(cause);}public BusinessException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {super(message, cause, enableSuppression, writableStackTrace);}
}

controller中一个请求方法模拟异常来测试我们的异常代码

package com.fs.springmvc.controller;import com.fs.springmvc.domain.User;
import com.fs.springmvc.exception.BusinessException;
import com.fs.springmvc.exception.SystemException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;import java.util.ArrayList;
import java.util.List;@Controller
public class UserController {@RequestMapping("/save")@ResponseBodypublic List<User> save(@RequestBody User user) {System.out.println("user controller save is running ...");//抛出自定义的异常throw new BusinessException("请勿连续刷新页面,谢谢~~");}//    @RequestMapping("/save")
//    @ResponseBody
//    public List<User> save(@RequestBody User user) {//        System.out.println("user controller save is running ...");//模拟业务层发起调用产生了异常
//        int i = 1/0;
//        String str = null;
//        str.length();//对用户的非法操作进行判定,并包装成异常对象进行处理,便于统一管理
//        if(user.getName().trim().length() < 8){//            throw new BusinessException("对不起,用户名长度不满足要求,请重新输入!");
//        }
//        if(user.getAge() < 0){//            throw new BusinessException("对不起,年龄必须是0到100之间的数字!");
//        }
//        if(user.getAge() > 100){//            throw  new SystemException("服务器连接失败,请尽快检查处理!");
//        }//        User u1 = new User();
//        u1.setName("Tom");
//        u1.setAge(3);
//        User u2 = new User();
//        u2.setName("Jerry");
//        u2.setAge(5);
//        ArrayList<User> al = new ArrayList<User>();
//        al.add(u1);
//        al.add(u2);
//
//        return al;
//    }
}

SpringMVC自定义拦截器与异常处理(自定义异常)相关推荐

  1. SpringMVC——自定义拦截器、异常处理以及父子容器配置

    SpringMVC--自定义拦截器.异常处理以及父子容器配置 参考文章: (1)SpringMVC--自定义拦截器.异常处理以及父子容器配置 (2)https://www.cnblogs.com/so ...

  2. JavaEE开发之SpringMVC中的自定义拦截器及异常处理

    上篇博客我们聊了<JavaEE开发之SpringMVC中的路由配置及参数传递详解>,本篇博客我们就聊一下自定义拦截器的实现.以及使用ModelAndView对象将Controller的值加 ...

  3. SpringMVC 之拦截器和异常处理

    1. 文件上传 Spring 使用 Jakarta Commons FileUpload 技术实现了一个 MultipartResolver 实现类: CommonsMultipartResolver ...

  4. SpringMVC之拦截器和异常处理

    第四章 拦截器和异常处理 回顾 课前测: 本章内容 拦截器 异常处理 第一节:拦截器 javaWeb: 三大组件为servlet.filter .listener filter: 1.filter接口 ...

  5. 【SSM框架系列】SpringMVC的文件上传、拦截器及异常处理

    SpringMVC的文件上传 服务器端实现文件上传的技术有很多种,Servlet3.0,FileUtils,框架等等,都可以实现文件上传,不管使用哪一种上传技术,都必须满足三要素: 表单项type=& ...

  6. springmvc高级(拦截器,全局异常处理,文件上传)

    SpringMVC 1.文件上传 文件上传: 指的就是将用户本地计算机中文件上传到服务器上的过程称之为文件上传 1).文件上传编程步骤 # 1.项目中引入相关依赖 <dependency> ...

  7. SpringMVC拦截器与异常处理

    SpringMVC拦截器与异常处理 参考文章: (1)SpringMVC拦截器与异常处理 (2)https://www.cnblogs.com/luckgood/p/9724057.html 备忘一下 ...

  8. 【SpringMVC】自定义拦截器和过滤器

    一.闲话 五一假期明天结束了,咬咬牙把SpringMVC结束掉 二.基本要点 1.过滤器 除了之前我们提到的spring提供的过滤器之外,我们还可以自定义过滤器,使用步骤如下 编写java类实现Fil ...

  9. layui上传文件请求接口异常_SpringMVC实现文件上传与下载,拦截器,异常处理

    第一章:响应数据和结果视图 1. 返回字符串 Controller方法返回字符串可以指定逻辑视图的名称,根据视图解析器为物理视图的地址. @RequestMapping(value="/he ...

最新文章

  1. Go 代码中如何绑定 Host
  2. UA OPTI570 量子力学32 参考系与绘景
  3. UVA1354天平难题 枚举二叉树
  4. 【送书福利8本】YYDS《剑指Offer》,百万程序员人手一册
  5. CodeForces 164C Machine Programming 费用流
  6. 蓝桥杯ADV-172 算法提高 身份证排序
  7. win7睡眠,休眠的区别
  8. Android学习笔记(18):编辑框EditText
  9. 已刷高格固件的路由器如何更换为潘多拉固件
  10. 电商需求分析mysql建表_电商-专题表 - 数据库设计 - 数据库表结构 - 果创云
  11. 学校机房计算机类型,学校计算机机房的管理和维护建议原稿(备份存档)
  12. dell服务器分区表修复,如何修复被Partition Magic损坏的分区表
  13. Unity3d报错及解决办法总结
  14. 新冠疫情历史数据查询
  15. Hadoop Steaming编程示例
  16. 美团网创始人王兴专访:我现在的事业十分和谐
  17. 线性回归预测PM2.5
  18. 手机相机好坏测试软件,教你一分钟教你看懂手机拍照好坏!
  19. 完全开源!快速上手 AI 理论及应用实战来了
  20. 科技助农、航空报国、产业兴邦——钱旺正式发布“雨田一号”农用无人机

热门文章

  1. H3C S3100交换机配置VLAN和远程管理
  2. 回顾JAVA---1.概述及基本语法
  3. python基础----python的使用(四)
  4. Unity编译Mono
  5. 十分钟搞懂什么是CGI
  6. 关于 XIB 和 NIB
  7. 各种排序总结(六)归并排序
  8. DebugDiagx检测内存泄露
  9. f60gen command
  10. datatables[columns] 中的详细参数