I have a POJO that extends another class ParentDTO both using Lombok with builder Pattern
ChildDTO
#Getter
#ToString
#EqualsAndHashCode(callSuper = false)
#SuperBuilder(toBuilder = true)
#AllArgsConstructor(access = AccessLevel.PRIVATE)
public class ChildDTO extends ParentDTO {
private final Foo foo; // Foo also extends ParentDTO
#Singular("items")
private final List<Item> items;
}
ParentDTO
#Data
#SuperBuilder(toBuilder = true)
public abstract class ParentDTO implements Serializable {
#JsonIgnore private final ObjectMapper objectMapper = new ObjectMapper();
protected ParentDTO () {}
}
My Code Implementation(here I am getting error in gson.toJson)
#PostMapping("/sendRequest")
public ResponseEntity<String> sendMessage(#RequestBody ChildDTO payload) {
final ChildDTO childDTO = payload.toBuilder().bar("xyz").build();
String serializedData = gson.toJson(childDTO); //getting stackoverflow exception in this line.
publishMesaage(serializedData);
return new ResponseEntity<>(HttpStatus.OK);
}
I am seeing the stackoverflow error happening in line gson.toJson(childDTO) when trying to use Gson.
java.lang.StackOverflowError
at java.lang.System.arraycopy(Native Method)
at java.lang.String.getChars(String.java:826)
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:449)
at java.lang.StringBuffer.append(StringBuffer.java:270)
at java.io.StringWriter.write(StringWriter.java:112)
at com.google.gson.stream.JsonWriter.string(JsonWriter.java:590)
at com.google.gson.stream.JsonWriter.writeDeferredName(JsonWriter.java:401)
at com.google.gson.stream.JsonWriter.beginObject(JsonWriter.java:308)
at
Related
I try to create a facebook messenger bot
I tried Victor de la Cruz method,the code is below
, and here is the origin code:
https://www.codementor.io/#vcg_cruz/a-facebook-messenger-bot-m2g6wgcxb#comments-m2g6wgcxb
it works but when I send a message it generates an infinite loop of conversation
this the result screen shot
#RestController()
#RequestMapping("webhook")
public class WebHook {
private final String PAGE_TOKEN ="THIS_IS_THE_TOKEN_YOU_COPIED_BEFORE";
private final String VERIFY_TOKEN="A_SECRET_VERIFY_TOKEN";
//this is for reply messages
private final String FB_MSG_URL="https://graph.facebook.com/v2.6/me/messages?access_token="
+ PAGE_TOKEN;
//logger to watch whats happening in our bot
private final Logger logger = LoggerFactory.getLogger(WebHook.class);
private final RestTemplate template = new RestTemplate();
//This is necessary for register a webhook in facebook
#GetMapping()
#ResponseStatus(HttpStatus.OK)
public String get(#RequestParam(name = "hub.verify_token")String token,
#RequestParam(name = "hub.challenge")String challenge){
if(token!=null && !token.isEmpty() && token.equals(VERIFY_TOKEN)){
return challenge;
}else{
return "Wrong Token";
}
}
//This method reply all messages with: 'This is a test message'
#PostMapping
#ResponseStatus(HttpStatus.OK)
public void post(#RequestBody FacebookHookRequest request){
logger.info("Message from chat: {}",request);
request.getEntry().forEach(e->{
e.getMessaging().forEach(m->{
String id = m.getSender().get("id");
sendReply(id,"This is a test message");
});
});
}
private void sendReply(String id,String text){
FacebookMessageResponse response = new FacebookMessageResponse();
response.setMessage_type("text");
response.getRecipient().put("id",id);
response.getMessage().put("text",text);
HttpEntity<FacebookMessageResponse> entity = new HttpEntity<>(response);
String result = template.postForEntity(FB_MSG_URL,entity,String.class).getBody();
logger.info("Message result: {}",result);
}
}
/************************************/
#Data
#NoArgsConstructor
#AllArgsConstructor
#ToString
public class FacebookEntry implements Serializable {
private String id;
private Long time;
private List<FacebookMessaging> messaging = new ArrayList<>();
}
#Data
#NoArgsConstructor
#AllArgsConstructor
#ToString
public class FacebookHookRequest implements Serializable {
private String object;
private List<FacebookEntry> entry = new ArrayList<>();
}
#Data
#NoArgsConstructor
#AllArgsConstructor
#ToString
public class FacebookMessage implements Serializable {
private String mid;
private Long seq;
private String text;
}
#Data
#NoArgsConstructor
#AllArgsConstructor
#ToString
public class FacebookMessageResponse implements Serializable {
private String message_type;
private Map<String,String> recipient = new HashMap<>();
private Map<String,String> message = new HashMap<>();
}
#Data
#NoArgsConstructor
#AllArgsConstructor
#ToString
public class FacebookMessaging implements Serializable {
private Map<String,String> sender;
private Map<String,String> recipient;
private Long timestamp;
private FacebookMessage message;
}
You're responding to yourself I assume. Similar to how the Discord API works, your post method is being called when you receive your own message. You most likely want to check if the message author is from yourself.
I have a Object that I would like Jackson to serialize like this...
<AccountsResponse>
<accounts>
<account/>
<account>
<userId>user</userId>
...
</account>
</accounts>
</AccountsResponse>
To try this I create the following class...
#Getter
#Setter
#ToString
#JsonInclude(JsonInclude.Include.NON_EMPTY)
public class Payload {
#JacksonXmlProperty(localName = "errormessage")
private String errorMessage;
}
#Getter
#Setter
#ToString
public class AccountsResponse extends Payload{
#JsonIgnore
private static Logger LOGGER = LogManager.getLogger(AccountsResponse.class);
#JacksonXmlProperty(localName = "accounts")
private List<Account> accounts = Lists.newArrayList();
public static AccountsResponse mapFromResultSet(ResultSet rs)
throws SQLException
{
AccountsResponse response = new AccountsResponse();
do {
Account acct = Account.mapFromResultSet(rs);
response.getAccounts().add(acct);
} while (rs.next());
return response;
}
public String toXml() throws JsonProcessingException {
ObjectMapper mapper = new XmlMapper();
return mapper.writeValueAsString(this);
}
}
#Getter
#Setter
#JsonInclude(JsonInclude.Include.NON_NULL)
public class Account extends ResultSetParser{
...
}
But when I serialize I get...
<AccountsResponse>
<accounts>
<accounts/>
<accounts>
<userId>user</userId>
...
</accounts>
</accounts>
</AccountsResponse>
As you can see the problem here is the child tags should be account but in fact are accounts. I tried hacking around with the localname but can't find the right mixture of VooDoo. What am I doing wrong?
I would change annotations on account list in AccountsResponse:
public class AccountsResponse extends Payload{
#JacksonXmlElementWrapper(localName = "accounts")
#JacksonXmlProperty(localName = "account")
private List<Account> accounts = Lists.newArrayList();
}
I've been struggling with the following issue for a few hours now, and I can't figure it out how to make it work:
Spring mapper, in order to convert DB response to DTO:
#Mapper(componentModel = "spring")
public interface ITeamResponseToDtoMapper {
TeamResponseDTO toDto(TeamResponse teamResponse);
}
TeamResponse class:
#Data
#NoArgsConstructor
public class TeamResponse {
private Map<String, List<NameAndType>> teamList;
}
NameAndType class:
#Data
#NoArgsConstructor
#AllArgsConstructor(access = AccessLevel.PUBLIC)
public class NameAndType{
private String name;
private String type;
private String team;
}
TeamResponseDTO class:
#Data
#NoArgsConstructor
public class TeamResponseDTO {
private Map<String, List<NameAndTypeDTO >> teamList;
}
NameAndTypeDTO class:
#Data
#NoArgsConstructor
#AllArgsConstructor(access = AccessLevel.PUBLIC)
public class NameAndTypeDTO {
private String name;
private String type;
private String team;
}
Basically, 'NameAndType' and 'NameAndTypeDTO' are the same, why it fails to do the conversion?
error: Can't map property "java.util.Map<java.lang.String,java.util.List<com.microservices.teamservice.dataobjects.NameAndType>> teamList" to "java.util.Map<java.lang.String,java.util.List<com.microservices.teamservice.api.dataobjects.NameAndTypeDTO>> teamList". Consider to declare/implement a mapping method:
I think you need to explicit add methods to map the whole chain of classes. On your example the following should work:
#Mapper(componentModel = "spring")
public interface ITeamResponseToDtoMapper {
TeamResponseDTO toDto(TeamResponse teamResponse);
List<NameAndTypeDTO> natListToDTO(List<NameAndType> natList);
NameAndTypeDTO nameAndTypeToDTO(NameAndType nameAndType);
}
regards,
WiPu
I am getting these error while integrating the spring-boot with JPA repository
here is the code
#CrossOrigin(origins = "http://localhost:4200")
#RestController
#RequestMapping("/api")
public class EmpController {
#Autowired
private CrudRepo crud;
#Autowired
private AddrCrudRepo addr;
#Autowired
private EntityManager entity;
//#Autowired
//private ModelMapper mapper;
private static int count = 0;
#Bean
public ModelMapper model() {
return new ModelMapper();
}
//#Autowired
// public EmpController(ModelMapper mapper) {
// this.mapper = mapper;
// }
#RequestMapping(path = "/post-addr", method = RequestMethod.POST)
public List<AddressModel> postAddr(#Valid #RequestBody List<AddressRequest> addr1){
// crud.findById(id)
//AddressModel list = new AddressModel();
EmployeeModel emp = new EmployeeModel();
System.out.println("CALLING THE MAPPER "+addr1);
List<AddressModel> addr_list = ObjectMapperUtils.mapAll(addr1, AddressModel.class);
System.out.println("CALLED THE MAPPER "+addr_list);
addr_list.forEach((a) -> {
crud.findById(a.getEmpId()).ifPresent((b) -> {
System.out.println(this.count++);
a.setEmp_id(b);
b.getAddress().add(a);
});
});
// AddressModel addr_list = model().map(addr1, AddressModel.class);
//
// crud.findById(addr1.getEmp_id()).ifPresent((b) -> {
// addr_list.setEmp_id(b);
//
// });`enter code here`
System.out.println(addr_list.size());
List<AddressModel> addr3 = addr.saveAll(addr_list);
System.out.println(addr3);
return addr_list;
}
getting an error in the postAddr method as when it returns the List<AddressModel> and here is the AddressModel
#Entity
#Table(name="Emp_Address")
public class AddressModel implements Serializable{
#Column(name="address_id")
#Id
private Integer address_id;
#Column(name="city")
private String city;
#Column(name="states")
private String states;
#Transient
private Integer empId;
#ManyToOne
#JoinColumn(name="emp_id")
private EmployeeModel emp_id;
public AddressModel() {
}
//getter and setter
and EmployeeModel
#Entity
#Table(name="Employee")
public class EmployeeModel implements Serializable{
#Column(name="Emp_id")
#Id
private Integer emp_id;
#Column(name="Emp_Name")
private String emp_name;
#OneToMany(mappedBy="emp_id")
private Collection<AddressModel> address = new ArrayList<>();
public EmployeeModel() {
}
//getter and setters
so while saveAll is done properly but when the postAddr method returns the List it throws the StackOverflow
This StackOverflow error is coming because generated toString methods of both classes are circularly dependent on each other.
EmployeeModel tries to print AddressModel but again AddressModel tries to print EmployeeModel and hence the error.
Try removing AddressModel from toString method of EmployeeModel class or reverse, remove EmployeeModel from toString method of AddressModel class.
Hi i need mappig variables to request. How can i mapp into List.
My request looks like.
public class Request {
private String Id;
private List<Data> applicationData;
#Data
#NoArgsConstructor
#AllArgsConstructor
public static class Data {
private String data1;
private String data2;
private String data3;
}
}
and my mapper
#Mapper(componentModel = "spring")
public abstract class RequestMapper {
#Mapping(target = "Id", source = "data.Id")
#Mapping(target = "data.???.data1", source = "data.data1")
#Mapping(target = "data.???.data2", source = "data.data2")
#Mapping(target = "applicationData.???.data3", source = "data.data3")
public abstract Request map(Data variables);
}
From what I understand you want to map your values into a singleton list. You can achieve that by providing 2 new methods in your mapper.
You mapper would look like:
#Mapper(componentModel = "spring")
public abstract class RequestMapper {
#Mapping(target = "Id", source = "Id")
#Mapping(target = "data", source = "variables")
public abstract Request map(Data variables);
protected List<Data> mapToList(Data variables) {
return variables == null ? null : mapToApplication(variables);
}
//Add mappings if they are needed
protected abstract ApplicationData mapToApplication(Data variables);
}