I'm working on a RestWebService using Resteasy. The basic implementation works fine. Know I tried to return a Complexer- Object through rest...
Actually its pretty easy..I thought. I'm getting a problem because of my nested object (Address)...
What I try is this:
#XmlRootElement(name = "person")
#XmlAccessorType(XmlAccessType.FIELD)
public class Person implements Serializable {
private static final long serialVersionUID = 1199647317278849602L;
private String uri;
private String vName;
private String nName;
private Address address;
.....
#XmlElementWrapper(name="Former-User-Ids")
#XmlElement(name="Adress")
public Address getAddress() {
return address;
}
....
Address looks like this:
#XmlRootElement(name = "address")
#XmlAccessorType(XmlAccessType.FIELD)
public class Address {
private String uri;
private String street;
private String city;
public String getCity() {
return city;
}
public String getStreet() {
return street;
}
....
The Restservice looks like this. It worked perfect without the address object..
#Path("/getPersonXML/{personNumber}")
#GET
#Produces(MediaType.APPLICATION_XML)
public Patient getPatientXML(#PathParam("personNumber") String personNumber) throws ParseException {
Address a1 = new Address("de.person/address/" + "432432","Teststret12","TestCity", "32433", "TestCountry", "081511833");
Patient p1 = new Person();
p1.setAddress(a1);
p1.setUri("de.spironto/person/"+ "432432");
p1.setnName("Power");
p1.setvName("Max");
return p1;
}
At the moment I'm always getting a
javax.xml.bind.JAXBException:
Any Ideas?
Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.
PROBLEM
The #XmlElementWrapper annotation must be used with a collection property. This means you can have:
#XmlElementWrapper
public List<PhoneNumber> getPhoneNumbers() {
return phoneNumbers;
}
But not
#XmlElementWrapper
public Address getAddress() {
return address;
}
SOLUTION #1 - Using Any JAXB Proivder
You could use an XmlAdapter to accomplish this (see linked answer below):
Access attribute of internal element in the most simple way
SOLUTION #2 - Using EclipseLink JAXB (MOXy)
You could leverage the #XmlPath extension to map this use case:
#XmlPath("Former-User-Ids/Address")
public Address getAddress() {
return address;
}
For More Information
http://blog.bdoughan.com/2010/07/xpath-based-mapping.html
http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html
After building a small marshaller test. I got the failure that there are several properties with the same name. So I tried to delete all #XML_Eleemets annotations in the Address class.
That worked for me...
Related
import javax.ws.rs.FormParam;
import com.alibaba.fastjson.JSON;
Hi guys, The JAX-RS seems cannot init the list field in resteasy 2.x/3.x/4.x automatically,
Here is my VO used in servce
public class OrderVO {
#FormParam("id")
private long id;
#FormParam("title")
private String title;
#FormParam("product")
private List<Integer> product;
...
public String toString() {
return JSON.toJSONString(this);
}
}
And here is my service method:
#POST
#Consumes(MediaType.APPLICATION_FORM_URLENCODED+";charset=UTF-8")
#Path("/create")
public InsertResult saveOrder(#BeanParam OrderVO order) {
logger.debug(order.toString());
}
Other parameters are auto inited except the List or Integer[], and can anyone tell me why....
In my Spring Boot Cassandra build I am getting the following error: s0-admin-1] c.d.o.d.i.c.control.ControlConnection : [s0] Error connecting to Node(endPoint=localhost:1234, hostId=null, hashCode=37hfeouh3), trying next node (ConnectionInitException: [s0|control|connecting...] Protocol initialization request, step 1 (OPTIONS): failed to send request (io.netty.channel.StacklessClosedChannelException))
Entity type of
#Data
#Builder
#Table
public class Class1 {
#Id
private String id;
private String data;
private Class2 data2;
private Integer data3;
...
}
public class2 Class2 {
#Id
#JasonProperty
private String id;
#Indexed
#JasonProperty
private String data;
#JasonProperty
private String data2;
#JasonProperty
private Integer data3;
...
}
#Configuration
#EnableCassandraRepositories
#ConfigurationProperties(prefix = "DBProperties")
public class ApplicationConfig extends AbstractCassandraConfiguration {
private String DBKEYSPACE;
#Override
protected String getKeyspaceName() {
return DBKEYSPACE;
}
public String[] getEntityBasePackages() {
return new String[] { "com.oreilly.springdata.cassandra" };
}
}
#ConfigurationProperties(prefix = "DBPROPERTIES")
#Slf4j
public class FactoryBeanAppConfig {
private String contactPoints;
private String keySpace;
private Integer port;
private String password;
private String username;
private String dataCenter;
/*
* Factory bean that creates the com.datastax.oss.driver.api.core.CqlSession instance
*/
#Bean
public CqlSessionFactoryBean session() {
//log it we made it.
log.info("I made it to CqlSessionFactoryBean");
CqlSessionFactoryBean session = new CqlSessionFactoryBean();
session.setContactPoints(URLINFO);
log.info("Contact Points: " +URLINFO);
session.setKeyspaceName(DBKEYSPACE);
//session.setPort(OURPORT);
session.setUsername(username);
session.setPassword(password);
session.setLocalDatacenter(LOCALDCENTER INFORMATION);
return session;
}
}
I am unable to find a good example or even a get it to work correctly. Looking at this documentation: https://docs.spring.io/spring-data/cassandra/docs/current/reference/html/#cassandra.core thats the only thing I should have to do to implement example 55
For the spring boot run your application, it need to load the DB when your server application (the tomcat for example) is starting. So, your schema should be created first. If it is ok, you could change the "localhost" to "127.0.0.1" in your cassandra.yaml file.
Important: "[s0] Error connecting to Node(endPoint=localhost:1234,..." please check the cassandra's port. The correct is 9042.
It will solve your problem. However, others errors can be happen, because the others classes.
Then, you could correct the classes below:
#SpringBootApplication
#EnableCassandraRepositories(basePackages = { "<package's path>" })
#EntityScan(basePackages = { "<package's path>" })
#ComponentScan(basePackages = { "<package's path>" })
public class ApplicationConfig extends SpringBootServletInitializer
{
SpringApplication.run(ApplicationConfig.class, args);
}
Entity:
#Table("<table name>")
public class Class1 {
#PrimaryKeyColumn(name = "<field name id>", type = PrimaryKeyType.PARTITIONED)
private String id;
#Column("<field name data>")
private String data;
private Class2 data2; //I think this declaretion can cause error
#Column("<field name data3>")
private Integer data3;
...
}
This FactoryBeanAppConfig's class is not sound good. I created a class to read the application.properties and inject this class to connect with the db datas like keyspace's name, port, and so one. This link will help you to creat this class: https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.external-config . And then, you use this class in your FactoryBeanAppConfig's class to get DBKEYSPACE, OURPORT, ... .
This is a example to helps you to understand what I'm saying: https://www.baeldung.com/spring-data-cassandra-tutorial .
This is my example.
public class Company {
....
private String companyName;
....
}
public class Employee {
....
private String name;
....
}
public class EmployeeDto {
....
private String name;
private String companyName;
....
}
#Mapper(componentModel = "spring")
public interface EmployeeDtoMapper {
#Mapping(target = "name", source = "source1.name")
#Mapping(target = "companyName", source = "source2.companyName")
EmployeeDto toDto(Employee source1, Company source2);
List<EmployeeDto> toDtos(List<Employee> sources, #Context Company source2);
}
I want that the method toDtos use toDto to map Employee to EmployeeDto but mapstruct generate a employeeDtoToEmployeeDto method.
How can I fix it ?
thanks
Mapstruct only allows for selecting submappings based on 1 source and 1 target. Hence the #Context annotation. This will effectively ignore that parameter, only handed it down to submapping..
But.. you can tackle your problem like this..
#Mapper(componentModel = "spring")
public interface EmployeeDtoMapper {
#Mapping(target = "name", source = "source1.name")
EmployeeDto toDto(Employee source1, #Context Company source2);
#AfterMapping
default afterToDto(#MappingTarget EmployeeDto target, #Context Company source2) {
target.setCompanyName( source2.getCompanyName();
}
List<EmployeeDto> toDtos(List<Employee> sources, #Context Company source2);
}
Note if you have multiple parameters in mapping source2, and you like to use MapStruct for that as well, you can define a new interface method mapping EmployDTO toDo(Company source) and call that from your default method.
I am reading and learning Spring Boot data with MongoDB. I have about 10 records in my database in the following format:
{
"_id" : ObjectId("5910c7fed6df5322243c36cd"),
name: "car"
}
When I open the url:
http://localhost:8090/items
I get an exhaustive list of all items. However, I want to use the methods of MongoRepository such as findById, count etc. When I use them as such:
http://localhost:8090/items/count
http://localhost:8090/items/findById/5910c7fed6df5322243c36cd
http://localhost:8090/items/findById?id=5910c7fed6df5322243c36cd
I get a 404.
My setup is as so:
#SpringBootApplication
public class Application {
public static void main(String[] args) throws IOException {
SpringApplication.run(Application.class, args);
}
}
#Document
public class Item implements Serializable {
private static final long serialVersionUID = -4343106526681673638L;
#Id
private String id;
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
#RepositoryRestResource(collectionResourceRel = "item", path = "items")
public interface ItemRepository<T, ID extends Serializable> extends MongoRepository<Item, String>, ItemRepositoryCustom {
}
What am I doing wrong? Do I need to implement the methods as defined by MongoRepository or will they be automatically implemented? I am lost and have been trying to figure this out for so long. I do not have any methods in my controller, its empty.
You have to declare the findById method in order for it to be exposed.
Item findById(String id);
Item findByName(String name);
Note that you don't need to implement the methods. SpringBoot will analyse the method name and provide the proper implementation
I had same issue,
After removing #Configuration,#ComponentScan everything worked fine.
How to enable ZK Page to bind with non public properties of bean.
Say I have a domain object called Book which looks like
class Book{
private String name;
protected String getName(){
return name;
}
protected void setName(String name){
this.name = name;
}
}
I want to be able to bind a textbox using #{book.name} , at present I think to enble binding i will need to make the getter and setter as public.
Frameworks like hibernate can operate on non public properties as well, so why has zk choosen not too, an configuration change possible to enable this ??
Any suggestions would be great.
Thanks
Sudarshan
Subclass it with making these accessors public and use the subclass instead of class Book.
Domain model definition:
public interface Book {
// some public methods you want to expose
}
Domain model implementation:
// This class is of package visibility
class BookSomewhatSpecificImplementation implements Book {
private String name;
// Note that they are package-scoped.
String getName(){
return name;
}
void setName(String name){
this.name = name;
}
}
Object factory:
public final class DomainModelFactory {
public static Book createBook(/* Some parameters */) {
return new BookSomewhatSpecificImplementation();
}
private DomainModelFactory() {}
}
Summary: you should program all other modules against Book interface. You can still use reflection for model implementation. To produce do mane objects use the factory.