I am trying to create a RESTful web-service and I created one but I am getting a
MessageBodyWriter not found for media type=application/json error
My Todo class:
package com.jersey.jaxb;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import org.pojomatic.Pojomatic;
import org.pojomatic.annotations.AutoProperty;
#XmlRootElement
#XmlType(name = "todo")
#XmlAccessorType(XmlAccessType.FIELD)
#AutoProperty
public class Todo {
#XmlElement(name = "summary")
private final String summary;
#XmlElement(name = "description")
private final String description;
public String getSummary() {
return summary;
}
public String getDescription() {
return description;
}
public Todo() {
this(new Builder());
}
public Todo(Builder builder) {
this.summary = builder.summary;
this.description = builder.description;
}
#Override
public boolean equals(Object o) {
return Pojomatic.equals(this, o);
}
#Override
public int hashCode() {
return Pojomatic.hashCode(this);
}
#Override
public String toString() {
return Pojomatic.toString(this);
}
public static class Builder {
private String description;
private String summary;
public Builder summary(String summary) {
this.summary = summary;
return this;
}
public Builder description(String description) {
this.description = description;
return this;
}
public Todo build() {
return new Todo(this);
}
}
}
And my Resource:-
package com.jersey.jaxb;
import javax.ws.rs.Path;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.Produces;
import javax.ws.rs.GET;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
#Path("/todo")
public class TodoResource {
#GET
#Produces(MediaType.APPLICATION_JSON)
public Response getTodo(){
Todo todo = new Todo.Builder().description("My Todo Object").summary("Created").build();
return Response.status(Status.OK).entity(todo).build();
}
}
My web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<display-name>MyFirstWebService</display-name>
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.jersey.jaxb</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
My Libraries:
aopalliance-repackaged-2.4.0-b10.jar
asm-debug-all-5.0.2.jar
hk2-api-2.4.0-b10.jar
hk2-locator-2.4.0-b10.jar
hk2-utils-2.4.0-b10.jar
jackson-jaxrs-json-provider-2.2.3.jar
javassist-3.18.1-GA.jar
javax.annotation-api-1.2.jar
javax.inject-2.4.0-b10.jar
javax.servlet-api-3.0.1.jar
javax.ws.rs-api-2.0.1.jar
jaxb-api-2.2.7.jar
jersey-client.jar
jersey-common.jar
jersey-container-servlet.jar
jersey-container-servlet-core.jar
jersey-guava-2.17.jar
jersey-media-jaxb.jar
jersey-server.jar
org.osgi.core-4.2.0.jar
osgi-resource-locator-1.0.1.jar
persistence-api-1.0.jar
validation-api-1.1.0.Final.jar
When I run this application on Tomcat server and run this :
http://localhost:8080/MyFirstWebService/rest/todo
I get the error:
SEVERE: MessageBodyWriter not found for media type=application/json,
type=class com.jersey.jaxb.Todo, genericType=class
com.jersey.jaxb.Todo.
You have jackson-jaxrs-json-provider which is a start..
But...
that artifact is still dependent on Jacskon itself, which includes all these artifacts
That's why we use Maven[1] (so we don't have to worry about this kind of thing :-). So go find these.
Then just add the package to the web.xml, and it should work
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>
com.jersey.jaxb,
com.fasterxml.jackson.jaxrs.json
</param-value>
1. Maven dependency
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.2.3</version>
</dependency>
Or use the below Jersey "wrapper" for the above dependency. It will register the Jackson providers (so we don't need to explicitly register like above), and the Jackson exception mappers, and start from version 2.17, provides support for Entity Data Filtering.
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>${jersey2.version}</version>
</dependency>
Note: The fact that we don't have to register anything with the above dependency, is made possible through the Auto-discovery feature of Jersey. If we for some reason disable the auto-discovery, you will want to explicitly register the JacksonFeature.
The solution may be to make ensure that the model classes have a no-argument constructor.
And add this dependency on your pom.XML:
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
</dependency>
I had the same issue, i solved it by addind a empty constructor to the class
public SandBoxClass(){} //-> solved the issue**
public SandBoxClass(Integer arg1, Integer arg2) {
this.arg1=arg1;
this.arg2=arg2;
}
If you already have the jersey-media-moxy dependency added into your pom.xml. Make sure your entity class has the default constructor.
I got this issue when I introduced a paramatrized constructor in the model class. Adding the default constructor again worked for me.
As for me, it helped to register JacksonFeature:
public class App extends ResourceConfig {
public App() {
packages("info.ernestas.simplerest");
register(new JacksonFeature()); // This magical line helped
}
}
Update Library Jax-RS 2.0 and Jersey 2.5.1(JAX-RS-RI) only
Return Bean object(todo) not response because while auto generating json or xml it response create issue.
Answered here: Obtaining "MessageBodyWriter not found for media type=application/json" trying to send JSON object through JAX-RS web service
As stated above:
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
</dependency>
For me I also had to add:
ClientConfig config = new ClientConfig();
config.register(JacksonJsonProvider.class);
return ClientBuilder.newClient(config)
Related
This is my first question on Stack, so I apologize if it's not formatted correctly.
I have an application that sends out an email using an HTML template when a shipment has changed status. The sending mechanism is working as it should, and it is finding my template just fine. The problem is that the email that is sent is just my HTML in plain text and not rendered at all. So instead of a nicely rendered HTML page, the body of the email is just code.
I think the problem lies somewhere in the config file. I have another app that is using an older version of Thymeleaf and works exactly as it should, but unfortunately the setup for that is outdated and no longer works. Also, I have attempted a few different config options, as shown in the commented out portion of my code.
I have checked every line of the HTML template to make sure there are no unclosed tags or symbols that would escape the HTML. All data is being pulled over from the controller into the template, and I have checked to make sure the template is displayed properly in a browser. It's just when it puts everything together and sends the email that it fails to work and doesn't render.
I have included my pom file, a relevant portion from the app.config, and the app.config itself. Again, this is my first question on here, so if I'm missing something I'd be happy to add it, and if the question is formatted wrong I apologize and am open to critique on how to do it correctly.
Thank you.
The app is using Spring Boot 2.1.1, Spring 5, and Thymeleaf 3.0.11. I have also tried using Spring 4, as well as downgraded versions of Thymeleaf.
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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.api</groupId>
<artifactId>tms-scheduled-tasks</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>tms-scheduled-tasks</name>
<description>TMS Scheduled Tasks</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-mail -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>3.0.11.RELEASE</version>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>3.0.11.RELEASE</version>
</dependency>
<dependency>
<groupId>net.sourceforge.nekohtml</groupId>
<artifactId>nekohtml</artifactId>
</dependency>
<dependency>
<groupId>nz.net.ultraq.thymeleaf</groupId>
<artifactId>thymeleaf-layout-dialect</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
</plugins>
</build>
</project>
From application.properties
# Thymeleaf
spring.thymeleaf.mode=HTML
spring.thymeleaf.cache=false
AppConfig
package com.api.tmsscheduledtasks.config;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import
org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.thymeleaf.spring5.SpringTemplateEngine;
import
org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver;
import org.thymeleaf.spring5.view.ThymeleafViewResolver;
#Configuration
#EnableWebMvc
#ComponentScan("com.api")
public class AppConfig implements WebMvcConfigurer {
private ApplicationContext applicationContext;
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/WEB-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
/**
* According to some resource I can no longer remember
*/
#Bean
public SpringResourceTemplateResolver templateResolver() {
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
templateResolver.setApplicationContext(this.applicationContext);
templateResolver.setPrefix("classpath:/templates/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode("HTML");
return templateResolver;
}
#Bean
SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
return templateEngine;
}
#Bean
public ViewResolver viewResolver() {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine());
return viewResolver;
}
/**
* According to Baeldung
*/
// #Bean
// public ViewResolver htmlViewResolver() {
// ThymeleafViewResolver resolver = new ThymeleafViewResolver();
// resolver.setTemplateEngine(templateEngine((templateResolver())));
// resolver.setContentType("text/html");
// resolver.setCharacterEncoding("UTF-8");
// resolver.setViewNames(ArrayUtil.array("*.html"));
//
// return resolver;
// }
//
// private ISpringTemplateEngine templateEngine(ITemplateResolver
templateResolver) {
// SpringTemplateEngine engine = new SpringTemplateEngine();
// engine.setTemplateResolver(templateResolver);
// return engine;
// }
//
// private ITemplateResolver templateResolver() {
// SpringResourceTemplateResolver templateResolver = new
SpringResourceTemplateResolver();
// templateResolver.setApplicationContext(applicationContext);
// templateResolver.setPrefix("classpath:/templates/");
// templateResolver.setSuffix(".html");
// templateResolver.setCacheable(false);
// templateResolver.setTemplateMode(TemplateMode.HTML);
//
// return templateResolver;
// }
/**
* According to thymeleaf.org
*/
// public void setApplicationContext(ApplicationContext
applicationContext) {
// this.applicationContext = applicationContext;
// }
//
// #Bean
// public ViewResolver viewResolver() {
// ThymeleafViewResolver resolver = new ThymeleafViewResolver();
// resolver.setTemplateEngine(templateEngine());
// resolver.setCharacterEncoding("UTF-8");
// return resolver;
// }
//
// #Bean
// public TemplateEngine templateEngine() {
// SpringTemplateEngine engine = new SpringTemplateEngine();
// engine.setEnableSpringELCompiler(true);
// engine.setTemplateResolver(templateResolver());
// return engine;
// }
//
// private ITemplateResolver templateResolver() {
// SpringResourceTemplateResolver resolver = new
SpringResourceTemplateResolver();
// resolver.setApplicationContext(applicationContext);
// resolver.setPrefix("/WEB-INF/templates/");
// resolver.setTemplateMode(TemplateMode.HTML);
// return resolver;
// }
/**
* Old setup from other app
*/
// #Bean
// public TemplateResolver templateResolver() {
// TemplateResolver templateResolver = new
ClassLoaderTemplateResolver();
// templateResolver.setSuffix(".html");
// templateResolver.setTemplateMode("HTML");
//
// return templateResolver;
// }
EDIT
After talking to a colleague at work he discovered the issue. It turns out I overlooked the Email class where everything was being built. It was a fairly silly mistake on my part, but I'll post the original code below and then the answer.
import org.springframework.mail.SimpleMailMessage;
public class Email {
private SimpleMailMessage message;
public Email setFrom(String from) {
getMessage().setFrom(from);
return this;
}
public Email setTo(String to) {
getMessage().setTo(to);
return this;
}
public Email setSubject(String subject) {
getMessage().setSubject(subject);
return this;
}
public Email setText(String text) {
getMessage().setText(text);
return this;
}
public SimpleMailMessage build() {
return getMessage();
}
protected SimpleMailMessage getMessage() {
if (message == null) {
message = new SimpleMailMessage();
}
return this.message;
}
}
Again. The solution was very simple, but I it was something I had overlooked in the Email class, I should have removed the SimpleMailMessage and replaced it with a MimeMessagePreparator. Nothing was wrong at all in the config or any of that. Just me overlooking an old method from when it was set up and forgetting to change it. Here is the change that was made.
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.mail.javamail.MimeMessagePreparator;
public class Email {
private String from;
private String to;
private String subject;
private String text;
public Email setFrom(String from) {
this.from = from;
return this;
}
public Email setTo(String to) {
this.to = to;
return this;
}
public Email setSubject(String subject) {
this.subject = subject;
return this;
}
public Email setText(String text) {
this.text = text;
return this;
}
public MimeMessagePreparator build() {
return mimeMessage -> {
MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage);
messageHelper.setFrom(from);
messageHelper.setTo(to);
messageHelper.setSubject(subject);
messageHelper.setText(text, true);
};
}
}
I am running google app engine and using JAVAEE.
I have a two filters but only one is configured with restrictions.
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">
<filter>
<filter-name>connexionFilter</filter-name>
<filter-class>AHSFilters.connexionFilter</filter-class>
</filter>
<filter>
<filter-name>restrictFilter</filter-name>
<filter-class>AHSFilters.restrictFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>connexionFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>restrictFilter</filter-name>
<url-pattern>/client</url-pattern>
<url-pattern>/admin</url-pattern>
</filter-mapping>
</web-app>
I first login so I can go trough the first filter.
I change my url to localhost:8080/client
my connexion filter is as so:
package AHSFilters;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class connexionFilter implements Filter {
#Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
}
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
HttpSession session = req.getSession();
if(session.getAttribute("sessionUser") != null)
chain.doFilter(req, resp);
if (req.getHeader("X-Requested-With") != null)
chain.doFilter(req, resp);
else
req.getServletContext().getRequestDispatcher("/").forward(request, response);
// TODO Auto-generated method stub
}
#Override
public void destroy() {
// TODO Auto-generated method stub
}
}
my servlet is as so:
package AHSServlets;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
#WebServlet(
name = "ClientServ",
urlPatterns = {"/client"}
)
public class ClientServ extends HttpServlet{
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
response.getWriter().flush();
this.getServletContext().getRequestDispatcher("/restrict/client/test.jsp").forward(request, response);;
}
}
when my file is setted to test.jsp I go to the correct page, but when I rename it to test.html and of course change the path in getRequestDispatcher I get redirected to my login page (/ route).
So I have to files /restrict/client/test.jsp i get the correct response
and /restrict/client/test.html I go back to the signin page.
I've tried putting a simple hello in test.html also tried with valid html page with the same result. Is there any settings I'm missing in order to allow html?
Where could it come from? Any help is greatly appreciated.
I think in order to do so you need little configuration. In web.xml write a configuration code
<jsp-config>
<jsp-property-group>
<url-pattern>*.html</url-pattern>
</jsp-property-group>
</jsp-config>
To understand better you can check
Can you render a file without a .jsp extension as a JSP?
Running .jsp as .html file
Have a method that returns List and want it to be sent to the client as JSON. Getting an exception "A message body writer for Java class java.util.ArrayList, and Java type java.util.List, and MIME media type application/json was not found."
I've added the #XMLRootElement annotation to my class declaration and added the POJO mapping param to web.xml but it doesn't work
Using Atmosphere 2.2.3 with Atmosphere-Jersey 2.2.3
POM
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.atmosphere</groupId>
<artifactId>atmosphere-runtime</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>org.atmosphere</groupId>
<artifactId>atmosphere-jersey</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>javax.xml</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.1</version>
</dependency>
</dependencies>
RESTFul resource:
package com.foo;
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
#Path("currencypairs")
#Produces(MediaType.APPLICATION_JSON)
public class CurrencyPairs {
#GET
#Path("foo")
public List<Thing> getPairs() {
List<Thing> ret = new ArrayList<Thing>();
ret.add(new Thing("CAD","USD"));
ret.add(new Thing("EUR", "USD"));
ret.add(new Thing("GBP","EUR"));
return ret;
}
}
Thing class:
package com.foo;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
public class Thing {
#XmlElement
private String a;
#XmlElement
private String b;
public Thing(String a, String b)
{
this.setA(a);
this.setB(b);
}
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
public String getB() {
return b;
}
public void setB(String b) {
this.b = b;
}
}
Web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:j2ee="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2.5.xsd">
<description>AtmosphereServlet</description>
<display-name>AtmosphereServlet</display-name>
<context-param>
<param-name>resteasy.scan</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>resteasy.scan.providers</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>resteasy.scan.resources</param-name>
<param-value>false</param-value>
</context-param>
<servlet>
<description>AtmosphereServlet</description>
<servlet-name>AtmosphereServlet</servlet-name>
<servlet-class>org.atmosphere.cpr.AtmosphereServlet</servlet-class>
<!-- If you want to use Servlet 3.0 -->
<async-supported>true</async-supported>
<!-- List of init-param -->
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.foo</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>AtmosphereServlet</servlet-name>
<!-- Any mapping -->
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
Add jersey-json-1.6.jar to your dependencies.
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.6</version>
</dependency>
Has anyone managed to get wildfly's undertow to work with Primefaces push 2.0? Wildfly's native websockets (jee7) works great on it's own. I'm not sure how to integrate with primefaces. Any examples would be helpful.
I got this working on WildFly 8.1.0.Final with:
pom.xml:
<dependency>
<groupId>org.atmosphere</groupId>
<artifactId>atmosphere-runtime</artifactId>
<version>2.1.6</version>
</dependency>
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>5.0</version>
</dependency>
web.xml:
<servlet>
<servlet-name>PrimePushServlet</servlet-name>
<servlet-class>org.primefaces.push.PushServlet</servlet-class>
<init-param>
<param-name>org.atmosphere.cpr.broadcasterCacheClass</param-name>
<param-value>org.atmosphere.cache.UUIDBroadcasterCache</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>PrimePushServlet</servlet-name>
<url-pattern>/primepush/*</url-pattern>
</servlet-mapping>
in .xhtml:
<p:socket onMessage="handleMessage" channel="/#{request.remoteUser}" />
<script type="text/javascript">
function handleMessage(facesmessage) {
var msgdetail = $.base64.decode(facesmessage.detail);
facesmessage.detail = msgdetail;
PF('growlWidget').show([ facesmessage ]);
}
</script>
My Resource:
#PushEndpoint("/{user}")
#Singleton
public class UserResource {
#PathParam("user")
private String user;
#OnMessage(encoders = { JSONEncoder.class }, decoders = { JSONDecoder.class })
public FacesMessage onMessage(FacesMessage message) {
return message;
}
The javascript-part should be modified to match your demand.
Wildfly 9.0.2
pom.xml
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>org.atmosphere</groupId>
<artifactId>atmosphere-runtime</artifactId>
<version>2.3.5</version>
</dependency>
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>5.2</version>
</dependency>
web.xml
<servlet>
<servlet-name>PrimePushServlet</servlet-name>
<servlet-class>org.primefaces.push.PushServlet</servlet-class>
<init-param>
<param-name>org.atmosphere.cpr.broadcasterCacheClass</param-name>
<param-value>org.atmosphere.cache.UUIDBroadcasterCache</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>PrimePushServlet</servlet-name>
<url-pattern>/primepush/*</url-pattern>
xhtml
<p:socketonMessage="handleMessage" channel="/counter" />
js
function handleMessage(data) {
console.log(data);
}
Java
import org.primefaces.push.annotation.OnMessage;
import org.primefaces.push.annotation.PushEndpoint;
import org.primefaces.push.impl.JSONEncoder;
#PushEndpoint("/counter")
public class MessageResources {
#OnMessage(encoders = {JSONEncoder.class})
public String onMessage(String count) {
return count;
}
}
More java
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import org.primefaces.push.EventBus;
import org.primefaces.push.EventBusFactory;
#ManagedBean
#SessionScoped
public class GlobalMessageControler implements Serializable {
private static final long serialVersionUID = -4507223739929042795L;
private volatile int count;
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public void increment() {
count++;
EventBus eventBus = EventBusFactory.getDefault().eventBus();
eventBus.publish("/counter", String.valueOf(count));
}
}
I'm creating a REST service which accepts input as PathParam and produces JSON Response. The code is working fine and I can able to build the response. After returning the response, REST is throwing an error like "COULD NOT FIND WRITER OR DATASOURCEPROVIDER FOR (ResponseClass) and MediaType application/json". Thanks.
This is how I got jackson 2.1.3 working with Wink as a JSON provider.
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.core.Application;
//see http://www.ibm.com/developerworks/web/library/wa-aj-jackson/
import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
import com.fasterxml.jackson.databind.AnnotationIntrospector;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector;
import com.fasterxml.jackson.databind.type.TypeFactory;
/**
* #see https://cwiki.apache.org/WINK/jax-rs-getting-started.html
*/
public class JaxrsApp extends Application {
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> classes = new HashSet<Class<?>>();
classes.add(YourJaxRSAnnotated.class);
//...
return classes;
}
#Override
public Set<Object> getSingletons() {
Set<Object> s = new HashSet<Object>();
// See http://wiki.fasterxml.com/JacksonJAXBAnnotations for more information
ObjectMapper mapper = new ObjectMapper();
AnnotationIntrospector primary = new JaxbAnnotationIntrospector( TypeFactory.defaultInstance() );
AnnotationIntrospector secondary = new JacksonAnnotationIntrospector();
AnnotationIntrospector pair = AnnotationIntrospector.pair(primary, secondary);
mapper.getDeserializationConfig().with(pair);
mapper.getSerializationConfig().with(pair);
// Set up the provider
JacksonJaxbJsonProvider jaxbProvider = new JacksonJaxbJsonProvider();
jaxbProvider.setMapper(mapper);
s.add(jaxbProvider);
return s;
}
}
then, in web.xml
<servlet>
<servlet-name>JAX-RS Servlet</servlet-name>
<servlet-class>org.apache.wink.server.internal.servlet.RestServlet</servlet-class>
<!-- this param tells the RestServlet which custom Application sub-class
will return a list of our classes that have JAX-RS annotations -->
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.example.JaxrsApp</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
I suppose you use Jersey.
First of all, check the dependencies: http://jersey.java.net/nonav/documentation/latest/chapter_deps.html#d4e1716
Here is my pom.xml:
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.15</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.15</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.15</version>
</dependency>
I myself found that the WinkApplication is not loaded properly. The restsdkservice configuration in web.xml was incorrect and because of that JacksonJaxbJsonProvider was not loaded into the Wink. Finally got it after 2 days. Thanks everyone!!