Jackson Serielize / Deserielize Date - rest

Iam a beginner to Java and Jersey Restful service, I try to use Jackson to
serielize/deserialize a date, but I can't get it to work
the frontend is a JavaFX application with a Jersey client and I include
the following library to classpath (Jersey client and Jackson jar file)
cglib-2.1.88.jar
guava-14.0.1.jar
hk2-api-2.1.88.jar
hk2-locator-2.1.88.jar
hk2-utils-2.1.88.jar
jackson-annotations-2.7.2.jar
jackson-core-2.7.2.jar
jackson-databind-2.7.2.jar
jackson-jaxrs-base-2.7.2.jar
jackson-jaxrs-json-provider-2.7.2.jar
javax.annotation-api-1.2.jar
javax.inject-2.1.88.jar
javax.ws.rs-api-2.0.jar
jersey-client.jar
jersey-common.jar
persistence-api-1.0.jar
org.osgi.core-4.2.0.jar
osgi-resource-locator-1.0.1.jar
the backend is a Maven Jersey restful service archetype project
groupid: org.glassfish.jersey.archetypes
artifactId: jersey-quickstart-webapp
and in the pom.xml I have add
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.7.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.7.2</version>
</dependency>
on both frontend and backend I have a Student class
import java.util.Date;
#XmlRootElement
public class Student {
public Student () { };
Date regDate;
}
frontend code:
Client client = ClientBuilder.newClient();
Student student = client.target("urlpath").path(servicepath).request(APPLICATION.JSON).get(Student.class);
when I make a GET request I get a deserilize Student object with date
Student {
regDate: "2016-04-09 12:23AM ... // this is RIGHT "
}
but when I make a PUT request, on the backend I get a Student object with
Student {
regDate: null; // this is WRONG
}
Did I miss some library on the frontend or some dependency on the backend ...
Did anybody having the same problem as I have, please help .....

Related

Maintaining the original traceId while passing messages through Kafka with quarkus and opentracing

