如何使用Spring Validation优雅地校验参数_java

来源:脚本之家  责任编辑:小易  

实际上,2113spring-session-data-redis并不是一个实际的jar包,只5261不过它配置了其他的四个依赖(如图4102,图中标1653绿色的四个):Spring-session-data-redis是一个空的包:Spring Core、Spring Web配置4.x版本:Spring Session还需要把Spring Web等常见的Spring包引入。Spring Session 1.0.2依赖Spring的版本为4.1.6以上,因此3.x版本的Spring是无法使用的。访问Web项目,查看session:访问Web项目,这个时候,使用redis-cli进入redis命令操作界面,在使用keys *可以查看所有的key。补充一下,如果要设置Session的过期时间,通常我们会在web.xml文件中进行设置根据具体问题类型,进行步骤拆解/原因原理分析/内容拓展等。具体步骤如下:/导致这种情况的原因主要是……,Spring Session作为Spring社区官2113方推荐的一个比较简5261单快速的Java Web分布式session解决方案,帮我们搞定了长期4102以来比较蛋疼的1653session分布式的问题。Spring Session解决的基本思路很简单,即将用户的session信息全部存放到一个redis数据库中,所有的session都从这个数据库拿。由于redis是一个内存数据库,数据信息读写是非常快速的。如此一来,多个Tomcat,共用一个redis数据库,即实现了session的共享问题。访问Spring Session官方网站:在百度中查询Spring Session即可找到Spring Session的官方站点。目前版本为1.0.2,1.0.3版本处于snapshot状态。Spring指出,Spring Session具有如下能力:(1) API and implementations for managing a user's session(2) HttpSession - allows replacing the HttpSession in an application container (i.e. Tomcat) neutral way(2-1)Clustered Sessions - Spring Session makes it trivial to support clustered sessions without being tied to an application container specific solution.(2-2)Multiple Browser Sessions - Spring Session supports managing multiple users' sessions in a single browser instance (i.e. multiple authenticated accounts similar to Google).(2-3)RESTful APIs - Spring Session allows providing session ids in headers to work with RESTful APIs(3) WebSocket - provides the ability to keep the HttpSession alive when receiving WebSocket messages对Spring Session有了基本了解之后,可以开始配置Maven的pom.xml,导入SpringSession的jar包Spring官方文档指出,要使用Spring Session,配置如下依赖即可:<dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> <version>1.0.2.RELEASE</version></dependency>实际上,spring-session-data-redis并不是一个实际的jar包,只不过它配置了其他的四个依赖:Spring-session-data-redis是一个空的包,我们可以从如下截图中看出。Spring-session-data-redis仅仅只有一个META-INF文件夹。它的作用就在于引入其他四个包。当然,实际上你也可以不配置spring-session-data-redis,而直接配置实际上导入的类:<!-- Redis --><dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.4.2.RELEASE</version></dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.5.2</version></dependency> <!-- Spring Session --><dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session</artifactId> <version>1.0.2.RELEASE</version></dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> <version>2.2</version></dependency>我们这里,首先,配置spring-data-redis和jedis,这样,就可以使用spring-data-redis框架,来实现访问redis数据库。spring-data-redis是spring的一个子项目,和spring-session一样。spring-session要访问redis,这里spring-session依赖spring-data-redis,来实现操作reids数据库。Spring Core、Spring Web需要配置4.x版本。当然,Spring Session还需要把Spring Web等常见的Spring包引入。Spring Session 1.0.2依赖Spring的版本为4.1.6以上,因此,3.x版本的Spring是无法使用的:可以从Maven Repository查看依赖情况:http://mvnrepository.com/artifact/org.springframework.session/spring-session/1.0.2.RELEASE此外,注意javax.servlet-api需要3.0.1版本以上。配置application-context.xml文件这里,我们以使用xml配置方式为例,当然也可以使用注解配置,详见SPring的官方例子(见参考资料)备注:xml的配置方法官方给出了一个例子:http://docs.spring.io/spring-session/docs/1.0.2.RELEASE/reference/html5/guides/httpsession-xml.html在application-context.xml文件中,加入:<context:annotation-config/> <bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration"/> <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig" /> <bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:host-name="${redis.host}" p:port="${redis.port}" p:password="${redis.pass}" p:pool-config-ref="poolConfig"/>其中,${redis.host}等即redis数据库的服务器地址,端口,密码等信息,放在properties文件中即可。修改web.xml,加入Spring Session的Filter在web.xml文件中,加入:<filter> <filter-name>springSessionRepositoryFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class></filter><filter-mapping> <filter-name>springSessionRepositoryFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>这样,所有的请求,都会被DelegatingFilterProxy处理,实际上,DelegatingFilterProxy会找到springSessionRepositoryFilter,创建它。每一次的请求还是由springSessionRepositoryFilter来过滤的。The DelegatingFilterProxy will look up a Bean by the name of springSessionRepositoryFilter and cast it to a Filter. For every request that DelegatingFilterProxy is invoked, the springSessionRepositoryFilter will be invoked.这里,Spring加入了一个Filter,其本质是:对每一个请求的request进行了一次封装。那么,在Controller里面拿出的request实际上是封装后的request,调用request.getSession()的时候,实际上拿到是Spring封装后的session。这个session则存储在redis数据库中。访问Web项目,查看session访问Web项目,这个时候,使用redis-cli进入redis命令操作界面,在使用keys *可以查看所有的key:第一个是当前访问的用户的session信息,第二个保存的是过期的时间。可以查看session的详细内容如下:可以看出,session对象被序列化后存入。因此,所有放入session的对象,都要实现Serializable接口。比如,我将所有的用户信息,封装到一个Authentication对象,那么这对象就必须实现Serializable接口:补充一下:如果要设置Session的过期时间,通常我们会在web.xml文件中进行设置:但是,使用Spring Session托管session后,这里的设置将会失效。我们要专门为Spring Session进行设置:将application-context.xml,即步骤4中的的RedisHttpSessionConfiguration,设置其maxInactiveIntervalInSeconds属性即可。注意,maxInactiveIntervalInSeconds的的单位是秒! 如下将设置session为10分钟过期!<bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration"> <property name="maxInactiveIntervalInSeconds" value="600"></property></bean>本回答被提问者采纳www.zgxue.com防采集请勿采集本网。

