Невозможно сделать поле закрытым Final java.lang.Object[] java.util.ImmutableCollections$ListN.elements доступнымJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Невозможно сделать поле закрытым Final java.lang.Object[] java.util.ImmutableCollections$ListN.elements доступным

Сообщение Anonymous »

Я хочу установить значение по умолчанию, когда json ответа HTTP возвращает значение null. если типом является строка, установите значение по умолчанию «», если типом является список, установите значение по умолчанию []. это действие позволит клиентской стороне легко проверить ответ. Вот код Java, как я это делаю:

Код: Выделить всё

package com.guannet.you.admin.rest.aop;

import com.guannet.frame.web.core.RestResult;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@ControllerAdvice
public class ResponseBodyDefaultValueAdvice implements ResponseBodyAdvice beforeBodyWrite(RestResult body, @NotNull MethodParameter returnType, @NotNull MediaType selectedContentType, Class> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
if (Objects.isNull(body)) {
return null;
}
Object data = body.getData();
if (Objects.nonNull(data)) {
setDefault(data);
return body;
}
var field = ReflectionUtils.findField(body.getClass(), "data");
if (Objects.nonNull(field)) {
data = BeanUtils.instantiateClass(field.getType());
}
if (Objects.nonNull(data)) {
setDefault(data);
}
return body;
}

private void setDefault(Object obj) {
ReflectionUtils.doWithFields(obj.getClass(), field -> {
ReflectionUtils.makeAccessible(field);
Object val = ReflectionUtils.getField(field, obj);
if (val != null) {
return;
}
Object defaultValue = null;
if (field.getType() == String.class) {
defaultValue = "";
} else if (field.getType() == List.class) {
defaultValue = Collections.emptyList();
} else if (field.getType() == Map.class) {
defaultValue = Collections.emptyMap();
}
ReflectionUtils.setField(field, obj, defaultValue);
});
}
}
но когда я запускаю этот код в JDK 21, появляется такая ошибка:

Код: Выделить всё

2024-10-15 09:59:24:210 [t-1] [http-nio-6100-exec-4] ERROR c.g.y.admin.support.AdminGlobalExceptionHandler - service error
java.lang.reflect.InaccessibleObjectException: Unable to make field private final java.lang.Object[] java.util.ImmutableCollections$ListN.elements accessible: module java.base does not "opens java.util"  to unnamed module @7a362b6b
at java.base/java.lang.reflect.AccessibleObject.throwInaccessibleObjectException(AccessibleObject.java:391)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:367)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:315)
at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:183)
at java.base/java.lang.reflect.Field.setAccessible(Field.java:177)
at org.springframework.util.ReflectionUtils.makeAccessible(ReflectionUtils.java:804)
at com.guangdanet.youxue.admin.rest.aop.ResponseBodyDefaultValueAdvice.lambda$setDefault$0(ResponseBodyDefaultValueAdvice.java:52)
at org.springframework.util.ReflectionUtils.doWithFields(ReflectionUtils.java:728)
at org.springframework.util.ReflectionUtils.doWithFields(ReflectionUtils.java:707)
at com.guangdanet.youxue.admin.rest.aop.ResponseBodyDefaultValueAdvice.setDefault(ResponseBodyDefaultValueAdvice.java:51)
at com.guangdanet.youxue.admin.rest.aop.ResponseBodyDefaultValueAdvice.beforeBodyWrite(ResponseBodyDefaultValueAdvice.java:37)
at com.guangdanet.youxue.admin.rest.aop.ResponseBodyDefaultValueAdvice.beforeBodyWrite(ResponseBodyDefaultValueAdvice.java:23)
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyAdviceChain.processBody(RequestResponseBodyAdviceChain.java:141)
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyAdviceChain.beforeBodyWrite(RequestResponseBodyAdviceChain.java:116)
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:288)
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:190)
at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:78)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:136)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:920)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:830)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:527)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
похоже, что список ответов неизменен и не позволяет изменяться. что мне следует сделать, чтобы установить значение по умолчанию для ответа? Вот так выглядит RestResult:

Код: Выделить всё

public class RestResult {
private int code = HttpStatus.OK.value();
private boolean success;
private String message = "";
private Content data;
}
содержимое ответа — json.

Подробнее здесь: https://stackoverflow.com/questions/790 ... blecollect
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»