I'm trying to create the most basic working example with two Quarkus (2.4.1.Final) microservices (a producer and a consumer) that communicate through Kafka and are traced with opentracing.
I have followed the kafka and the opentracing tutorial, ran the producer and consumer in dev mode (so they create that redpanda kafka broker), and then attempted to emit a POJO and log the traceId in both the consumer and producer. As far as I understand, this should work out of the box.
The POJO is sent, serialized and de-serialized without a hitch. The kafka message header that the consumer receives even has the correct original trace and span id injected into it (I've checked with debugging both the producer and consumer) using that uber-trace-id field.
But, for some reason, when logging the trace id, they don't match. It's like the tracing context "forgets" about the span it receives via kafka. Note that my business need is to just print the traceId every log so we can follow printed logs through kibana.
The producer:
package com.example;
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 org.eclipse.microprofile.reactive.messaging.Channel;
import org.eclipse.microprofile.reactive.messaging.Emitter;
import org.jboss.logging.Logger;
#Path("/hello")
public class ExampleResource {
private static final Logger log = Logger.getLogger(ExampleResource.class);
private final Emitter<Person> peopleEmitter;
public ExampleResource(#Channel("people") Emitter<Person> peopleEmitter) {this.peopleEmitter = peopleEmitter;}
#GET
#Path("/{name}")
#Produces(MediaType.APPLICATION_JSON)
public Person hello(#PathParam("name") String name) {
var p = new Person();
p.name = name;
log.info("Produced " + p.name);
peopleEmitter.send(p);
return p;
}
}
The consumer:
package com.example;
import org.eclipse.microprofile.opentracing.Traced;
import org.eclipse.microprofile.reactive.messaging.Incoming;
import org.jboss.logging.Logger;
import javax.enterprise.context.ApplicationScoped;
#ApplicationScoped
public class PeopleConsumer {
private static final Logger log = Logger.getLogger(PeopleConsumer.class);
#Traced
#Incoming("people")
public void process(Person person) {
log.info("received " + person.name);
}
}
The POJO:
package com.example;
public class Person {
public String name;
}
App config for the producer:
quarkus.application.name=producer
quarkus.http.port=8090
quarkus.log.console.format=%d{HH:mm:ss} %-5p traceId=%X{traceId}, spanId=%X{spanId}, [%c{2.}] (%t) %s%e%n
mp.messaging.outgoing.people.connector=smallrye-kafka
mp.messaging.outgoing.people.interceptor.classes=io.opentracing.contrib.kafka.TracingProducerInterceptor
And the consumer:
quarkus.http.port=8091
quarkus.application.name=consumer
quarkus.log.console.format=%d{HH:mm:ss} %-5p traceId=%X{traceId}, spanId=%X{spanId}, [%c{2.}] (%t) %s%e%n
mp.messaging.incoming.people.connector=smallrye-kafka
mp.messaging.incoming.people.interceptor.classes=io.opentracing.contrib.kafka.TracingConsumerInterceptor
Serializer/deserializer
public class PersonDeserializer extends ObjectMapperDeserializer<Person> {
public PersonDeserializer() {
super(Person.class);
}
}
public class PersonSerializer extends ObjectMapperSerializer<Person> {
}
The dependencies (same for both):
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-opentracing</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-reactive-messaging-kafka</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-context-propagation</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-arc</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-reactive-jackson</artifactId>
</dependency>
<dependency>
<groupId>io.opentracing.contrib</groupId>
<artifactId>opentracing-kafka-client</artifactId>
</dependency>
</dependencies>
Basic use case:
Put http://localhost:8090/hello/John into a browser. You will see log at the producer:
18:43:24 INFO traceId=00019292a43349df, spanId=19292a43349df, [co.ex.ExampleResource] (executor-thread-0) Produced John
And at the consumer
18:43:25 INFO traceId=1756e0a24c740fa6, spanId=1756e0a24c740fa6, [co.ex.PeopleConsumer] (pool-1-thread-1) received John
Notice the trace ids being different. I am not sure what else I'm supposed to be doing/configuring...

How to integrate Keycloak with Spring boot(API) without login page

There's need to integrate Keycloak with my spring boot application. What i need is that any REST request coming to my API will have a header e.g. "Authorisation" which will have value as "basic " to be used as auth token.
The request came to API should be validated from keyclaok without redirecting to any login page of keycloak.
All the tutorials to integrate keycloak with spring boot shows a login page or pre generated bearer token.
When i try to do this, below is my SecurityConfig.java:
#Configuration
#EnableWebSecurity
#ComponentScan(basePackageClasses = KeycloakSecurityComponents.class)
class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
auth.authenticationProvider(keycloakAuthenticationProvider);
}
#Bean
public KeycloakSpringBootConfigResolver keycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
#Bean
#Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.authorizeRequests().antMatchers("/myapi*").hasRole("user").anyRequest().permitAll();
}
}
My application.properties:
server.port=8081
keycloak.auth-server-url=http://localhost:9080/auth
keycloak.realm=myrealm
keycloak.resource=myclient
keycloak.public-client=false
keycloak.credentials.secret=mysecret
keycloak.use-resource-role-mappings=true
keycloak.enabled=true
keycloak.ssl-required=external
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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.7.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.example.api</groupId>
<artifactId>springboot-kc-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-kc-api</name>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.keycloak.bom</groupId>
<artifactId>keycloak-adapter-bom</artifactId>
<version>6.0.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-boot-starter</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Whenever a GET request is made, keycloak debug shows below log:
o.k.adapters.OAuthRequestAuthenticator : Sending redirect to login page: http://localhost:9080/auth/realms/myrealm/protocol/openid-connect/auth?response_type=code&client_id=myclient&redirect_uri=http%3A%2F%2Flocalhost%3A8081%2Fmyapi%2Fsampleget?param1=val1&state=a2b5072a-acb8-4bf6-8f33-b3f25deab492&login=true&scope=openid
Keycloak configuration:
Client Protocol : openid-connect
Access Type : confidential
Valid Redirect URIs: http://localhost:8081/myapi/*
Above setup working fine for an API written in Java REST Easy framework for one of existing application running on JBoss EAP 7.
Need help to understand how to configure spring boot API to use auth header in request to authenticate & authorise request.
This can be achieved by enabling the bearer only mode. Start with enabling this in your spring boot service via application.properties:
keycloak.bearer-only=true
See [1] for more details on this.
You can also enforce this inside the admin console for your client.
[1] https://www.keycloak.org/docs/latest/securing_apps/index.html#_java_adapter_config
You need to enable basic auth in the adapter configuration and also send the client secret. What this will do is not redirect to login page but send 401 if the basic auth headers are missing.
keycloak.enable-basic-auth=true
keycloak.credentials.secret=${client.secret}
Check out here for solution.
I just wanna give you the class which is created to talk to Keycloak through the api in spring boot. I think this will help you!
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder
import org.keycloak.admin.client.Keycloak
import org.keycloak.admin.client.KeycloakBuilder
import org.keycloak.admin.client.resource.RealmResource
import org.keycloak.admin.client.resource.UsersResource
import org.springframework.beans.factory.annotation.Value
import org.springframework.stereotype.Component
#Component
class KeycloakComponent {
#Value("\${keycloakconfig.server.url}")
var serverUrl: String = ""
#Value("\${keycloakconfig.username}")
var username: String = ""
#Value("\${keycloakconfig.password}")
var password: String = ""
#Value("\${keycloakconfig.realm}")
var realmName: String = ""
#Value("\${keycloakconfig.client.id}")
var clientId: String = ""
#Value("\${keycloakconfig.client.secret}")
var clientSecret: String = ""
val keycloak: Keycloak by lazy {
KeycloakBuilder.builder()
.serverUrl(serverUrl)
.username(username)
.password(password)
.realm(realmName)
.clientId(clientId)
.clientSecret(clientSecret)
.resteasyClient(ResteasyClientBuilder().connectionPoolSize(20).register(CustomJacksonProvider()).build())
.build()
}
val realm: RealmResource by lazy {
keycloak.realm(realmName)
}
val userResource: UsersResource by lazy {
realm.users()
}
fun keycloakForFetchUserToken(username:String, password: String): Keycloak {
return KeycloakBuilder.builder()
.serverUrl(serverUrl)
.username(username)
.password(password)
.realm(realmName)
.clientId(clientId)
.clientSecret(clientSecret)
.resteasyClient(ResteasyClientBuilder().connectionPoolSize(20).register(CustomJacksonProvider()).build())
.build()
}
}
If something does not make sense, do not hesitate to contact