引言

不知道大家平时的业务开发过程中 controller 层的参数校验都是怎么写的?是否也存在下面这样的直接判断?

总结如下: 1. @Autowired有个required属性,可以配置为false,这种情况下如果没有找到对应的bean是不会抛异常的。@Inject和@Resource没有提供对应的配置,所以必须找到否则会抛异常。 2. @Autowired和@Inject基本是一样的,因为两者都是使用Aut

public String add(UserVO userVO) { if(userVO.getAge() == null){ return "年龄不能为空"; } if(userVO.getAge() > 120){ return "年龄不能超过120"; } if(userVO.getName().isEmpty()){ return "用户名不能为空"; } // 省略一堆参数校验... return "OK";}

Spring Security如何控制权限概要 Spring使用由Filter组成的Chain,来判断权限。如下图所示:Spring预定义了很多out-of-boxed filter供开发者直接使用。每个Filter一般情况下(有些Filter是abstract的),都和配置文件的一个元素(有的情况下可

业务代码还没开始写呢,光参数校验就写了一堆判断。这样写虽然没什么错,但是给人的感觉就是:不优雅,不专业。

测试主类为: package myspring2; import java.sql.*; import javax.sql.DataSource; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MySpr

其实Spring框架已经给我们封装了一套校验组件:validation。其特点是简单易用,自由度高。接下来课代表使用springboot-2.3.1.RELEASE搭建一个简单的 Web 工程,给大家一步一步讲解在开发过程中如何优雅地做参数校验。

spring是J2EE应用程序框架,是轻量级的IoC和AOP的容器框架,主要是针对javaBean的生命周期进行管理的轻量级容器。Spring包含7大模块,每个模块可以单独使用、也可以结合起来使用;但是在实际开发过程中,一般需要结合Struts、Hibernate来使用。

1. 环境搭建

1指具体的人或物,例如:请把钥匙递到桌子上,请把钥匙递给我,放在桌子上。那个女孩是他的妹妹。穿红衣服的女孩是他的妹妹。那边镇上最高的。那边的大楼是这座城市中最高的。我喜欢这部电影。我喜欢这部电影的音乐。2说双方都知道或理解人或事

springboot-2.3开始,校验包被独立成了一个starter组件,所以需要引入如下依赖:

<!--校验组件--><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId></dependency><!--web组件--><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId></dependency>

springboot-2.3之前的版本只需要引入 web 依赖就可以了。

2.小试牛刀

参数校验非常简单,首先在待校验字段上增加校验规则注解

public class UserVO { @NotNull(message = "age 不能为空") private Integer age;}

然后在controller方法中添加@Validated和用于接收错误信息的BindingResult就可以了,于是有了第一版:

public String add1(@Validated UserVO userVO, BindingResult result) { List<FieldError> fieldErrors = result.getFieldErrors(); if(!fieldErrors.isEmpty()){ return fieldErrors.get(0).getDefaultMessage(); } return "OK";}

通过工具(postman)去请求接口,如果参数不符合规则,会将相应的 message信息返回:

age 不能为空

内置的校验注解有很多,罗列如下:

注解 校验功能
@AssertFalse 必须是false
@AssertTrue 必须是true
@DecimalMax 小于等于给定的值
@DecimalMin 大于等于给定的值
@Digits 可设定最大整数位数和最大小数位数
@Email 校验是否符合Email格式
@Future 必须是将来的时间
@FutureOrPresent 当前或将来时间
@Max 最大值
@Min 最小值
@Negative 负数(不包括0)
@NegativeOrZero 负数或0
@NotBlank 不为null并且包含至少一个非空白字符
@NotEmpty 不为null并且不为空
@NotNull 不为null
@Null 为null
@Past 必须是过去的时间
@PastOrPresent 必须是过去的时间,包含现在
@PositiveOrZero 正数或0
@Size 校验容器的元素个数

3. 规范返回值

待校验参数多了之后我们希望一次返回所有校验失败信息,方便接口调用方进行调整,这就需要统一返回格式,常见的就是封装一个结果类。

public class ResultInfo<T>{ private Integer status; private String message; private T response; // 省略其他代码...}

改造一下controller 方法,第二版:

public ResultInfo add2(@Validated UserVO userVO, BindingResult result) { List<FieldError> fieldErrors = result.getFieldErrors(); List<String> collect = fieldErrors.stream() .map(o -> o.getDefaultMessage()) .collect(Collectors.toList()); return new ResultInfo<>().success(400,"请求参数错误",collect);}

请求该方法时,所有的错误参数就都返回了:

{ "status": 400, "message": "请求参数错误", "response": [ "年龄必须在[1,120]之间", "bg 字段的整数位最多为3位,小数位最多为1位", "name 不能为空", "email 格式错误" ]}

4. 全局异常处理

每个Controller方法中都如果都写一遍对BindingResult信息的处理,使用起来还是很繁琐。可以通过全局异常处理的方式统一处理校验异常。

当我们写了@validated注解,不写BindingResult的时候,Spring 就会抛出异常。由此,可以写一个全局异常处理类来统一处理这种校验异常,从而免去重复组织异常信息的代码。

全局异常处理类只需要在类上标注@RestControllerAdvice,并在处理相应异常的方法上使用@ExceptionHandler注解,写明处理哪个异常即可。

@RestControllerAdvicepublic class GlobalControllerAdvice { private static final String BAD_REQUEST_MSG = "客户端请求参数错误"; // <1> 处理 form data方式调用接口校验失败抛出的异常 @ExceptionHandler(BindException.class) public ResultInfo bindExceptionHandler(BindException e) { List<FieldError> fieldErrors = e.getBindingResult().getFieldErrors(); List<String> collect = fieldErrors.stream() .map(o -> o.getDefaultMessage()) .collect(Collectors.toList()); return new ResultInfo().success(HttpStatus.BAD_REQUEST.value(), BAD_REQUEST_MSG, collect); } // <2> 处理 json 请求体调用接口校验失败抛出的异常 @ExceptionHandler(MethodArgumentNotValidException.class) public ResultInfo methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) { List<FieldError> fieldErrors = e.getBindingResult().getFieldErrors(); List<String> collect = fieldErrors.stream() .map(o -> o.getDefaultMessage()) .collect(Collectors.toList()); return new ResultInfo().success(HttpStatus.BAD_REQUEST.value(), BAD_REQUEST_MSG, collect); } // <3> 处理单个参数校验失败抛出的异常 @ExceptionHandler(ConstraintViolationException.class) public ResultInfo constraintViolationExceptionHandler(ConstraintViolationException e) { Set<ConstraintViolation<?>> constraintViolations = e.getConstraintViolations(); List<String> collect = constraintViolations.stream() .map(o -> o.getMessage()) .collect(Collectors.toList()); return new ResultInfo().success(HttpStatus.BAD_REQUEST.value(), BAD_REQUEST_MSG, collect); } }

事实上,在全局异常处理类中,我们可以写多个异常处理方法,课代表总结了三种参数校验时可能引发的异常:

    使用form data方式调用接口,校验异常抛出 BindException 使用 json 请求体调用接口,校验异常抛出 MethodArgumentNotValidException 单个参数校验异常抛出ConstraintViolationException

注:单个参数校验需要在参数上增加校验注解,并在类上标注@Validated

全局异常处理类可以添加各种需要处理的异常,比如添加一个对Exception.class的异常处理,当所有ExceptionHandler都无法处理时,由其记录异常信息,并返回友好提示。

5.分组校验

如果同一个参数,需要在不同场景下应用不同的校验规则,就需要用到分组校验了。比如:新注册用户还没起名字,我们允许name字段为空,但是不允许将名字更新为空字符。

分组校验有三个步骤:

    定义一个分组类(或接口) 在校验注解上添加groups属性指定分组 Controller方法的@Validated注解添加分组类

public interface Update extends Default{}

public class UserVO { @NotBlank(message = "name 不能为空",groups = Update.class) private String name; // 省略其他代码...}

@PostMapping("update")public ResultInfo update(@Validated({Update.class}) UserVO userVO) { return new ResultInfo().success(userVO);}

细心的同学可能已经注意到,自定义的Update分组接口继承了Default接口。校验注解(如: @NotBlank)和@validated默认都属于Default.class分组,这一点在javax.validation.groups.Default注释中有说明

/** * Default Jakarta Bean Validation group. * <p> * Unless a list of groups is explicitly defined: * <ul> * <li>constraints belong to the {@code Default} group</li> * <li>validation applies to the {@code Default} group</li> * </ul> * Most structural constraints should belong to the default group. * * @author Emmanuel Bernard */public interface Default {}

在编写Update分组接口时,如果继承了Default,下面两个写法就是等效的:

@Validated({Update.class})

@Validated({Update.class,Default.class})

请求一下/update接口可以看到,不仅校验了name字段,也校验了其他默认属于Default.class分组的字段

{ "status": 400, "message": "客户端请求参数错误", "response": [ "name 不能为空", "age 不能为空", "email 不能为空" ]}

如果Update不继承Default@Validated({Update.class})就只会校验属于Update.class分组的参数字段,修改后再次请求该接口得到如下结果,可以看到, 其他字段没有参与校验:

{ "status": 400, "message": "客户端请求参数错误", "response": [ "name 不能为空" ]}

6.递归校验

如果 UserVO 类中增加一个 OrderVO 类的属性,而 OrderVO 中的属性也需要校验,就用到递归校验了,只要在相应属性上增加@Valid注解即可实现(对于集合同样适用)

OrderVO类如下

public class OrderVO { @NotNull private Long id; @NotBlank(message = "itemName 不能为空") private String itemName; // 省略其他代码...}

在 UserVO 类中增加一个 OrderVO 类型的属性

public class UserVO { @NotBlank(message = "name 不能为空",groups = Update.class) private String name;//需要递归校验的OrderVO @Valid private OrderVO orderVO; // 省略其他代码...}

调用请求验证如下:

7. 自定义校验

Spring 的 validation 为我们提供了这么多特性,几乎可以满足日常开发中绝大多数参数校验场景了。但是,一个好的框架一定是方便扩展的。有了扩展能力,就能应对更多复杂的业务场景,毕竟在开发过程中,唯一不变的就是变化本身。

Spring Validation允许用户自定义校验,实现很简单,分两步:

    自定义校验注解 编写校验者类

代码也很简单,结合注释你一看就能懂

@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})@Retention(RUNTIME)@Documented@Constraint(validatedBy = {HaveNoBlankValidator.class})// 标明由哪个类执行校验逻辑public @interface HaveNoBlank { // 校验出错时默认返回的消息 String message() default "字符串中不能含有空格"; Class<?>[] groups() default { }; Class<? extends Payload>[] payload() default { }; /** * 同一个元素上指定多个该注解时使用 */ @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE }) @Retention(RUNTIME) @Documented public @interface List { NotBlank[] value(); }}

public class HaveNoBlankValidator implements ConstraintValidator<HaveNoBlank, String> { @Override public boolean isValid(String value, ConstraintValidatorContext context) { // null 不做检验 if (value == null) { return true; } if (value.contains(" ")) { // 校验失败 return false; } // 校验成功 return true; }}

自定义校验注解使用起来和内置注解无异,在需要的字段上添加相应注解即可,同学们可以自行验证

回顾

    内置多种常用校验注解 支持单个参数校验 结合全局异常处理自动组装校验异常 分组校验 支持递归校验 自定义校验

本文代码已上传至

GitHub

到此这篇关于如何使用Spring Validation优雅地校验参数的文章就介绍到这了,更多相关Spring Validation校验参数内容请搜索真格学网以前的文章或继续浏览下面的相关文章希望大家以后多多支持真格学网!

导入spring的jar包,然后写spring的配置文件,在方法中声明configuarion对象,参数就是spring配置文件的路径,大概就是这个顺序,用eclipse工具就利用它吧2113, 右键项目-> Properties -> Java Build Path -> Libraries -> Add External JARs,然后加入自己的5261spring jar包就好。Spring jar介绍如下:4102(1) spring-core.jar这个jar文件包含Spring框架基本的核心工具1653类,Spring其它组件要都要使用到这个包里的类,是其它组件的基本核心,当然你也可以在自己的应用系统中使用这些工具类。(2) spring-beans.jar这个jar文件是所有应用都要用到的,它包含访问配置文件、创建和管理bean以及进行Inversion of Control / Dependency Injection(IoC/DI)操作相关的所有类。如果应用只需基本的IoC/DI支持,引入spring-core.jar及spring- beans.jar文件就可以了。(3) spring-aop.jar这个jar文件包含在应用中使用Spring的AOP特性时所需的类。使用基于AOP的Spring特性,如声明型事务管理(Declarative Transaction Management),也要在应用里包含这个jar包。(4) spring-context.jar  这个jar文件为Spring核心提供了大量扩展。可以找到使用Spring ApplicationContext特性时所需的全部类,JDNI所需的全部类,UI方面的用来与模板(Templating)引擎如 Velocity、FreeMarker、JasperReports集成的类,以及校验Validation方面的相关类。(5) spring-dao.jar  这个jar文件包含Spring DAO、Spring Transaction进行数据访问的所有类。为了使用声明型事务支持,还需在自己的应用里包含spring-aop.jar。(6) spring-hibernate.jar  这个jar文件包含Spring对Hibernate 2及Hibernate 3进行封装的所有类。(7) spring-jdbc.jar  这个jar文件包含对Spring对JDBC数据访问进行封装的所有类。(8) spring-orm.jar  这个jar文件包含Spring对DAO特性集进行了扩展,使其支持 iBATIS、JDO、OJB、TopLink,因为Hibernate已经独立成包了,现在不包含在这个包里了。这个jar文件里大部分的类都要依赖 spring-dao.jar里的类,用这个包时你需要同时包含spring-dao.jar包。(9) spring-remoting.jar  这个jar文件包含支持EJB、JMS、远程调用Remoting(RMI、Hessian、Burlap、Http Invoker、JAX-RPC)方面的类。(10) spring-support.jar  这个jar文件包含支持缓存Cache(ehcache)、JCA、JMX、邮件服务(Java Mail、COS Mail)、任务计划Scheduling(Timer、Quartz)方面的类。(11) spring-web.jar  这个jar文件包含Web应用开发时,用到Spring框架时所需的核心类,包括自动载入WebApplicationContext特性的类、Struts与JSF集成类、文件上传的支持类、Filter类和大量工具辅助类。(12) spring-webmvc.jar  这个jar文件包含Spring MVC框架相关的所有类。包含国际化、标签、Theme、视图展现的FreeMarker、JasperReports、Tiles、Velocity、 XSLT相关类。当然,如果你的应用使用了独立的MVC框架,则无需这个JAR文件里的任何类。(13) spring-mock.jar  这个jar文件包含Spring一整套mock类来辅助应用的测试。Spring测试套件使用了其中大量mock类,这样测试就更加简单。模拟HttpServletRequest和HttpServletResponse类在Web应用单元测试是很方便的。本回答被网友采纳内容来自www.zgxue.com请勿采集。


  • 本文相关:
  • spring boot validation参数校验实例分析
  • springboot+dubbo+validation 进行rpc参数校验的实现方法
  • 详解spring注解式参数校验
  • 详解如何在spring boot项目使用参数校验
  • springboot整合sso(single sign on)单点登录
  • java抛出异常与自定义异常类应用示例
  • 浅谈java文件执行顺序、main程序入口的理解
  • java实现ftp文件上传下载解决慢中文乱码多个文件下载等问题
  • 简单了解java标识符的作用和命名规则
  • springmvc前台向后台传值几种方式总结(从简单到复杂)
  • springboot如何使用aop做访问请求日志
  • java 中httpurlconnection附件上传的实例详解
  • java腾讯ai人脸对比对接代码实例
  • java中方法的重写与成员变量的隐藏
  • 普通Java project如何使用spring?
  • 如何使用Spring Session实现分布式Session管理
  • 如何用Spring进行日志管理
  • Spring、Spring MVC、Spring Boot 怎么使用,有什...
  • 如何使用spring component 以及注意事项
  • 如何使用spring security
  • 如何用spring连接数据库
  • Spring是怎么用的
  • 如何使用Spring Cloud
  • 如何学习使用Spring 框架
  • 网站首页网页制作脚本下载服务器操作系统网站运营平面设计媒体动画电脑基础硬件教程网络安全c#教程vbvb.netc 语言java编程delphijavaandroidiosswiftscala易语言汇编语言其它相关首页spring boot validation参数校验实例分析springboot+dubbo+validation 进行rpc参数校验的实现方法详解spring注解式参数校验详解如何在spring boot项目使用参数校验springboot整合sso(single sign on)单点登录java抛出异常与自定义异常类应用示例浅谈java文件执行顺序、main程序入口的理解java实现ftp文件上传下载解决慢中文乱码多个文件下载等问题简单了解java标识符的作用和命名规则springmvc前台向后台传值几种方式总结(从简单到复杂)springboot如何使用aop做访问请求日志java 中httpurlconnection附件上传的实例详解java腾讯ai人脸对比对接代码实例java中方法的重写与成员变量的隐藏java使double保留两位小数的多方java8 十大新特性详解java.net.socketexception: connjava写入文件的几种方法分享java环境变量的设置方法(图文教程java 十六进制与字符串的转换java list用法示例详解java中file类的使用方法javaweb实现文件上传下载功能实例java 字符串截取的三种方法(推荐java中join线程操作实例分析intellij idea 中使用jrebel进行 java 热在centos系统上安装java的openjdk的方法java 程序员必备的 intellij idea 插件springboot+vue前后端分离实现请求api跨域java swing中的jbutton、jcombobox、jlisjava随机数算法原理与实现方法实例详解springmvc利用fastjson接口返回json数据相maven默认中央仓库(settings.xml 配置详解java volatile的适用场景实例详解
    免责声明 - 关于我们 - 联系我们 - 广告联系 - 友情链接 - 帮助中心 - 频道导航
    Copyright © 2017 www.zgxue.com All Rights Reserved