I am trying to create rest service using camel cxfRs server from this link But When I try to hit using soapUi it shows me "The requested resource is not available" my endpoint is "/customers/gold?active=true" and I tried this one also.
"CxfRsRouterTest/rest/customers/gold?active=true". Here is cxfConfig.xml
<jaxrs:server id="restService"
address="http://localhost:8080/CxfRsRouterTest/rest" staticSubresourceResolution="true">
<jaxrs:serviceBeans>
<ref bean="customerService"/>
</jaxrs:serviceBeans>
</jaxrs:server>
<bean id="jsonProvider" class="org.apache.cxf.jaxrs.provider.json.JSONProvider"></bean>
<bean id="customerService" class="com.infy.CustomerService"></bean>
<cxf:rsServer id="rsServer"
address="http://localhost:8080/CxfRsRouterTest/route"
serviceClass="com.infy.CustomerService"
loggingFeatureEnabled="true" loggingSizeLimit="20" >
<cxf:providers>
<ref bean="jsonProvider"/>
</cxf:providers>
</cxf:rsServer>
Customer.java
#XmlRootElement
public class Customer {
private String name;
private String country;
private String organization;
public String getName() {
return name;
}
#XmlElement
public void setName(String name) {
this.name = name;
}
public String getCountry() {
return country;
}
#XmlElement
public void setCountry(String country) {
this.country = country;
}
public String getOrganization() {
return organization;
}
#XmlElement
public void setOrganization(String organization) {
this.organization = organization;
}
This is my service class
#POST#Path("/customer/{type}")
public Response newCustomer(Customer customer,#PathParam("type") String type,#QueryParam("active") #DefaultValue("true") boolean active){
return null;
}
Response is jxrs response class
I am using tomcat 8 to deploy. please help me out where I am going wrong in this. I just started to learn camel cxf
I am getting the error "Could not resolve matching constructor (hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)" while executing my spring program. I am new to Spring core and trying to learn the framework. Below is the code:
Student.java
package com.inject.test;
public class Student {
private String name;
private String className;
private Address address;
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
}
Address.java
package com.inject.test;
public class Address {
private String city;
private String state;
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
Test.java
package com.inject.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
#SuppressWarnings("resource")
ApplicationContext context = new ClassPathXmlApplicationContext("file:com/applicationContext.xml");
Student student = (Student) context.getBean("student");
System.out.println("Name: " + student.getName());
System.out.println("Class: " + student.getClassName());
Address studentAddress = student.getAddress();
System.out.println("Student Address: ");
System.out.println("City: " + studentAddress.getCity());
System.out.println("State: " + studentAddress.getState());
}
}
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="student" class="com.inject.test.Student">
<property name="name" value="Jai"/>
<property name="className" value="MCA"/>
<constructor-arg ref="address" type="java.lang.String"/>
</bean>
<bean id="address" class="com.inject.test.Address">
<property name="city" value="Hyderabad"/>
<property name="state" value="Telangana"/>
</bean>
</beans>
What change should be made to resolve the constructor issue, please suggest.
Your xml configuration specifies a constructor argument containing the address, but your Student class does not have a constructor that takes any arguments.
Either add the appropriate constructor, or change the constructor-arg to a property in the xml configuration.
1)you have not added constructor in your class,so replace your applicationContext.xml file
<bean id="student" class="com.inject.test.Student">
<property name="name" value="jai"></property>
<property name="className" value="MCA"></property>
//instead of writing <constructor-arg>property write as follow
<property name="address" ref="addressOne"></property>
</bean>
<bean id="addressOne" class="com.inject.test.Address">
<property name="city" value="Hyderabad"/>
<property name="state" value="Telangana"/>
</bean>
or 2) just add
public Student(Address address) {
this.address = address;
}
in student class
and replace this line
<constructor-arg ref="address" type="java.lang.String"/>
with this
<constructor-arg ref="address"/>
I need to write a rest service which accepts XML/JSON as a input (POST method) and XML/JSON as a output (based on the input format). I have tried a below approach to achieve this but doesn't helped out.Endpoint method accepts both XML/JSON but while responding it always gives either JSON or XML based on the order specified in #RequestMapping -produces.Any help will be really appreciated.
My endpoint method:
#RequestMapping(value = "/getxmljson", method = RequestMethod.POST,produces={"application/json","application/xml"},
consumes={"application/json", "application/xml"})
public #ResponseBody Student processXMLJsonRequest(#RequestBody Student student)
throws Exception {
System.out.println("*************Inside Controller");
return student;
}
POJO Class: Student.java
import java.io.Serializable;
import java.util.ArrayList;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
#XmlRootElement(name = "student")
#XmlType(propOrder = {"id", "name", "graduationTime", "courses"})
#JsonPropertyOrder({"id", "name", "graduationTime", "courses"})
public class Student implements Serializable {
private static final long serialVersionUID = 1L;
private int id;
private String name;
private String graduationTime;
private ArrayList<Course> courses = new ArrayList<Course>();
#XmlElement
public int getId() { return id; }
#XmlElement
public String getName() { return name; }
#XmlElement
public String getGraduationTime() { return graduationTime; }
#XmlElement
public ArrayList<Course> getCourses() { return courses; }
public void setId(int value) { this.id = value; }
public void setName(String value) { this.name = value; }
public void setGraduationTime(String value) { this.graduationTime = value; }
public void setCourses(ArrayList<Course> value) { this.courses = value; }
#JsonIgnore
public String toString() {
return this.name + " - "
+ graduationTime == null? "Unknown" : graduationTime.toString();
}
public Student() {}
public Student(int id, String name, String graduationTime) {
this.id = id;
this.name = name;
this.graduationTime = graduationTime;
}
}
POJO Class: Course.java
import java.io.Serializable;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
#XmlRootElement(name = "course")
#XmlType(propOrder = {"courseName", "score"})
#JsonPropertyOrder({"courseName", "score"})
public class Course implements Serializable {
private static final long serialVersionUID = 1L;
private String courseName;
private Integer score;
public #XmlElement String getCourseName() { return courseName; }
public #XmlElement Integer getScore() { return score; }
public void setCourseName(String value) { courseName = value; }
public void setScore(Integer value) { score = value; }
public Course() {}
public Course(String courseName, Integer score) {
this.courseName = courseName;
this.score = score;
}
}
spring-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:sws="http://www.springframework.org/schema/web-services"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:oxm="http://www.springframework.org/schema/oxm"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/web-services
http://www.springframework.org/schema/web-services/web-services-2.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd
http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-4.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-2.5.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing
infrastructure -->
<!-- Enables the Spring MVC #Controller programming model -->
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving
up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Configure to plugin JSON as request and response in method handler -->
<beans:bean
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<beans:property name="messageConverters">
<beans:list>
<beans:ref bean="jsonMessageConverter" />
<beans:ref bean="xmlMessageConverter" />
</beans:list>
</beans:property>
</beans:bean>
<!-- Configure bean to convert JSON to POJO and vice versa -->
<beans:bean id="jsonMessageConverter"
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
</beans:bean>
<beans:bean id="xmlMessageConverter"
class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter">
</beans:bean>
<beans:bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
</beans:bean>
<beans:bean id="objectMapper" class="com.fasterxml.jackson.databind.ObjectMapper" />
<context:component-scan base-package="com.test" />
</beans:beans>
Json Input:
{
"id":2014,
"name":"test",
"graduationtime":"09/05/2014",
"courses":[
{
"courseName":"Math",
"score":150
},
{
"courseName":"Che",
"score":150
}
]
}
XML Input:
<?xml version="1.0" encoding="UTF-8" ?>
<student>
<id>2014</id>
<name>test</name>
<graduationTime>09/05/2014</graduationTime>
<courses>
<courseName>Math</courseName>
<score>150</score>
</courses>
<courses>
<courseName>Che</courseName>
<score>150</score>
</courses>
</student>
The best practice for handling different data formats with the same controller is to let the framework do all the work of figuring out the marshalling and unmarshalling mechanisms.
Step 1: Use minimal controller configuration
#RequestMapping(value = "/getxmljson", method = RequestMethod.POST)
#ResponseBody
public Student processXMLJsonRequest(#RequestBody Student student) {
return student;
}
There is no need to specify consumes and produces here. As an example, consider that you may want this same method to handle other formats in the future such as Google Protocol Buffers, EDI, etc. Keeping the controllers free of consumes and produces will let you add data formats through global configuration instead of having to modify the controller code.
Step 2: Use ContentNegotiatingViewResolver instead of RequestMappingHandlerAdapter
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="defaultViews">
<list>
<bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"/>
</list>
</property>
</bean>
Let the view resolver decide how to read incoming data and how to write it back.
Step 3: Use Accepts and Content-Type HTTP headers
Hitting your controller with the correct HTTP header values will force ContentNegotiatingViewResolver to marshal and unmarshal data automatically using the appropriate data representations.
If you want to exchange data in JSON format, set both headers to application/json. If you want XML instead, set both to application/xml.
If you do not want to use HTTP headers (which ideally you should), you can simply add .json or .xml to the URL and ContentNegotiatingViewResolver will do the rest.
You can check out my sample app that I created using your code snippets that works fine for JSON and XML.
Adding to Manish's answer above, if you don't wanna use xml based configuration use this java based configuration instead-
#Bean
public ViewResolver contentNegotiatingViewResolver() {
ContentNegotiatingViewResolver resolver =
new ContentNegotiatingViewResolver();
List<View> views = new ArrayList<>();
views.add(new MappingJackson2XmlView());
views.add(new MappingJackson2JsonView());
resolver.setDefaultViews(views);
return resolver;
}
Register a filter that intercepts each request, warp the HttpServletRequest into an implementation of HttpServletRequestWrapper and returns the Content-Type value for Accept header. For example, you can register a filter named SameInSameOutFilter like following:
#Component
public class SameInSameOutFilter extends GenericFilterBean {
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
SameInSameOutRequest wrappedRequest = new SameInSameOutRequest((HttpServletRequest) request);
chain.doFilter(wrappedRequest, response);
}
}
It wraps current request in a SameInSameOutRequest:
public class SameInSameOutRequest extends HttpServletRequestWrapper {
public SameInSameOutRequest(HttpServletRequest request) {
super(request);
}
#Override
public String getHeader(String name) {
if (name.equalsIgnoreCase("accept")) {
return getContentType();
}
return super.getHeader(name);
}
}
This wrapper tells spring mvc to select a HttpMessageConverter based on request's Content-Type value. If request body's Content-Type is application/xml, then the response would be an XML. Otherwise, the response would be JSON.
The other solution is to manually set the Accept header along with Content-Type in each request and avoid all these hacks.
i was facing the same problem like yours. Below is my solution and sample.
Below is maven dependency that you need to include:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.4.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.4.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.4.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.4.3</version>
</dependency>
dispatcher-servlet.xml
<mvc:annotation-driven
content-negotiation-manager="contentManager" />
<bean id="contentManager"
class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="favorPathExtension" value="false" />
<property name="ignoreAcceptHeader" value="false" />
<property name="defaultContentType" value="application/json" />
<property name="useJaf" value="false" />
</bean>
and my #RequestMapping ( you can use your own request mapping )
#RequestMapping(value = "/testXMLJSON",
method = RequestMethod.GET, produces = {
MediaType.APPLICATION_XML_VALUE,
MediaType.APPLICATION_JSON_VALUE })
#ResponseBody
public ArtworkContentMessageType testXMLJSON()
{
//this is GS1 xml standard mapping.
ArtworkContentMessageType resp = new ArtworkContentMessageType();
StandardBusinessDocumentHeader standarBusinessDocumentHeader = new StandardBusinessDocumentHeader();
resp.setStandardBusinessDocumentHeader(standarBusinessDocumentHeader );
ArtworkContentType artWorkContent = new ArtworkContentType();
resp.getArtworkContent().add(artWorkContent);
return resp ;
}
If application/xml is required then, below headers must be present
Content-Type:application/xml
Accept:application/xml
If the resource define as below
#GET
#Path("/{id}")
#Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Student getStudent(#PathParam("id") String id) {
return student(); // logic to retunrs student object
}
Then the request should contains 'accept' header ('application/json' or application/xml'),
then it returns response in json or xml format.
Sample request :
curl -k -X GET -H "accept: application/json" "https://172.17.0.5:8243/service/1.0/222"
Sample Student class
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name = "student")
public class Student {
private int id;
private String name;
private String collegeName;
private int age;
#XmlAttribute
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#XmlElement
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#XmlElement
public String getCollegeName() {
return collegeName;
}
public void setCollegeName(String collegeName) {
this.collegeName = collegeName;
}
public int getAge() {
return age;
}
#XmlElement
public void setAge(int age) {
this.age = age;
}
}
I have a rather large object tree which I want to export to XML. An object named Person is used at several places (as userCreated, userModified of many child entities, as client, etc)
Depending of the use of the Person-object I need to have different elements in the xml. Example:
<policy>
<userCreated>
<firstName>John</firstName>
<lastName>Doe</lastName>
</userCreated>
<client>
<clientId>1234</clientId>
<email>jdoe#example.com</email>
<firstName>John</firstName>
<lastName>Doe</lastName>
</client>
</policy>
userCreated and client are instances of the same object (named Person)
How can this be set up in bindings.xml ?
You can use EclipseLink JAXB (MOXy)'s #XmlNamedObjectGraph extension to support this use case. What #XmlNamedObjectGraph allows you to do is create multiple views on your data.
Person
Below we will use #XmlNamedObjectGraph to create a view on the Person class that only exposes 2 fields (firstName and lastName).
import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.*;
#XmlNamedObjectGraph(
name = "simple",
attributeNodes = {
#XmlNamedAttributeNode("firstName"),
#XmlNamedAttributeNode("lastName")
}
)
#XmlAccessorType(XmlAccessType.FIELD)
public class Person {
private int clientId;
private String firstName;
private String lastName;
private String email;
public void setClientId(int clientId) {
this.clientId = clientId;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public void setEmail(String email) {
this.email = email;
}
}
Policy
We will also use #XmlNamedObjectGraph on the Policy class. It says that for the userCreated field apply the named object graph called simple that we defined on the Person class.
import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.*;
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
#XmlNamedObjectGraph(
name = "policy",
attributeNodes = {
#XmlNamedAttributeNode(value = "userCreated", subgraph = "simple"),
#XmlNamedAttributeNode("client")
}
)
public class Policy {
private Person userCreated;
private Person client;
public void setUserCreated(Person userCreated) {
this.userCreated = userCreated;
}
public void setClient(Person client) {
this.client = client;
}
}
Demo
In the demo code below we will specify the named object graph that we want applied on the Marshaller using the MarshallerProperties.OBJECT_GRAPH property.
import javax.xml.bind.*;
import org.eclipse.persistence.jaxb.MarshallerProperties;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Policy.class);
Person person = new Person();
person.setClientId(1234);
person.setFirstName("John");
person.setLastName("Doe");
person.setEmail("jdoe#example.com");
Policy policy = new Policy();
policy.setClient(person);
policy.setUserCreated(person);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(MarshallerProperties.OBJECT_GRAPH, "policy");
marshaller.marshal(policy, System.out);
}
}
Output
Below is the output from running the demo code:
<?xml version="1.0" encoding="UTF-8"?>
<policy>
<userCreated>
<firstName>John</firstName>
<lastName>Doe</lastName>
</userCreated>
<client>
<clientId>1234</clientId>
<firstName>John</firstName>
<lastName>Doe</lastName>
<email>jdoe#example.com</email>
</client>
</policy>
For More Information
http://blog.bdoughan.com/2013/03/moxys-object-graphs-inputoutput-partial.html
http://blog.bdoughan.com/2013/03/moxys-object-graphs-partial-models-on.html
I am new to Hibernate. Recently, I was trying simple example to connect my UI with Database using Spring and Hibernate.
I am able to successfully call a method to fetch the data through my controller, service etc using REST.
But I am encountering below error,whenever I run the application.
Here "Feedback" is the name of Table in Database as well as the same name of my Pojo Java class.
Note : Giving different names to table and Java class also results in same error.
org.springframework.orm.hibernate3.HibernateQueryException: Feedback
is not mapped [from Feedback]; nested exception is
org.hibernate.hql.ast.QuerySyntaxException: Feedback is not mapped
[from Feedback]
Java Pojo:-
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name="Feedback")
public class Feedback {
private int id;
private String title;
private String content;
private String name;
#Id
#GeneratedValue
#Column(name="id")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#Column(name="title", nullable=false)
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
#Column(name="content", nullable=false)
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
#Column(name="name", nullable=false)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public String toString() {
return "Feedback [id=" + id + ", title=" + title + ", content="
+ content + ", name=" + name + "]";
}
}
FeedbackDAO :-
#Repository
public class FeedbackDAO implements IFeedbackDAO {
private HibernateTemplate hibernateTemplate;
public HibernateTemplate getHibernateTemplate() {
return hibernateTemplate;
}
#Autowired
public void setSessionFactory(SessionFactory sessionFactory) {
hibernateTemplate = new HibernateTemplate(sessionFactory);
}
#SuppressWarnings("unchecked")
public List<Feedback> getFeedbackList() {
// This line causes that error.
return hibernateTemplate.find("from Feedback");
}
...
...
}
Configuration made in db-config.xml
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>
What could be causing this ?
Do am I missing something here ?
Thanks
You might have missed a thing in sessionFactory definition.
<bean id="sessionFactory" ...>
...
<property name="annotatedClasses">
<list>
<value><java package name here>.Feedback</value>
</list>
</property>
...
</bean>