spring boot with java + groovy _maven in embedded tomcat, controller but error

Sorry if this is already answered, I am not able to find it.
I have created new project using spring boot.
My requirements are that I have some java classes, some groovy classes and they should be able to call each others.
I am using maven and running my embedded tomcat by
mvn spring-boot:run
Problem is, RestController which is Java Class is there and I am able to call it REST URL.
But the controller which is in Groovy, is not able to be called and gives me error.
curl localhost:8080/
{"timestamp":1455913384508,"status":404,"error":"Not Found","message":"No message available","path":"/"}
Good part is that I am able to call groovy class from java.
Below are my files.
<?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>org.springframework</groupId>
<artifactId>gs-spring-boot</artifactId>
<version>0.1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.2.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>2.3.7</version>
</dependency>
</dependencies>
<properties>
<java.version>1.8</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<!-- 2.8.0-01 and later require maven-compiler-plugin 3.1 or higher -->
<version>3.1</version>
<configuration>
<compilerId>groovy-eclipse-compiler</compilerId>
</configuration>
<dependencies>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-eclipse-compiler</artifactId>
<version>2.9.1-01</version>
</dependency>
<!-- for 2.8.0-01 and later you must have an explicit dependency on
groovy-eclipse-batch -->
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-eclipse-batch</artifactId>
<version>2.3.7-01</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>
app.groovy:
package hello
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;
#RestController
class ThisWillActuallyRun {
#RequestMapping("/home")
String home() {
return "Hello World!"
}
}
Application.java
package hello;
import java.util.Arrays;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
#SpringBootApplication
public class Application {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(Application.class, args);
System.out.println("Let's inspect the beans provided by Spring Boot:");
String[] beanNames = ctx.getBeanDefinitionNames();
Arrays.sort(beanNames);
for (String beanName : beanNames) {
System.out.println(beanName);
}
}
}
Controller class
package hello;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;
#RestController
public class HelloController {
#RequestMapping("/hello")
public String index() {
ThisWillActuallyRun t = new ThisWillActuallyRun() ;
String v = t.home() ;
System.out.println("value from groovy="+v) ;
return "Greetings from Spring Boot!";
}
}
This works:
curl localhost:8080/hello
Greetings from Spring Boot!
Thanks a lot for the help.
I don't see a problem with your Groovy controller ThisWillActuallyRun
One concern I would have is that you have 2 separate controllers, but did not provide a #RequestMapping(path="controllerpath") at the top of your class on each controller. You did not specify a unique context (relative path) to your controller.
In addition, your curl command only goes to "/". I don't see any mapping for that.
It may work if you curl to "/home", just like you did for "/hello". Regardless, it is a better practice to give a controller level path as well.
An example of how the URL would look if you annotated the #RequestMapping at the top of your 2 controllers might look like:
#RestController
#RequestMapping(path="destination")
class ThisWillActuallyRun {
#RequestMapping("/home")
String home() { }
}
#RestController
#RequestMapping(path="greeting")
public class HelloController {
#RequestMapping("/hello")
public String index() {}
}
Then to reach the 2 endpoints would look like:
http://localhost:8080/destination/home
http://localhost:8080/greeting/hello

