1.SpringBoot统一接口返回和全局异常处理
2.java-增强版Comparator进行集合排序null异常处理
3.Java如何生成版本号?比如0001 0002 0002
4.java中的源码空指针异常如何处理?
5.不含npe是什么意思?
SpringBoot统一接口返回和全局异常处理
背景
在分布式、微服务盛行的源码今天,绝大部分项目都采用的源码微服务框架,前后端分离方式。源码前端和后端进行交互,源码前端按照约定请求URL路径,源码源码90H的真值并传入相关参数,源码后端服务器接收请求,源码进行业务处理,源码返回数据给前端。源码维护一套完善且规范的源码接口是非常有必要的,这样不仅能够提高对接效率,源码也可以让我的源码代码看起来更加简洁优雅。
使用统一返回结果时,源码还有一种情况,源码就是程序的报错是由于运行时异常导致的结果,有些异常是我们在业务中抛出的,有些是pycharm调试源码无法提前预知。
因此,我们需要定义一个统一的全局异常,在Controller捕获所有异常,并且做适当处理,并作为一种结果返回。
统一接口返回定义API返回码枚举类publicenumResultCode{ /*成功状态码*/SUCCESS(,"成功"),/*错误状态码*/NOT_FOUND(,"请求的资源不存在"),INTERNAL_ERROR(,"服务器内部错误"),PARAMETER_EXCEPTION(,"请求参数校验异常"),/*业务状态码*/USER_NOT_EXIST_ERROR(,"用户不存在"),;privateIntegercode;privateStringmessage;publicIntegercode(){ returnthis.code;}publicStringmessage(){ returnthis.message;}ResultCode(Integercode,Stringmessage){ this.code=code;this.message=message;}}定义正常响应的API统一返回体@DatapublicclassResult<T>implementsSerializable{ privateIntegercode;privateStringmessage;privatebooleansuccess=true;privateTdata;@JsonIgnoreprivateResultCoderesultCode;privateResult(){ }publicvoidsetResultCode(ResultCoderesultCode){ this.resultCode=resultCode;this.code=resultCode.code();this.message=resultCode.message();}publicResult(ResultCoderesultCode,Tdata){ this.code=resultCode.code();this.message=resultCode.message();this.data=data;}publicstatic<T>Result<T>success(){ Result<T>result=newResult<>();result.setResultCode(ResultCode.SUCCESS);returnresult;}publicstatic<T>Result<T>success(Tdata){ Result<T>result=newResult<>();result.setResultCode(ResultCode.SUCCESS);result.setData(data);returnresult;}}定义异常响应的API统一返回体@DatapublicclassErrorResultimplementsSerializable{ privateIntegercode;privateStringmessage;privatebooleansuccess=false;@JsonIgnoreprivateResultCoderesultCode;publicstaticErrorResulterror(){ ErrorResultresult=newErrorResult();result.setResultCode(ResultCode.INTERNAL_ERROR);returnresult;}publicstaticErrorResulterror(Stringmessage){ ErrorResultresult=newErrorResult();result.setCode(ResultCode.INTERNAL_ERROR.code());result.setMessage(message);returnresult;}publicstaticErrorResulterror(Integercode,Stringmessage){ ErrorResultresult=newErrorResult();result.setCode(code);result.setMessage(message);returnresult;}publicstaticErrorResulterror(ResultCoderesultCode,Stringmessage){ ErrorResultresult=newErrorResult();result.setResultCode(resultCode);result.setMessage(message)returnresult;}}编写包装返回结果的自定义注解@Retention(RetentionPolicy.RUNTIME)@Target({ ElementType.TYPE,ElementType.METHOD})//作用于方法和类(接口)上@Documentedpublic@interfaceResponseResult{ }定义返回结果拦截器@ComponentpublicclassResponseResultInterceptorimplementsHandlerInterceptor{ /*使用统一返回体的标识*/privatestaticfinalStringRESPONSE_RESULT_ANNOTATION="RESPONSE-RESULT-ANNOTATION";@OverridepublicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler){ //正在处理请求的方法beanif(handlerinstanceofHandlerMethod){ finalHandlerMethodhandlerMethod=(HandlerMethod)handler;//获取当前类finalClass<?>clazz=handlerMethod.getBeanType();//获取当前方法finalMethodmethod=handlerMethod.getMethod();//判断是否在类对象上加了注解if(clazz.isAnnotationPresent(ResponseResult.class)){ //设置该请求返回体,需要包装,往下传递,在ResponseBodyAdvice接口进行判断request.setAttribute(RESPONSE_RESULT_ANNOTATION,clazz.getAnnotation(ResponseResult.class));}//判断是否在方法上加了注解elseif(method.isAnnotationPresent(ResponseResult.class)){ //设置该请求返回体,需要包装,往下传递,在ResponseBodyAdvice接口进行判断request.setAttribute(RESPONSE_RESULT_ANNOTATION,method.getAnnotation(ResponseResult.class));}}returntrue;}}WebMvc配置类拦截器注册者添加返回结果拦截器@ConfigurationpublicclassWebMvcConfigimplementsWebMvcConfigurer{ /***添加自定义拦截器*/@OverridepublicvoidaddInterceptors(InterceptorRegistryregistry){ registry.addInterceptor(newResponseResultInterceptor()).addPathPatterns("/**");}}编写响应体处理器/***统一处理响应体,用Result.success静态方法包装,*在API接口使用时就可以直接返回原始类型*/@RestControllerAdvicepublicclassResponseResultHandlerimplementsResponseBodyAdvice<Object>{ /*使用统一返回体的标识*/privatestaticfinalStringRESPONSE_RESULT_ANNOTATION="RESPONSE-RESULT-ANNOTATION";@Overridepublicbooleansupports(MethodParametermethodParameter,Class<?extendsHttpMessageConverter<?>>aClass){ ServletRequestAttributessra=(ServletRequestAttributes)RequestContextHolder.getRequestAttributes();HttpServletRequestrequest=Objects.requireNonNull(sra).getRequest();ResponseResultresponseResult=(ResponseResult)request.getAttribute(RESPONSE_RESULT_ANNOTATION);//判断返回体是否需要处理returnresponseResult!=null;}@OverridepublicObjectbeforeBodyWrite(Objectbody,MethodParametermethodParameter,MediaTypemediaType,Class<?extendsHttpMessageConverter<?>>aClass,ServerHttpRequestserverHttpRequest,ServerHttpResponseserverHttpResponse){ //异常响应体则直接返回code+message的消息体if(bodyinstanceofErrorResult){ returnbody;}//正常响应体则返回Result包装的code+message+data的消息体returnResult.success(body);}}接口调用@Api("用户管理")@RestController@RequestMapping("user")@ResponseResult//作用于类上,对所有接口有效publicclassUserController{ @AutowiredprivateUserServiceuserService;@ResponseResult//作用于方法上@ApiOperation("根据ID查询用户")@GetMapping("one")publicUserselectOne(Longid){ //由于在ResponseResultHandler中已经统一将返回数据用Result.success包装了,//直接返回原始类型即可,代码更简洁returnthis.userService.queryById(id);}@ResponseResult@ApiOperation("查询所有用户")@GetMapping("all")publicList<User>selectAll(Pagepage){ //由于在ResponseResultHandler中已经统一将返回数据用Result.success包装了,antd源码解读//直接返回原始类型即可,代码更简洁returnthis.userService.queryAllByLimit(page);}}测试结果全局异常处理编写自定义异常基类@DatapublicclassBaseExceptionextendsRuntimeException{ privatestaticfinalintBASE_EXCEPTION_CODE=ResultCode.INTERNAL_ERROR.code();privatestaticfinalStringBASE_EXCEPTION_MESSAGE=ResultCode.INTERNAL_ERROR.message();privateIntegercode;privateStringmessage;publicBaseException(){ super(BASE_EXCEPTION_MESSAGE);this.code=BASE_EXCEPTION_CODE;this.message=BASE_EXCEPTION_MESSAGE;}publicBaseException(Stringmessage){ super(message);this.code=BASE_EXCEPTION_CODE;this.message=message;}publicBaseException(ResultCoderesultCode){ super(resultCode.message());this.code=resultCode.code();this.message=resultCode.message();}publicBaseException(Throwablecause){ super(cause);this.code=BASE_EXCEPTION_CODE;this.message=BASE_EXCEPTION_MESSAGE;}publicBaseException(Stringmessage,Throwablecause){ super(message,cause);this.code=BASE_EXCEPTION_CODE;this.message=message;}publicBaseException(Integercode,Stringmessage){ super(message);this.code=code;this.message=message;}publicBaseException(Integercode,Stringmessage,Throwablecause){ super(message,cause);this.code=code;this.message=message;}}编写自定义业务异常类publicclassBizExceptionextendsBaseException{ publicBizException(ResultCoderesultCode){ super(resultCode);}}定义全局异常处理类通过@ExceptionHandler注解来统一处理某一类异常
@DatapublicclassResult<T>implementsSerializable{ privateIntegercode;privateStringmessage;privatebooleansuccess=true;privateTdata;@JsonIgnoreprivateResultCoderesultCode;privateResult(){ }publicvoidsetResultCode(ResultCoderesultCode){ this.resultCode=resultCode;this.code=resultCode.code();this.message=resultCode.message();}publicResult(ResultCoderesultCode,Tdata){ this.code=resultCode.code();this.message=resultCode.message();this.data=data;}publicstatic<T>Result<T>success(){ Result<T>result=newResult<>();result.setResultCode(ResultCode.SUCCESS);returnresult;}publicstatic<T>Result<T>success(Tdata){ Result<T>result=newResult<>();result.setResultCode(ResultCode.SUCCESS);result.setData(data);returnresult;}}0接口调用@DatapublicclassResult<T>implementsSerializable{ privateIntegercode;privateStringmessage;privatebooleansuccess=true;privateTdata;@JsonIgnoreprivateResultCoderesultCode;privateResult(){ }publicvoidsetResultCode(ResultCoderesultCode){ this.resultCode=resultCode;this.code=resultCode.code();this.message=resultCode.message();}publicResult(ResultCoderesultCode,Tdata){ this.code=resultCode.code();this.message=resultCode.message();this.data=data;}publicstatic<T>Result<T>success(){ Result<T>result=newResult<>();result.setResultCode(ResultCode.SUCCESS);returnresult;}publicstatic<T>Result<T>success(Tdata){ Result<T>result=newResult<>();result.setResultCode(ResultCode.SUCCESS);result.setData(data);returnresult;}}1测试结果作者:l拉不拉米
java-增强版Comparator进行集合排序null异常处理
在Java开发中,我们有时会遇到使用增强版Comparator对集合进行排序时遇到null异常的问题。例如,当尝试对一个Student对象列表按照no、age、name和money进行排序时,如果列表中存在未赋值的no或money,就可能导致NullPointerException。为了解决这个问题,我们可以通过查阅Comparator的源码来找到解决策略。
Comparator类中的Objects.requireNonNull方法确保了比较对象和字段不能为空。针对null值,Comparator提供了两个有用的静态方法:nullsFirst和nullsLast。这两个方法分别将null视为小于或大于非null值,从而避免了排序时的null异常。例如,靓号 源码可以将代码修改为:
dataList.sort(Comparator.comparing(Student::getNo, Comparator.nullsFirst(String::compareTo).reversed()).thenComparing(Student::getAge)
.thenComparing(Student::getName).thenComparing(Student::getMoney));
在这个修改后的代码中,我们首先对no字段使用了nullsFirst,确保了null值的排序位置。Comparator.comparing方法允许我们指定比较函数,而Comparator.thenComparing则支持多字段排序。
除了这些,Comparator还提供了其他一些方法,如reversed、reverseOrder、naturalOrder等,用于调整排序顺序。比如,Comparator.reverseOrder()会反转排序顺序,Comparator.naturalOrder()则按照对象的自然顺序进行排序。这些方法可以根据实际需求灵活运用。
总的来说,通过使用Comparator的exoplayer源码详解nullsFirst和nullsLast方法,我们可以有效地处理Java集合排序时的null异常问题,使得代码更加健壮。更多关于Comparator的方法可以参考Java 8的官方开发文档。
Java如何生成版本号?比如
首先还是不太明白你说的这个“生成版本号”是什么意思,如果只是生成一个自增序列的话1、如果有oracle数据库的话可以利用它的序列生成。
2、没有oracle,用redis也行。
3、没有数据库,那就写个文件来存取吧:
public class Test2 {
public static void main(String[] args) throws IOException {
System.out.println(getSequence("d:\\test\\sequence.txt"));
setSequence("d:\\test\\sequence.txt", "");
System.out.println(getSequence("d:\\test\\sequence.txt"));
}
//读取序列
public static String getSequence(String sequenceFile) throws IOException {
FileInputStream fileInputStream = null;
InputStreamReader inputStreamReader = null;
BufferedReader bufferedReader = null;
try {
File file = new File(sequenceFile);
fileInputStream = new FileInputStream(file);
inputStreamReader = new InputStreamReader(fileInputStream);
bufferedReader = new BufferedReader(inputStreamReader);
// 按行读取字符串
String str;
if ((str = bufferedReader.readLine()) != null) {
return str;
}
return null;
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
if (bufferedReader != null) {
bufferedReader.close();
}
if (inputStreamReader != null) {
inputStreamReader.close();
}
if (fileInputStream != null) {
fileInputStream.close();
}
}
}
//设置序列,如果传入的序列号为空,则在原序列的基础上+1
public static void setSequence(String sequenceFile, String sequence) throws IOException {
if (sequence == null || sequence.isEmpty()) {
String oriSequence = getSequence(sequenceFile);
Objects.requireNonNull(oriSequence);
sequence = String.format("%d", Integer.valueOf(oriSequence) + 1);
}
FileOutputStream fileOutputStream = null;
OutputStreamWriter outputStreamWriter = null;
BufferedWriter bufferedWriter = null;
try {
File file = new File(sequenceFile);
fileOutputStream = new FileOutputStream(file);
outputStreamWriter = new OutputStreamWriter(fileOutputStream);
bufferedWriter = new BufferedWriter(outputStreamWriter);
bufferedWriter.write(sequence);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (bufferedWriter != null) {
bufferedWriter.close();
}
if (outputStreamWriter != null) {
outputStreamWriter.close();
}
if (fileOutputStream != null) {
fileOutputStream.close();
}
}
}
}
代码又挤在一起了:
读序列:
写序列:运行结果:
先生成好这个文件:
冲!:
java中的空指针异常如何处理?
处理 Java 中的空指针异常主要涉及问题定位、解决方法以及预防策略。在堆栈异常信息的第一行,可以定位到是哪里出现了空指针。对于非自定义类的空指针问题,检查代码的逻辑,找到相关类,问题一般出在该类或其方法上。对于空对象调用方法或属性导致的空指针异常,主要问题在于对象为空。
解决这类问题的步骤包括:
1. **运行时检测**:使用 `if (obj == null)` 检测所有对象,包括参数、返回值和类实例成员变量。当检测到 null 值时,可抛出 `IllegalArgumentException` 并附带具体信息。引入如 Java 7 开始提供的 `Objects#requireNonNull` 方法简化代码。此外,使用 Guava 的 `Preconditions` 类中提供的空值检测工具函数,或借助 Lombok 自动生成空值检测代码,并抛出带有提示信息的空指针异常。
2. **编程规范**:通过编程规范减少空指针异常的发生。使用已对 null 值做判断的方法,如 `String#equals`、`String#valueOf` 等。对于可接收 null 的参数,考虑使用两个函数,通过不同的函数签名强制每个参数都不为空。避免返回 null 的空集合,而是返回一个空集合或抛出异常。Spring JdbcTemplate 就采用了这种处理方式。
3. **静态代码分析**:利用静态代码分析工具如 Eclipse IDE、SpotBugs、Checker Framework 等,结合 `@Nullable` 和 `@Nonnull` 注解,进行编译期的空值检测。虽然空值检测注解尚未标准化,但使用如 SpotBugs 或 Checker Framework 这样的工具,可以有效检测可能抛出空指针异常的代码。这些工具在 Maven 或 Eclipse 等 IDE 中的集成,提供了跨 IDE 的解决方案。
4. **使用 Optional 类型**:Java 8 引入的 `Optional` 类型,用以明确表示方法的返回值可能是空值。将返回值包装为 `Optional` 可以避免空指针异常,同时需要编写更多代码以处理空值情况,需权衡性能与代码清晰度。
5. **其他 JVM 语言中的解决方案**:Scala 使用 `Option` 类与 Java 8 的 `Optional` 类型类似,提供 `Some` 和 `None` 两种状态。Kotlin 强调类型区分,用户需在定义变量时明确类型,并进行空值检测。这些语言中提供的类型系统和注解机制,为预防空指针异常提供了支持。
综上所述,采用注解进行空值检测是较为推荐的方法,它在代码中注入了预防逻辑,同时对代码的侵入性较小。所有公共 API 应使用 `@Nullable` 和 `@NonNull` 进行注解,这样可以强制调用方预防空指针异常,提升程序的健壮性。
不含npe是什么意思?
NPE是“空指针异常”的缩写。在Java编程中,当程序试图使用一个空对象时,就会出现NPE异常。换句话说,当程序试图调用一个对象的方法或属性,而该对象指向null时,就会抛出NPE异常。由于NPE是编程中常见的错误之一,程序员应该尽可能避免它的发生。
NPE异常是Java编程中最常见的错误之一,它会导致程序的不稳定甚至崩溃。如果NPE异常没有被正确处理,会对应用程序的安全和稳定性造成巨大的影响。因此,它是必须尽力避免的。
为了避免NPE异常的发生,程序员应该始终保证在使用对象之前检查其是否为空。对于可能为空的对象,应该在使用时先进行非空判断。此外,还可以使用一些工具来帮助检测和避免NPE异常的发生,如Guava库中的Objects.requireNonNull()方法。通过这些方法,可以有效地减少NPE异常的出现,提高应用程序的安全性和可靠性。