Developing JAX-RS app and struggle a problem.
Need to customize json-output from my resource so configured Jersey(2.22.2) to use Jackson(2.5) parser instead default Moxy (according to this answer).
Here is pom.xml fragment
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jersey-bom</artifactId>
<version>${jersey.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<!-- use the following artifactId if you don't need servlet 2.x compatibility -->
<!-- artifactId>jersey-container-servlet</artifactId -->
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.25.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.3</version>
</dependency>
</dependencies>
<properties>
<jersey.version>2.22.2</jersey.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
I also configured web.xml file to use Jackson by default
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>
com.mycompany.myresourcepackage
com.fasterxml.jackson.jaxrs
</param-value>
</init-param>
But resource output is deffer from what I configure with annotations and serializer.
Here is model to represent as json
#XmlRootElement(name = "geo")
public class Geometry {
public Geometry() {
coordinates = new ArrayList<List<Double>>();
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
#JsonSerialize(using = CoordinatesSerializer.class)
public List<List<Double>> getCoordinates() {
return coordinates;
}
public void setCoordinates( List<List<Double>> coordinates) {
this.coordinates = coordinates;
}
#JsonProperty("tp")
private String type;
private List<List<Double>> coordinates;
}
And serializer
protected CoordinatesSerializer(Class<List<List<Double>>> t) { }
private static final long serialVersionUID = 1L;
#Override
public void serialize(List<List<Double>> value, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonGenerationException {
try {
jgen.writeArrayFieldStart("motherfucking-coordinates");
int coordinates_size = value.size();
for (int i = 0; i < coordinates_size; i++) {
jgen.writeStartArray();
jgen.writeNumber(value.get(i).get(0));
jgen.writeNumber(value.get(i).get(1));
jgen.writeEndArray();
}
jgen.writeEndArray();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
And here is resource fragment
#GET
#Path("/route/{id}")
#Produces(MediaType.APPLICATION_JSON)
public Geometry(#PathParam("id") int id) {
// construct and return object
}
Response json is not customized at all.
{"geometry":{"coordinates":["27.56 53.9","27.58 53.88","27.55 53.94"],"type":"LineString"},"id":"1","type":"Feature"}
Desired output is
{"geometry":{"coordinates":[[27.56, 53.9],[27.58, 53.88],[27.55, 53.94]],"type":"LineString"},"id":"1","type":"Feature"}
Thanks a lot.
I finally managed to configure Jersey project to use Jackson JSON parser instead of Moxy(default). The application is running at Glassfish JEE Server.
Maven dependencies
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<!-- use the following artifactId if you don't need servlet 2.x compatibility -->
<!-- artifactId>jersey-container-servlet</artifactId -->
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.5.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.3</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
Than you need to create class with extends org.glassfish.jersey.server.ResourceConfig. The object of the class is created when app is first loaded.
public class MyApplication extends ResourceConfig {
public MyApplication() {
// create custom ObjectMapper
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
// create JsonProvider to provide custom ObjectMapper
JacksonJaxbJsonProvider provider = new JacksonJaxbJsonProvider();
provider.setMapper(mapper);
register(provider);
register(JacksonFeature.class);
packages("your.resources.package");
}
}
And created MyApplication class should be registered in web.xml file (to be actually created). Edit section of web.xml.
<servlet>
<servlet-name>App</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>your.app.package.MyApplication</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
Listed steps are enough to register Jackson JSON Parser as default for Jersey Jax-RS app.
Related
I'm learning Apache Camel with book Mastering Apache Camel by Jean-Baptiste. I need to learn this framework for use it in my current work.
The version of Apache Camel used in the book is 2.12.4 but I inadvertently made a lot of PoC with the version 3.1.0.
In this moment I'm trying to translate XML files to JSON files but without any result.
My pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.redhat</groupId>
<artifactId>apachecamel-learning</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<!-- Apache CAMEL -->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.30</version>
</dependency>
<!-- MARSHALL AND UNMARSHALL -->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-jackson</artifactId>
<version>3.1.0</version>
</dependency>
<!-- Camel JMS -->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-jms</artifactId>
<version>2.5.0</version>
</dependency>
<!-- ActiveMQ -->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-core</artifactId>
<version>5.3.2</version>
</dependency>
<!-- OSGi -->
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
<version>4.3.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
My Java Class:
package com.redhat.pocs.camel.eip;
import org.apache.camel.CamelContext;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.model.dataformat.JacksonXMLDataFormat;
public class TestMarshallAndUnmarshall {
public static void main(String[] args) throws Exception {
CamelContext context = new DefaultCamelContext();
context.addRoutes(new RouteBuilder() {
public void configure() {
from("file:/tmp/in")
.marshal(new JacksonXMLDataFormat())
.to("file:/tmp/out");
}
});
context.start();
Thread.sleep(10000); // Prevent to Camel to shutdown and don't run the route
context.stop();
context.close();
}
}
I tried with XmlJsonDataFormat, JaxbDataFormat, JacksonXMLDataFormat and always with the same error:
Exception in thread "main" org.apache.camel.FailedToCreateRouteException: Failed to create route route1 at: >>> Marshal[org.apache.camel.model.dataformat.JacksonXMLDataFormat#6e4784bc] <<< in route: Route(route1)[From[file:/tmp/in] -> [Marshal[org.apache.came... because of Data format 'jacksonxml' could not be created. Ensure that the data format is valid and the associated Camel component is present on the classpath
Does anyone have any idea what I'm doing wrong?
For Camel 2
Since version 2.10.x there is the camel-xmljson component.
I use it like this (version 2.22.2)
Camel route:
final XmlJsonDataFormat xmlJsonFormat = new XmlJsonDataFormat();
xmlJsonFormat.setRootName("result");
CamelContext context = new DefaultCamelContext();
context.addRoutes(new RouteBuilder() {
public void configure() {
from("file:/tmp?fileName=in.xml")
.marshal(xmlJsonFormat)
.to("file:/tmp?fileName=out.json")
.end();
}
});
context.start();
Thread.sleep(5000); // Prevent to Camel to shutdown and don't run the route
context.stop();
Pom.xml:
...
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-xmljson</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>xom</groupId>
<artifactId>xom</artifactId>
<version>1.2.5</version>
</dependency>
...
For Camel 3
The camel-xmljson component is deprecated for this version of camel. I couldn't find a direct way to transform from xml to json.
Unfortunately, the only way I could made this work was using an intermediate pojo. So first I transform from xml to Pojo and then from Pojo to json.
Camel route:
JacksonDataFormat jacksonDataFormat = new JacksonDataFormat();
jacksonDataFormat.setPrettyPrint(true);
jacksonDataFormat.enableFeature(SerializationFeature.WRAP_ROOT_VALUE);
CamelContext context = new DefaultCamelContext();
context.addRoutes(new RouteBuilder() {
public void configure() {
from("file:/tmp?fileName=in.xml")
.unmarshal().jacksonxml(Order.class)
.marshal(jacksonDataFormat)
.to("file:/tmp?fileName=out.json")
.end();
}
});
context.start();
Thread.sleep(10000); // Prevent to Camel to shutdown and don't run the route
context.stop();
context.close();
Order and Item classes
public class Order {
#JacksonXmlProperty(localName = "name")
private String name;
#JacksonXmlProperty(localName = "items")
private List<Item> items;
public Order() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Item> getItems() {
return items;
}
public void setItems(List<Item> items) {
this.items = items;
}
}
public class Item {
#JacksonXmlProperty(localName = "name")
private String name;
public Item() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Order.xml
<order>
<name>123</name>
<items>
<item>
<name>a</name>
</item>
<item>
<name>b</name>
</item>
</items>
</order>
Result Order.json
{
"Order" : {
"name" : "123",
"items" : [ {
"name" : "a"
}, {
"name" : "b"
} ]
}
}
Hope it helps.
xj
(mike drop)
I was looking for same information and almost accidentally found the poorly named "camel-xj". https://camel.apache.org/components/3.18.x/xj-component.html
The XJ component allows you to convert XML and JSON documents directly
forth and back without the need of intermediate java objects. You can even specify an XSLT stylesheet to convert directly to the target JSON / XML (domain) model..
I get this error when I try to see JSON response in my browser. I read a lot of posts on stack witch are similar but nothing work. Browser return "Error 500". Intellij IDEA return error "Error MessageBodyWriter not found for media type=application/json". Here is my code:
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>groupId</groupId>
<artifactId>app</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jersey-bom</artifactId>
<version>${jersey.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-entity-filtering</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
<properties>
<jersey.version>2.23.2</jersey.version>
</properties>
</project>
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>app</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
MessageService:
package app.resource;
import app.model.Message;
import app.service.MessageService;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.List;
#Path("messages")
public class MessageResource {
MessageService messageService = new MessageService();
#GET
#Produces(MediaType.APPLICATION_JSON)
public List<Message> getMessages()
{
return messageService.getAllMessages();
}
#GET
#Path("/{messageId}")
#Produces(MediaType.APPLICATION_JSON)
public Message test(#PathParam("messageId") long id)
{
return messageService.getMessage(id);
}
}
Message class:
package app.model;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.Date;
#XmlRootElement
public class Message {
private long id;
private String message;
private Date created;
private String author;
public Message()
{
}
public Message(long id, String message, String author) {
this.id = id;
this.message = message;
this.created = new Date();
this.author = author;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}
Old post, but I figured it could help someone. I can across the same issue playing around with Apache Tomcat 9.0.36 and Jersey. This error is due to a missing media dependency. Here are my Jersey POM dependencies that worked for me:
<!-- Jersey dependencies -->
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>2.29.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.29.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>2.29.1</version>
</dependency>
<!-- Jersey media type files, including XML -->
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-jaxb</artifactId>
<version>2.29.1</version>
</dependency>
<!-- Jersey JSON entity providers -->
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.29.1</version>
</dependency>
You can read more about Jersey supported media types in their documentation.
I have selected Jersey Test Framework to implement unit test cases for REST services.But i am getting following issue once i ran the test.
Note: I even add the resteasy-jackson-provider into pom file but couldn't help.
Here is the .pom file dependency
<!-- jersey security dependency -->
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>${jersey.version}</version>
</dependency>
<!-- jersey test framework dependency -->
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-jetty</artifactId>
<version>${jersey.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson-provider</artifactId>
<version>2.3.4.Final</version>
</dependency>
<!--junit Dependency-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
MockServices.Java
#Path("/hello")
public class MockServices {
#GET
#Produces(MediaType.APPLICATION_JSON)
#Path("/world")
public DateVO getHello() {
DateVO j=new DateVO ();
j.setActive(true);
return j;
}
}
MockServicesTest.Java
public class MockServicesTest extends JerseyTest {
#Override
protected Application configure() {
return new ResourceConfig(MockServices.class);
}
#Test
public void test() {
Response hello = target("/hello/world").request().get();
System.out.println(hello.readEntity(String.class));//throw an above exception
}
}
Please let me know how can i overcome this problem.
Override your provider method like this
#Override
protected Application configure() {
ResourceConfig config =new ResourceConfig(MockServices.class).register(JacksonFeature.class).register("Your ContextResolver<ObjectMapper> implementation class");
return config;
}
I had to use explicitly Jersey client implementation to invoke the REST end points.
#Test
public void test() {
final Client client = new JerseyClientBuilder().build();
WebTarget target = client.target("http://localhost:9998");
final Response response =
target.path("/hello/world").request().get();
final String json = response.readEntity(String.class);
}
Reference
I am getting a NullPointerException on an autowired bean in a service class. The class I'm trying to autowire is a Cassandra Repository.
My main class Application.java
#SpringBootApplication
#EnableAutoConfiguration
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
My Cassandra configuration CassandraConfig.java
#Configuration
#EnableCassandraRepositories(basePackages = "com.myretail")
public class CassandraConfig extends AbstractCassandraConfiguration {
#Override
protected String getKeyspaceName() {
return "myretail";
}
#Bean
public CassandraClusterFactoryBean cluster() {
CassandraClusterFactoryBean cluster =
new CassandraClusterFactoryBean();
cluster.setContactPoints("127.0.0.1");
cluster.setPort(9042);
return cluster;
}
#Bean
public CassandraMappingContext cassandraMapping()
throws ClassNotFoundException {
return new BasicCassandraMappingContext();
}
#Bean
public ProductService productService() {
return new ProductService();
}
}
My repository (dao) ProductPriceRepository.java
public interface ProductPriceRepository extends CassandraRepository<ProductPrice> {
#Query("select * from productprice where productId = ?0")
ProductPrice findByProductId(String productId);
}
My service class ProductService.java
#Path("/product")
#Component
public class ProductService {
#Autowired
ProductPriceRepository productPriceRepository;
#GET
#Path("/{id}")
#Produces(MediaType.APPLICATION_JSON)
public Product getTargetProduct(#PathParam("id") String productId) {
String urlString = "https://api.vendor.com/products/v3/" + productId + "?fields=descriptions&id_type=TCIN&key=43cJWpLjH8Z8oR18KdrZDBKAgLLQKJjz";
JSONObject json = null;
try {
json = new JSONObject(JsonReader.getExternalJsonResponse(urlString));
} catch (JSONException e) {
e.printStackTrace();
}
Product product = new Product();
product.setId(productId);
try {
JSONObject productCompositeResponse = json.getJSONObject("product_composite_response");
JSONArray items = productCompositeResponse.getJSONArray("items");
JSONObject item = items.getJSONObject(0);
JSONObject onlineDescription = item.getJSONObject("online_description");
product.setName(onlineDescription.getString("value"));
} catch (JSONException e) {
e.printStackTrace();
}
ProductPrice productPrice = productPriceRepository.findByProductId(productId);
product.setProductPrice(productPrice);
return product;
}
}
My pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.myretail</groupId>
<artifactId>MyRetail</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>MyRetail</name>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>com.datastax.cassandra</groupId>
<artifactId>cassandra-driver-core</artifactId>
<version>2.1.5</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-cassandra</artifactId>
<version>1.4.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.cassandraunit</groupId>
<artifactId>cassandra-unit-spring</artifactId>
<version>2.1.9.2</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.cassandraunit</groupId>
<artifactId>cassandra-unit</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.cassandraunit</groupId>
<artifactId>cassandra-unit-shaded</artifactId>
<version>2.1.9.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hectorclient</groupId>
<artifactId>hector-core</artifactId>
<version>2.0-0</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.18.3</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.18.3</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>1.3.6.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<url>http://localhost:8080/manager/text</url>
<server>my-tomcat</server>
<path>/myRetail</path>
</configuration>
</plugin>
</plugins>
</build>
</project>
It is my understanding that the annotations should pick up the repository and create the bean based off of the #EnableCassandraRepositories annotation. The #Autowired ProductPriceRepository in ProductService.java is always null though when I run this on tomcat. HOWEVER, if I run a junit test against the service call, the bean is properly created, the object is not null, and the tests pass (via #ContextConfiguration annotation).
I've looked at a couple different patterns that I thought might help, but none of them have worked. I can't create an implementation of my interface because Cassandra handles that internally and I'm forced to implement the Cassandra methods.
I feel like something is just slightly off with the annotations somewhere. Any ideas?
The problem is with your pom.xml
For spring-boot Cassandra application, you have to include below dependencies and parent pom in pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.5.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-cassandra</artifactId>
</dependency>
</dependencies>
I'm trying to return xml from my #RestController method -
#RestController
public class MCSController {
.
.
#RequestMapping(value = "/encoders", method = { RequestMethod.GET }, produces = { MediaType.APPLICATION_JSON,
MediaType.APPLICATION_XML })
public List<EncoderVO> getEncoders() {
List<EncoderVO> encoders = null;
try {
encoders = infoService.listEncoders();
} catch (MCSException e) {
logger.error("Error in listing encoders : " + e.getMessage());
}
return encoders;
}
Here is my EncoderVO.java -
#XmlRootElement
public class EncoderVO {
#XmlElement
private Long id;
#XmlElement
private String name;
#XmlElement
private Boolean flagActive;
public EncoderVO() {
}
public EncoderVO(Long id, String name, Boolean flagActive) {
super();
this.id = id;
this.name = name;
this.flagActive = flagActive;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Boolean getFlagActive() {
return flagActive;
}
public void setFlagActive(Boolean flagActive) {
this.flagActive = flagActive;
}
}
This is my pom.xml file -
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.test</groupId>
<artifactId>mcs</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<!-- Inherit defaults from Spring Boot -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.0.RELEASE</version>
</parent>
<properties>
<aws.sdk-version>1.9.1</aws.sdk-version>
<liquibase.version>3.3.0</liquibase.version>
</properties>
<!-- Add typical dependencies for a web application -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<artifactId>jackson-annotations</artifactId>
<groupId>com.fasterxml.jackson.core</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
<exclusions>
<exclusion>
<artifactId>jackson-annotations</artifactId>
<groupId>com.fasterxml.jackson.core</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-broker</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<!-- Aws SDK Dependencies -->
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId>
<version>${aws.sdk-version}</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-elastictranscoder</artifactId>
<version>${aws.sdk-version}</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-sqs</artifactId>
<version>${aws.sdk-version}</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-sns</artifactId>
<version>${aws.sdk-version}</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-datapipeline</artifactId>
<version>${aws.sdk-version}</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-cloudfront</artifactId>
<version>${aws.sdk-version}</version>
</dependency>
</dependencies>
</project>
Below is my Application class -
#SpringBootApplication(exclude = { SpringBootWebSecurityConfiguration.class, LiquibaseAutoConfiguration.class })
#ComponentScan(basePackages = { "com.test.ott.mcs" })
#EnableAspectJAutoProxy
#EnableJms
#EntityScan("com.test.ott.mcs.entities")
#EnableJpaRepositories("com.test.ott.mcs.repository")
public class MCSApplication {
#Bean
JmsListenerContainerFactory<?> jmsContainerFactory(ConnectionFactory connectionFactory) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
// A core poll size of 3 threads and a maximum pool size of 10 threads
factory.setConcurrency("3-10");
return factory;
}
// Using factory pattern with spring annotation
#Bean
public FactoryBean serviceLocatorFactoryBean() {
ServiceLocatorFactoryBean factoryBean = new ServiceLocatorFactoryBean();
factoryBean.setServiceLocatorInterface(EncodingAPIFactory.class);
return factoryBean;
}
public static void main(String args[]) {
SpringApplication.run(MCSApplication.class, args);
}
}
When I hit the url /encoders in browser, i get the below error -
There was an unexpected error (type=Not Acceptable, status=406). Could
not find acceptable representation
The jackson related jars in my calsspath are -
jackson-core-asl : 1.9.13
jackson-jaxrs : 1.9.13
jackson-mapper-asl : 1.9.13
jackson-annotations : 2.6.3
jackson-core : 2.6.3
jackson-module-jaxb-annotations : 2.2.3
jackson-jaxrs-json-provider : 2.2.3
jackson-jaxrs-base : 2.5.4
jackson-databind : 2.6.3
So, I have MappingJackson2HttpMessageConverter in my classpath.
Please suggest. Thanks in advance.
There is a solution that will work out-of-the-box, similarly to JAX-RS but with a bit worse output. The solution uses jackson-dataformat-xml. Add dependency to your project:
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
Response will look like this:
<?xml version="1.0" encoding="UTF-8"?>
<List>
<item>
<id>1</id>
<name>testEncoder1</name>
<flagActive>true</flagActive>
</item>
<item>
<id>2</id>
<name>testEncoder2</name>
<flagActive>true</flagActive>
</item>
<item>
<id>3</id>
<name>testEncoder3</name>
<flagActive>true</flagActive>
</item>
</List>
For further details please look at Spring MVC Way (jackson-dataformat-xml)
try
http://localhost:8080/mcs-0.0.1-SNAPSHOT/encoders.
mcs is the name of the application and
0.0.1-SNAPSHOT the version.
If it doesn't works you have to add a global path into the RequestController. Something like:
#RestController
#RequestMapping(value = "/mcs")
public class MCSController {
.
.
#RequestMapping(value = "/encoders", method = { RequestMethod.GET }, produces = { MediaType.APPLICATION_JSON,
MediaType.APPLICATION_XML })
public List<EncoderVO> getEncoders() {
and this request:
http://localhost:8080/mcs-0.0.1-SNAPSHOT/mcs/encoders
i hope it helps you.
Cheers
Add this dependecy in you POM.xml
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.8</version>
problem is with version of this jar. so please try out this solution