No injection source found for a parameter of type public javax.ws.rs.core.Response - Jersey - MultiPartFeature

I'm creating a web service with Jersey and Jetty Embedded with no web.xml file. It is very simple, It receive a binary file by a POST from a HTML form. It seems I didn't register the MultiPart Feature properly because When I try to use it with HTML form I get this error :
*
WARNING: No injection source found for a parameter of type public
javax.ws.rs.core.Response
org.multipart.demo.ReceiveFile.postMsg(java.io.InputStream,org.glassfish.jersey.media.multipart.FormDataContentDisposition)
throws java.lang.Exception at index 0. 2016-02-09
21:49:59.916:WARN:/:qtp1364335809-16: unavailable
org.glassfish.jersey.server.model.ModelValidationException: Validation
of the application resource model has failed during application
initialization.|[[FATAL] No injection source found for a parameter of
type public javax.ws.rs.core.Response
org.multipart.demo.ReceiveFile.postMsg(java.io.InputStream,org.glassfish.jersey.media.multipart.FormDataContentDisposition)
throws java.lang.Exception at index 0.;
source='ResourceMethod{httpMethod=POST,
consumedTypes=[multipart/form-data], producedTypes=[text/plain],
suspended=false, suspendTimeout=0,
I was looking for the solution for weeks, I have read all question related to this error on StackOverflow, for instance:
MULTIPART_FORM_DATA: No injection source found for a parameter of type public javax.ws.rs.core.Response
Jersey 2 injection source for multipart formdata
They didn't help me because Im not using web.xml
I have 3 classes
- ReceiveFile.class (try to receive the POST)
- resourceConfig.class (try to register the MultiPart feature)
- JettyServer.class (create server instance)
ReceiveFile.class
package org.multipart.demo;
import java.io.InputStream;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam;
#Path("/resources")
public class ReceiveFile
{
#POST
#Path("/fileUpload")
#Produces("text/plain")
#Consumes(MediaType.MULTIPART_FORM_DATA)
public Response postMsg (
#FormDataParam("file") InputStream stream,
#FormDataParam("file") FormDataContentDisposition fileDetail) throws Exception {
Response.Status respStatus = Response.Status.OK;
return Response.status(respStatus).build();
}
}
resourceConfig.class
package org.multipart.demo;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import org.glassfish.jersey.media.multipart.MultiPart;
import org.glassfish.jersey.media.multipart.MultiPartFeature;
import org.glassfish.jersey.server.ResourceConfig;
/**
* Registers the components to be used by the JAX-RS application
*
*/
#ApplicationPath("/resources/fileUpload")
public class resourceConfig extends ResourceConfig {
/**
* Register JAX-RS application components.
*/
public resourceConfig(){
register(ReceiveFile.class);
register(JettyServer.class);
register(MultiPartFeature.class);
//packages("org.glassfish.jersey.media", "com.mypackage.providers");
}
}
JettyServer.class
package org.multipart.demo;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.server.handler.ResourceHandler;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.glassfish.jersey.media.multipart.MultiPartFeature;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.ServerProperties;
public class JettyServer
{
// private static final Logger LOGGER = Logger.getLogger(UploadFile.class.getName());
public static void main(String[] args) throws Exception
{
ResourceConfig config = new ResourceConfig();
config.packages("org.multipart.demo");
Server jettyServer = new Server(8080);
ResourceHandler resource_handler = new ResourceHandler();
// Configure the ResourceHandler. Setting the resource base indicates where the files should be served out of.
// In this example it is the current directory but it can be configured to anything that the jvm has access to.
resource_handler.setDirectoriesListed(true);
resource_handler.setWelcomeFiles(new String[]{ "./index.html" , "./html/FileUpload.html" });
resource_handler.setResourceBase(".");
//Jersey ServletContextHandler
final ResourceConfig resourceConfig = new ResourceConfig(ReceiveFile.class);
resourceConfig.register(MultiPartFeature.class);
ServletContextHandler servletContextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
ServletHolder jerseyServlet = servletContextHandler.addServlet(org.glassfish.jersey.servlet.ServletContainer.class, "/*" );
jerseyServlet.setInitParameter(ServerProperties.PROVIDER_PACKAGES, "org.multipart.demo");
// Add the ResourceHandler to the server.
HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[] { resource_handler, servletContextHandler, new DefaultHandler() });
jettyServer.setHandler(handlers);
try {
jettyServer.start();
jettyServer.join();
} finally {
jettyServer.destroy();
}
}
}
the 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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org</groupId>
<artifactId>multipart.demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>multipart.demo</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>9.2.3.v20140905</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>9.2.3.v20140905</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-jetty-http</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.jvnet.mimepull</groupId>
<artifactId>mimepull</artifactId>
<version>1.9.6</version>
</dependency>
</dependencies>
</project>
Thanks in advance!
I See three different ResourceConfigs in your codebase, but none of them are actually used for the application. So the MultiPartFeature is never register, which is what is causing the error. You have a few options on how to use a ResourceConfig in your case.
You can instantiate the ServletContainer, passing in the ResourceConfig instance. Unfortunately, there is no ServletContextHolder#addServlet(Servlet) method, but there is a ServletContextHolder#addServlet(ServletHolder) method, so we need to wrap the ServletContainer in a ServletHolder
ServletHolder jerseyServlet = new ServletHolder(new ServletContainer(resourceConfig));
servletContextHolder.addServlet(jerseyServlet, "/*");
With the above option, you can use a local instance or a subclass, but if you only have a subclass, like your first bit of code, then you add a servlet init param, that specifies the ResourceConfig subclass.
ServletContextHandler servletContextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
ServletHolder jerseyServlet = servletContextHandler.addServlet(org.glassfish.jersey.servlet.ServletContainer.class, "/*" );
jerseyServlet.setInitParameter(ServerProperties.PROVIDER_PACKAGES, "org.multipart.demo");
jerseyServlet.setInitParameter(ServletProperties.JAXRS_APPLICATION_CLASS, resourceConfig.class.getCanonicalName());
Notice the last call where I set the application class name.
Without using a ResourceConfig, you could just register the MulitPartFeature with an init param
jerseyServlet.setInitParameter(ServerProperties.PROVIDER_CLASSNAMES, MultiPartFeature.class.getCanonicalName());

