I have a webservice:
#WebService()
public interface WMCService {
#WebMethod(operationName="getGroupInfoFromUserId")
#ResponseWrapper(className="wmc.web.service.BasicGroupWrapper")
#WebResult(name="basicGroup")
BasicGroup getGroupInfoFromUserId(#WebParam(name = "id") Long id);
}
#WebService(endpointInterface="wmc.web.service.WMCService", serviceName="WMCService")
public class WMCServiceImpl implements WMCService {
#Override
public BasicGroup getGroupInfoFromUserId(Long id) {
UserHelper uh = new UserHelper();
WMCUser user = uh.getById(id);
if (user != null) {
return user.getBasicGroup();
} else {
return null;
}
}
}
and I have the ResponseWrapper:
#XmlRootElement()
#XmlType(name="Group")
#XmlAccessorType(XmlAccessType.FIELD)
public class BasicGroupWrapper {
#XmlElement(name="groupName")
private String groupName;
#XmlElement(name="groupId")
private Long groupId;
#XmlTransient
private BasicGroup basicGroup;
public String getGroupName() {
return groupName;
}
public void setGroupName(String groupName) {
this.groupName = groupName;
}
public Long getGroupId() {
return groupId;
}
public void setGroupId(Long groupId) {
this.groupId = groupId;
}
public void setBasicGroup(BasicGroup group) {
this.groupName = group.getGroupName();
this.groupId = group.getId();
this.basicGroup = group;
}
public BasicGroup getBasicGroup() {
return basicGroup;
}
}
When I test this operation I get the following error which I can't google a solution to. Maybe you can help.
Caused by: javax.xml.bind.JAXBException: basicGroup is not a valid property on class wmc.web.service.BasicGroupWrapper
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getElementPropertyAccessor(JAXBContextImpl.java:971)
at com.sun.xml.ws.server.sei.EndpointResponseMessageBuilder$DocLit.<init>(EndpointResponseMessageBuilder.java:203)
... 34 more
#WebResult(name="basicGroup") this is not part of your WSDL since it's marked as XmlTransient:
#XmlTransient
private BasicGroup basicGroup;
So it won't be able to pick out that part of for your response.
I had the same problem when there were MS Web Service and Java client on JBoss.
I generated stub classes using wsconsume. And after that I usually deleted package-info.java because I thought that this is redundant class. After that this case reproduced.
After some time I tried to include this file (package-info.java) into project. And it solved the problem.
But when I've used Java Web Service (on JBoss) it works perfectly even without package-info class. It's very strange. Just FYI.
Following link was helpful: link
Related
I have a basic spring boot data rest api with posts that can have many comments. My problem is that I cant seem to find a way to post my comment directly to the sub resource uri such as http://localhost:8090/posts/1/comments.
The only way I've been able to do it was to to create the comment resource first at http://localhost:8090/comments and then post the uri of comment into http://localhost:8090/posts/1/comments.
It seems like a really bad idea as comments should never be able to exist on their own and only ever linked to a post.
Does anybody know how I can do this as one action, otherwise I'll have to manually deal with potential orphaned comments where the comment gets posted but never gets posted into http://localhost:8090/posts/1/comments for whatever reason.
My code is below.
Any help would be massively appreciated.
#Entity
public class Comment extends ResourceSupport {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#JsonIgnore
private Long id;
private String comment;
#ManyToOne
private Post post;
#ManyToOne
private User sender;
protected Comment() {};
public void setId(Long id) {
this.id = id;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public User getSender() {
return sender;
}
public void setSender(User sender) {
this.sender = sender;
}
public Post getPost() {
return post;
}
public void setPost(Post post) {
this.post = post;
}
#Entity
public class Post extends ResourceSupport {
#Id
#GeneratedValue(strategy= GenerationType.AUTO)
private #JsonIgnore Long id;
private String text;
#OneToMany
private List<Comment> comments;
protected Post () {};
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public List<Comment> getComments() {
return comments;
}
public void setComments(List<Comment> comments) {
this.comments = comments;
}
}
#RepositoryRestResource
public interface PostRepository extends PagingAndSortingRepository<Post, Long> {}
#RepositoryRestResource
public interface CommentRepository extends PagingAndSortingRepository<Comment, Long> {}
#SpringBootApplication
#EnableJpaRepositories("rest.api.repository")
#EnableWebMvc
#EnableTransactionManagement
#EnableAutoConfiguration
public class Application extends SpringBootServletInitializer{
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
the json im using to try to post the comment into the post is
{
"comment": "some text",
"sender": "http://localhost:8090/users/1"
}
It turned out that i needed to use mapped by i.e. #OneToMany(mappedBy = "post") on my comments list in my Post class.
Now i can post to http://localhost:8090/comments and then when i follow the http://localhost:8090/posts/1/comments link as before i now see the comments.
I am new to Spring Data JPA and Hibernate. By looking at different examples I built a working model for CRUD operations on one entity, I am having trouble in joining two tables to extract AF_NAME using AF_ID from another table which is Foreign key. A null column is created with the names of and while accessing, null is returned.please check if I am following preocedure for joins and point me to any tutorial know.
I followed this solution and still there is no progress.
#Entity
#Configuration
#EnableAutoConfiguration
#Table(name = "AFF_CONFIG")
public class AFF_CONFIG implements Serializable {
#Id
#Column(name = "AFF_CONFIG_ID")
private String AFF_CONFIG_ID;
#Column(name = "AFF_ID")
private String AFF_ID;
#Column(name = "CH_ID")
private String CH_ID;
#Column(name = "M_ID")
private Long M_ID;
#Column(name = "KEY")
private String KEY;
#Column(name = "VALUE")
private String VALUE;
#Column(name = "SYSTEM")
private String SYSTEM;
private AFF aff;
#LazyCollection(LazyCollectionOption.TRUE)
#ManyToOne
#JoinColumn(name = "AFF_ID")
public AFF getAff() {
return aff;
}
public void setAffiliate(AFF aff) {
this.aff = aff;
}
public String getAFF_CONFIG_ID() {
return AFF_CONFIG_ID;
}
public void setAFF_CONFIG_ID(String aFF_CONFIG_ID) {
AFF_CONFIG_ID = aFF_CONFIG_ID;
}
public String getAFF_ID() {
return AFF_ID;
}
public void setAFF_ID(String aFF_ID) {
AFF_ID = AFF_ID;
}
public String getCH_ID() {
return CH_ID;
}
public void setCHANNEL_ID(String cH_ID) {
CH_ID = cH_ID;
}
public Long getM_ID() {
return M_ID;
}
public void setM_ID(Long m_ID) {
M_ID = m_ID;
}
public String getKEY() {
return KEY;
}
public void setKEY(String kEY) {
KEY = kEY;
}
public String getVALUE() {
return VALUE;
}
public void setVALUE(String vALUE) {
VALUE = vALUE;
}
public String getSYSTEM() {
return SYSTEM;
}
public void setSYSTEM(String sYSTEM) {
SYSTEM = sYSTEM;
}
Second entity is:
#Entity
#Table(name = "AFF")
public class AFF implements Serializable {
#Column(name = "AFF_NAME")
private String AFF_NAME;
#Column(name = "AFF_CODE")
private String AFF_CODE;
#Id
#Column(name = "AFF_ID")
private String AFF_ID;
private Set<AFF_CONFIG> someAff = new HashSet<AFF_CONFIG>();
#LazyCollection(LazyCollectionOption.TRUE)
#OneToMany(cascade = CascadeType.ALL, mappedBy = "aff")
public Set<AFF_CONFIG> getSomeAff() {
return someAff;
}
public void setSomeAff(Set<AFF_CONFIG> someAff) {
this.someAff = someAff;
}
public String getAFF_ID() {
return AFF_ID;
}
public void setAFF_ID(String aFF_ID) {
AFF_ID = aFF_ID;
}
public String getAFF_NAME() {
return AFF_NAME;
}
public void setAFF_NAME(String aFF_NAME) {
AFF_NAME = aFF_NAME;
}
public String getAFF_CODE() {
return AFF_CODE;
}
public void setAFF_CODE(String aFF_CODE) {
AFF_CODE = aFF_CODE;
}
Since this is many to one relation I created set type in one and object type in another as defined in other places.Created a repository by extending crud and added a query. Excise the bunch of different annotations, I included them in hoping to solve the null entry.
#Repository
public interface MarketRepository extends CrudRepository<AFF_CONFIG,String> {
Page<AFF_CONFIG> findAll(Pageable pageable);
#Query("Select a,b from AFF_CONFIG a, AFF b where a.AFF_ID = b.AFF_ID" )
public List<AFF_CONFIG> getAffData();
}
the applicatoin is working fine even after some tinkering until I Included these annotations. Now there is this error:
Caused by: org.hibernate.MappingException: Could not determine type for: java.util.Set, at table: aff.
I solved the issue with the help of my Supervisor. Looks like we have to follow naming specifications for Class and variables. And one more correction is to remove collection type object and change it to just object (removed set in aff class).I will post the corrected later, to compare and contrast.
I am working on one project in which i am developing a java client for .NET/C#.
I want to send information of device to the web service.
I have created one class which contains the device information.
I want to send the information of the device to service.
what is appropriate way to do this. Please help.
sorry for my weak English.
And thanks in advance.
package com.ivb.syntecApp.models;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
public class DeviceInformation {
private String vendorId;
private String productId;
private String hardwareRevision;
private String deviceName;
private String manufacturerName;
#XmlElement
public String getVendorId() {
return vendorId;
}
public void setVendorId(String vendorId) {
this.vendorId = vendorId;
}
#XmlElement
public String getProductId() {
return productId;
}
public void setProductId(String productId) {
this.productId = productId;
}
#XmlElement
public String getHardwareRevision() {
return hardwareRevision;
}
public void setHardwareRevision(String hardwareRevision) {
this.hardwareRevision = hardwareRevision;
}
#XmlElement
public String getDeviceName() {
return deviceName;
}
public void setDeviceName(String deviceName) {
this.deviceName = deviceName;
}
#XmlElement
public String getManufacturerName() {
return manufacturerName;
}
public void setManufacturerName(String manufacturerName) {
this.manufacturerName = manufacturerName;
}
}
For this purpose the Common Object Request Broker Architecture (CORBA) was developed. But it's too big gun for your needs. I recommend you to use some kind of REST or SOAP service with transformators(Adapter pattern)
I have solved at my own. I don't know is it good practice or not.
My answer is ->
I have used JAXB for marshaling DeviceInformation class and used
`void marshal(Object jaxbElement,
Writer writer)
throws JAXBException
` to convert this object in to StringWriter object then converted it into string and sent this string to .NET/C# service.
This meets my requirement.
I found this here
Input paramter to my webservice method is an Object of Class AddSingleDocRequest. This class contains all the input fields as class instance variable with their getter and setter. I want to make some of the input fields mandatory. What is the best way to achieve this ?
Following is the code snippet:
**//webservice method
public String uploadDoc(AddSingleDocRequest request)
{
}
**//Request Class**
public class AddSingleDocRequest
{
private String sFilepath;
private String sDataClass;
public void setDataClassName(String dataClassName)
{
this.sDataClass= dataClassName;
}
public String getDataClassName() {
return sDataClass;
}
public void setFilePath(String filePath)
{
this.sFilepath=filePath;
}
public String getFilePath()
{
return sFilepath;
}
}
I want to make sFilePath parameter as mandatory.
Add the next JAX-B annotations:
#XmlType(name = "AddSingleDocRequestType", propOrder = {
"sFilepath", "sDataClass"
})
public class AddSingleDocRequest {
#XmlElement(name = "sFilepath", required = true)
private String sFilepath;
#XmlElement(name = "sDataClass", required = false)
private String sDataClass;
public void setDataClassName(String dataClassName) {
this.sDataClass = dataClassName;
}
public String getDataClassName() {
return sDataClass;
}
public void setFilePath(String filePath) {
this.sFilepath = filePath;
}
public String getFilePath() {
return sFilepath;
}
}
See more in Using JAXB to customize mapping for JAX-WS web services.
I have application separated to frontend and backend modules which communicate through restfull webservice. Unfortunately, something goes wrong in this code and I get from Backend part:
java.lang.ClassCastException: com.rrd.ecomdd.data.SharedFile cannot be cast to javax.xml.bind.JAXBElement
Frontend snippet:
#Override
public void share(Set<SharedFile> fileSet) {
apiTarget.path(ApiConstant.FILESERVICE)
.path(ApiConstant.FILESERVICE_SHARE)
.request(MediaType.APPLICATION_JSON_TYPE.withCharset("UTF-8"))
.post(Entity.entity(fileSet.toArray(new SharedFile[0]), MediaType.APPLICATION_JSON_TYPE.withCharset("UTF-8")), new GenericType<Set<SharedFile>>() {
});
}
Backend snippet
#POST
#Path(ApiConstant.FILESERVICE_SHARE)
#Produces("application/json; charset=UTF-8")
#Consumes("application/json; charset=UTF-8")
public List<SharedFile> share(SharedFile[] sharedList) {
for (SharedFile s : sharedList) {
fileService.share(s);
}
return Arrays.asList(sharedList);
}
SharedFile class:
public class SharedFile {
private Long id;
private User user;
private ManagedFile file;
private UUID uuid = UUID.randomUUID();
public SharedFile(User user, ManagedFile file) {
this.user = user;
this.file = file;
}
public SharedFile() {
}
//getters, setters, equals and hashcode below
}
Any ideas how to fix this?
Try to annotate the class and its attributes as mentioned here:
#XmlRootElement
public class SharedFile {
#XmlElement
private Long id;
#XmlElement
private User user;
#XmlElement
private ManagedFile file;
Follow this for more: http://docs.oracle.com/javaee/6/tutorial/doc/gkknj.html