如何在我的 spring boot rest 服务中将字符串写入 POJO 转换器?
How to write a String to POJO converter in my spring boot rest service?
我有一个 JavaFX 客户端,它使用 Spring Boot v2.0.0 中实现的 Rest 服务,在开发时我确实创建了一个控制器,其中它有一个 POJO 列表作为 [=34 中的请求参数=] 请求以便我可以在一次调用中添加一组实体对象
这是我到目前为止所做的
我的控制器:
@PostMapping
private ServerResponse creatAllCompDatas(
@RequestParam final List<ComponentDataForm> componentDataFormValues
) {
if (isSessionValid()) {
List<Long> datasIds = new ArrayList();
componentDataFormValues.stream().forEach(formValue -> {
MNG_COMPOSANT_DATA mng_composant_data = new MNG_COMPOSANT_DATA();
mng_composant_data.setCmp_attr_code(formValue.getAttCode());
mng_composant_data.setCmp_attr_label(formValue.getAttTitle());
mng_composant_data.setCmp_attr_value(formValue.getAttVal());
datasIds.add(mng_composant_data.getId());
});
initSuccessResponse(datasIds);
return serverResponse;
}
initFailLoginResponse();
return serverResponse;
}
我的 ComponentDataForm POJO(本例中为 DTO)
@Component
public class ComponentDataForm {
@JsonProperty("attCode")
private String attCode;
@JsonProperty("attTitle")
private String attTitle;
@JsonProperty("attVal")
private String attVal;
public ComponentDataForm() {
}
public String getAttCode() {
return attCode;
}
public void setAttCode(String attCode) {
this.attCode = attCode;
}
public String getAttTitle() {
return attTitle;
}
public void setAttTitle(String attTitle) {
this.attTitle = attTitle;
}
public String getAttVal() {
return attVal;
}
public void setAttVal(String attVal) {
this.attVal = attVal;
}
@Override
public int hashCode() {
int hash = 7;
hash = 29 * hash + Objects.hashCode(this.attCode);
hash = 29 * hash + Objects.hashCode(this.attTitle);
hash = 29 * hash + Objects.hashCode(this.attVal);
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final ComponentDataForm other = (ComponentDataForm) obj;
if (!Objects.equals(this.attCode, other.attCode)) {
return false;
}
if (!Objects.equals(this.attTitle, other.attTitle)) {
return false;
}
if (!Objects.equals(this.attVal, other.attVal)) {
return false;
}
return true;
}
@Override
public String toString() {
return "ComponentDataForm{" + "attCode=" + attCode + ", attTitle=" + attTitle + ", attVal=" + attVal + '}';
}
public ComponentDataForm(String attCode, String attTitle, String attVal) {
this.attCode = attCode;
this.attTitle = attTitle;
this.attVal = attVal;
}
}
通过这个我恢复了我的后端
现在我将向您提供我的前端 Javafx :
@FXML
private void doCommit(ActionEvent event) throws UnirestException{
if(validate()){
final ObservableList<AppDataAttTDO> items = tableAtributes.getItems();
final List<ComponentDataForm> componentDataFormValues = new ArrayList();
items.stream().forEach(item -> {
final ComponentDataForm requestItem = new ComponentDataForm();
requestItem.setAttCode(item.getAttCode());
requestItem.setAttTitle(item.getAttTitle());
requestItem.setAttVal(item.getAttValue());
componentDataFormValues.add(requestItem);
});
HttpResponse<String> asString = Unirest.post(APPLICATION_DATA_SERVICE_URL)
.queryString("componentDataFormValues", componentDataFormValues)
.asString();
System.out.println(asString.getStatus());
System.out.println(asString.getBody());
}
}
当我将客户端的请求提交到服务器时,服务器抛出以下异常
2018-05-17 14:47:24.970 WARN 3660 --- [nio-8443-exec-7] .w.s.m.s.DefaultHandlerExceptionResolver : Failed to convert request element: org.springframework.web.method.annotation.MethodArgumentConversionNotSupportedException: Failed to convert value of type 'java.lang.String[]' to required type 'java.util.List'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'com.easyData.pos.easyPos.rest.contoller.application.ComponentDataForm': no matching editors or conversion strategy found
2018-05-17 14:47:24.970 WARN 3660 --- [nio-8443-exec-7] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved exception caused by Handler execution: org.springframework.web.method.annotation.MethodArgumentConversionNotSupportedException: Failed to convert value of type 'java.lang.String[]' to required type 'java.util.List'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'com.easyData.pos.easyPos.rest.contoller.application.ComponentDataForm': no matching editors or conversion strategy found
经过 1 天的研究,我明白我需要创建一个转换器,通过扩展 org.springframework.core.convert.converter.Converter;
接口来创建一个 String,ComponentDataForm 转换器[=16,它将接收到的请求参数解析为我的 POJO =]
但是我卡住了,我不知道如何编写这个转换器。
所以我迷路了,直到我动了脑筋,想出了一个主意
我的 pojo 是一个在后端和前端之间共享的 DTO,所以知道我不知道如何转换我确实说过为什么不将这个过程委托给一些机制
杰克逊来了api
我重写了 toString dto 的方法来编写当前 pojo 的 json 字符串,在转换器中我所拥有的只是使用 ObjectMapper
来读取这个 json 将其解析为我的 pojo(DTO 对象)
这是我的实现
@Override
public String toString() {
try {
return new ObjectMapper().writeValueAsString(this);
} catch (JsonProcessingException ex) {
Logger.getLogger(ApplicationFormAddController.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
我的转换器
public class AppDataFormConverter implements Converter<String, ComponentDataForm>{
@Override
public ComponentDataForm convert(String s) {
System.out.println(s);
ObjectMapper objectMapper = new ObjectMapper();
try {
return objectMapper.readValue(s, ComponentDataForm.class);
} catch (IOException ex) {
Logger.getLogger(AppDataFormConverter.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("handled here");
return new ComponentDataForm();
}
}
和转换器注册过程
@Configuration
public class ConvertersConfig extends WebMvcConfigurerAdapter{
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new AppDataFormConverter());
super.addFormatters(registry); //To change body of generated methods, choose Tools | Templates.
}
}
我有一个 JavaFX 客户端,它使用 Spring Boot v2.0.0 中实现的 Rest 服务,在开发时我确实创建了一个控制器,其中它有一个 POJO 列表作为 [=34 中的请求参数=] 请求以便我可以在一次调用中添加一组实体对象
这是我到目前为止所做的
我的控制器:
@PostMapping
private ServerResponse creatAllCompDatas(
@RequestParam final List<ComponentDataForm> componentDataFormValues
) {
if (isSessionValid()) {
List<Long> datasIds = new ArrayList();
componentDataFormValues.stream().forEach(formValue -> {
MNG_COMPOSANT_DATA mng_composant_data = new MNG_COMPOSANT_DATA();
mng_composant_data.setCmp_attr_code(formValue.getAttCode());
mng_composant_data.setCmp_attr_label(formValue.getAttTitle());
mng_composant_data.setCmp_attr_value(formValue.getAttVal());
datasIds.add(mng_composant_data.getId());
});
initSuccessResponse(datasIds);
return serverResponse;
}
initFailLoginResponse();
return serverResponse;
}
我的 ComponentDataForm POJO(本例中为 DTO)
@Component
public class ComponentDataForm {
@JsonProperty("attCode")
private String attCode;
@JsonProperty("attTitle")
private String attTitle;
@JsonProperty("attVal")
private String attVal;
public ComponentDataForm() {
}
public String getAttCode() {
return attCode;
}
public void setAttCode(String attCode) {
this.attCode = attCode;
}
public String getAttTitle() {
return attTitle;
}
public void setAttTitle(String attTitle) {
this.attTitle = attTitle;
}
public String getAttVal() {
return attVal;
}
public void setAttVal(String attVal) {
this.attVal = attVal;
}
@Override
public int hashCode() {
int hash = 7;
hash = 29 * hash + Objects.hashCode(this.attCode);
hash = 29 * hash + Objects.hashCode(this.attTitle);
hash = 29 * hash + Objects.hashCode(this.attVal);
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final ComponentDataForm other = (ComponentDataForm) obj;
if (!Objects.equals(this.attCode, other.attCode)) {
return false;
}
if (!Objects.equals(this.attTitle, other.attTitle)) {
return false;
}
if (!Objects.equals(this.attVal, other.attVal)) {
return false;
}
return true;
}
@Override
public String toString() {
return "ComponentDataForm{" + "attCode=" + attCode + ", attTitle=" + attTitle + ", attVal=" + attVal + '}';
}
public ComponentDataForm(String attCode, String attTitle, String attVal) {
this.attCode = attCode;
this.attTitle = attTitle;
this.attVal = attVal;
}
}
通过这个我恢复了我的后端
现在我将向您提供我的前端 Javafx :
@FXML
private void doCommit(ActionEvent event) throws UnirestException{
if(validate()){
final ObservableList<AppDataAttTDO> items = tableAtributes.getItems();
final List<ComponentDataForm> componentDataFormValues = new ArrayList();
items.stream().forEach(item -> {
final ComponentDataForm requestItem = new ComponentDataForm();
requestItem.setAttCode(item.getAttCode());
requestItem.setAttTitle(item.getAttTitle());
requestItem.setAttVal(item.getAttValue());
componentDataFormValues.add(requestItem);
});
HttpResponse<String> asString = Unirest.post(APPLICATION_DATA_SERVICE_URL)
.queryString("componentDataFormValues", componentDataFormValues)
.asString();
System.out.println(asString.getStatus());
System.out.println(asString.getBody());
}
}
当我将客户端的请求提交到服务器时,服务器抛出以下异常
2018-05-17 14:47:24.970 WARN 3660 --- [nio-8443-exec-7] .w.s.m.s.DefaultHandlerExceptionResolver : Failed to convert request element: org.springframework.web.method.annotation.MethodArgumentConversionNotSupportedException: Failed to convert value of type 'java.lang.String[]' to required type 'java.util.List'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'com.easyData.pos.easyPos.rest.contoller.application.ComponentDataForm': no matching editors or conversion strategy found
2018-05-17 14:47:24.970 WARN 3660 --- [nio-8443-exec-7] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved exception caused by Handler execution: org.springframework.web.method.annotation.MethodArgumentConversionNotSupportedException: Failed to convert value of type 'java.lang.String[]' to required type 'java.util.List'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'com.easyData.pos.easyPos.rest.contoller.application.ComponentDataForm': no matching editors or conversion strategy found
经过 1 天的研究,我明白我需要创建一个转换器,通过扩展 org.springframework.core.convert.converter.Converter;
接口来创建一个 String,ComponentDataForm 转换器[=16,它将接收到的请求参数解析为我的 POJO =]
但是我卡住了,我不知道如何编写这个转换器。
所以我迷路了,直到我动了脑筋,想出了一个主意
我的 pojo 是一个在后端和前端之间共享的 DTO,所以知道我不知道如何转换我确实说过为什么不将这个过程委托给一些机制
杰克逊来了api
我重写了 toString dto 的方法来编写当前 pojo 的 json 字符串,在转换器中我所拥有的只是使用 ObjectMapper
来读取这个 json 将其解析为我的 pojo(DTO 对象)
这是我的实现
@Override
public String toString() {
try {
return new ObjectMapper().writeValueAsString(this);
} catch (JsonProcessingException ex) {
Logger.getLogger(ApplicationFormAddController.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
我的转换器
public class AppDataFormConverter implements Converter<String, ComponentDataForm>{
@Override
public ComponentDataForm convert(String s) {
System.out.println(s);
ObjectMapper objectMapper = new ObjectMapper();
try {
return objectMapper.readValue(s, ComponentDataForm.class);
} catch (IOException ex) {
Logger.getLogger(AppDataFormConverter.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("handled here");
return new ComponentDataForm();
}
}
和转换器注册过程
@Configuration
public class ConvertersConfig extends WebMvcConfigurerAdapter{
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new AppDataFormConverter());
super.addFormatters(registry); //To change body of generated methods, choose Tools | Templates.
}
}