Getting error on pubsub example using Atmosphere + Jersey

I'm following the tutorial here
http://jfarcand.wordpress.com/2011/06/29/rest-websocket-applications-why-not-using-the-atmosphere-framework/
I already have a Jersey project up and running and working fine using JBoss 7. The one difference i have is that i am using Jersey with Spring. So my JQueryPubSub looks like this
#Service <-- For Spring component Scan
#Path("/pubsub/{topic}")
#Produces("text/html;charset=ISO-8859-1")
public class JQueryPubSub {
#PathParam("topic")
Broadcaster topic;
#GET
public SuspendResponse<String> subscribe() {
return new SuspendResponse.SuspendResponseBuilder<String>()
.broadcaster(topic)
.outputComments(true)
.addListener(new EventsLogger())
.build();
}
#POST
#Broadcast
public Broadcastable publish(#FormParam("message") String message) {
return new Broadcastable(message, "", topic);
}
}
So i wanted to add this example but i'm getting
22:55:27,381 SEVERE [com.sun.jersey.spi.inject.Errors] (MSC service thread 1-3) The following errors and warnings have been detected with resource
and/or provider classes:
SEVERE: Missing dependency for field: org.atmosphere.cpr.Broadcaster com.order.resources.JQueryPubSub.topic
Any ideas how i can fix this issue and why Jersey seems to be aggressively injecting the value into broadcaster??
I had the same problem and was able to fix it by updating jersey jars from 1.4 to 1.6
If you use maven, you can add the following dependencies.
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.6</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>1.6</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.6</version>
</dependency>
Answering after long time..but people who are trying can still take some advantage out of this
You can try with the following .
I just tried and it worked for me
Step-1
If you are using weblogic 12 c make the following change
function subscribe() {
var request = {
url :document.location.origin+'/<your-context-path>/ws/pubsub/' + getElementByIdValue('topic'),
Step-2
In web.xml add the below configuration
<servlet>
<description>AtmosphereServlet</description>
<servlet-name>AtmosphereServlet</servlet-name>
<servlet-class>org.atmosphere.cpr.AtmosphereServlet</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>*******package name where your handler is**********</param-value>
</init-param>
<init-param>
<param-name>org.atmosphere.cpr.broadcasterCacheClass</param-name>
<param-value>org.atmosphere.cache.UUIDBroadcasterCache</param-value>
</init-param>
<init-param>
<param-name>org.atmosphere.cpr.broadcastFilterClasses</param-name>
<param-value>org.atmosphere.client.TrackMessageSizeFilter
</param-value>
</init-param>
<init-param>
<param-name>WEBSOCKET_PROTOCOL_EXECUTION</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>AtmosphereServlet</servlet-name>
<url-pattern>/pubsub/*</url-pattern>
</servlet-mapping>
step-3
paste the below code in a java file in the package you defined in the above step(also can be found in the git site of atmosphere)
import java.io.IOException;
import org.atmosphere.client.TrackMessageSizeInterceptor;
import org.atmosphere.config.service.AtmosphereHandlerService;
import org.atmosphere.config.service.Singleton;
import org.atmosphere.cpr.AtmosphereResourceEvent;
import org.atmosphere.handler.AtmosphereHandlerAdapter;
import org.atmosphere.interceptor.AtmosphereResourceLifecycleInterceptor;
import org.atmosphere.interceptor.BroadcastOnPostAtmosphereInterceptor;
import org.atmosphere.interceptor.SuspendTrackerInterceptor;
import org.atmosphere.util.SimpleBroadcaster;
#Singleton
#AtmosphereHandlerService(path = "/{chat}",
interceptors = {
AtmosphereResourceLifecycleInterceptor.class,
TrackMessageSizeInterceptor.class,
BroadcastOnPostAtmosphereInterceptor.class,
SuspendTrackerInterceptor.class},
broadcaster = SimpleBroadcaster.class)
public class AtmosphereHandler extends AtmosphereHandlerAdapter {
#Override
public void onStateChange(AtmosphereResourceEvent event) throws IOException {
if (event.isSuspended()) {
String message = event.getMessage() == null ? null : event.getMessage().toString();
if (message != null && message.indexOf("message") != -1) {
event.getResource().write(message.substring("message=".length()));
} else {
event.getResource().write("=error=");
}
}
}
}
Now deploy the ear it works..
Jar files
atmosphere-annotations-2.1.1.jar
atmosphere-jersey-2.1.1.jar
atmosphere-runtime-2.1.1.jar
atmosphere-weblogic-2.1.1.jar
commons-collections-3.2.1.jar
commons-dbutils-1.5.jar
commons-io-2.4.jar
jersey-core-1.17.1.jar
jersey-json-1.17.1.jar
jersey-server-1.17.1.jar
jersey-servlet-1.17.1.jar
log4j-1.2.15.jar