[JAX-RS] Use @Provider to leverage JAX-RS provider auto-discovery feature.

Please see the result in the new blog: http://dev.vvirlan.com/jax-rs-use-provider-to-leverage-jax-rs-provider-auto-discovery-feature/

Advertisements

[JAX-WS] Simple Dispatch Client Example

Here is an example of a Dispatch type Java SE WebService client.
1. A sample Web Service (Running as a Dynamic Web Application in Glassfish):

package com.vvirlan;
import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.xml.ws.soap.Addressing;
/**
 *
 * @author vladimir
 */
@Addressing(enabled = true, required = true)
@WebService(serviceName = "NewWebService")
public class NewWebService {

    @WebMethod(operationName = "hello")
    public String hello(@WebParam(name = "name") String txt) {
        return "Hello " + txt + " !";
    }
}

2. Here is the client (A simple Java SE application). Make sure to start the previous application first:

package dispatchclient;

import javax.xml.namespace.QName;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPBodyElement;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.Dispatch;
import javax.xml.ws.Service;
import javax.xml.ws.soap.AddressingFeature;
import javax.xml.ws.soap.SOAPBinding;

/**
 *
 * @author vladimir
 */
public class DispatchClient {

    public static void main(String[] args) {

        QName port = new QName("http://vvirlan.com/", "PortName");
        Service service = Service.create(port);
        service.addPort(port, SOAPBinding.SOAP11HTTP_MTOM_BINDING, "http://localhost:8080/SimpleJaxWs/NewWebService");
        Dispatch<SOAPMessage> dispatch = service.createDispatch(port, SOAPMessage.class, Service.Mode.MESSAGE, new AddressingFeature());
        SOAPBinding binding = (SOAPBinding) dispatch.getBinding();
        
        binding.setMTOMEnabled(true);
        SOAPMessage request = null;
        try {
            request = MessageFactory.newInstance().createMessage();
            SOAPBody reqSoapBody = request.getSOAPBody();
            SOAPElement methodName;
            QName method = new QName("http://vvirlan.com/", "hello", "vvir");
            QName name = new QName("name");

            methodName = reqSoapBody.addChildElement(method);
            SOAPElement nameParam = methodName.addChildElement(name);
            nameParam.addTextNode("Vladimir");

        } catch (SOAPException e) {
            e.printStackTrace();
        }

        SOAPMessage response = dispatch.invoke(request);
        try {
            SOAPBody resSoapBody = response.getSOAPBody();
            System.out.println(resSoapBody.getTextContent());
        } catch (SOAPException e) {
            e.printStackTrace();
        }

    }
}

This will generate a SOAP request like:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:vvir="http://vvirlan.com/">
    <soapenv:Header/>
    <soapenv:Body>
        <vvir:hello>
            <name>Vladimir</name>
        </vvir:hello>
    </soapenv:Body>
</soapenv:Envelope>

And the response will be

<?xml version='1.0' encoding='UTF-8'?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Body>
        <ns2:helloResponse xmlns:ns2="http://vvirlan.com/">
            <return>Hello Vladimir !</return>
        </ns2:helloResponse>
    </S:Body>
</S:Envelope>

Low Level SOAP manipulation and JAX-WS invokation (SAAJ)

1. The Client Code

package com.vvirlan;

import java.io.IOException;
import java.net.URL;

import javax.xml.namespace.QName;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPBodyElement;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
public class MessageFactoryExample {
	public static void main(String[] args) throws SOAPException, IOException {
		MessageFactoryExample ex = new MessageFactoryExample();
		ex.run();
	}
	private void run() throws SOAPException, IOException {
		MessageFactory factroy = MessageFactory.newInstance();
		SOAPMessage message = factroy.createMessage();
		SOAPPart soapPart = message.getSOAPPart();
		SOAPEnvelope envelope = soapPart.getEnvelope();
		SOAPHeader header = envelope.getHeader();
		SOAPBody body = envelope.getBody();
		//header.detachNode();
		QName bodyName = new QName("http://vvirlan.com/", "sayHello", "PRE");
		SOAPBodyElement bodyElement = body.addBodyElement(bodyName);
		QName name = new QName("arg0");
		SOAPElement arg0 = bodyElement.addChildElement(name);
		arg0.addTextNode("Vlad");
		message.writeTo(System.out);
		System.out.println();
		SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
		SOAPConnection soapConnection = soapConnectionFactory.createConnection();
		URL endpoint = new URL("http://localhost:8080/JaxWsServiceExample/MyCalculatorService");
		SOAPMessage response = soapConnection.call(message, endpoint);
		response.writeTo(System.out);
soapConnection.close();
	}
}

2. The server (a very simple Dynamic Web App in eclipse running on Glassfish):

package com.vvirlan;
import javax.jws.WebMethod;
import javax.jws.WebService;
@WebService
public class MyCalculator {
	@WebMethod
	public String sayHello(String msg) {
		return "Hi" + msg;
	}
}

3. Invokation results:
3.1. Request

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
	<SOAP-ENV:Header />
	<SOAP-ENV:Body>
		<PRE:sayHello xmlns:PRE="http://vvirlan.com/">
			<arg0>Vlad</arg0>
		</PRE:sayHello>
	</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

3.2. Response

<?xml version='1.0' encoding='UTF-8'?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
	<S:Body>
		<ns2:sayHelloResponse xmlns:ns2="http://vvirlan.com/">
			<return>HiVlad</return>
		</ns2:sayHelloResponse>
	</S:Body>
</S:Envelope>

[JAX-RS] Simple Server and Client using Jersey 1.19 Client API (JSON)

Using Jersey 1.19. in general 1.xx vs 2.xx – the package names differ and some of the Client API methods and ways to get the Client.
Note that the server here is a Dynamic Java Application running on Glassfish 4 so the dependencies are added automatically while the client is a maven project.

1. The server Application:

package com.vvirlan;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
@ApplicationPath("rest")
public class RestApplication extends Application {
	@Override
	public Set<Class<?>> getClasses() {
		Set<Class<?>> classes = new HashSet<>();
		classes.add(ResourceOne.class);
		return classes;
	}
}

2. Server Resource:

package com.vvirlan;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
@Path("one")
public class ResourceOne {
	@POST
	@Path("hello")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public MyBean sayJsonHello(@FormParam("x") String x, @FormParam("y") String y) {
		System.out.println("X is " +x+" Y is "+y);
		MyBean bean = new MyBean();
		bean.setName("Bob How "+x);
		bean.setAge(120);
		return bean;
	}
}

3. The bean:

package com.vvirlan;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class MyBean {
	private String name;
	private Integer age;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
}

4. Client (a simple Maven project):

package com.vvirlan;
import javax.ws.rs.core.MediaType;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.representation.Form;
public class JaxRsClientApi {
	public static void main(String[] args) {
		JaxRsClientApi client = new JaxRsClientApi();
		client.run();
	}
	public void run() {
		Client client = Client.create();
		WebResource resource = client.resource("http://localhost:8080/JaxRsSimpleServer/rest/one/hello");
		Form form = new Form();
		form.add("x", "XFOO");
		form.add("y", "YBAR");
		MyBean bean = resource
				.type(MediaType.APPLICATION_FORM_URLENCODED_TYPE)
				.accept(MediaType.APPLICATION_JSON_TYPE)
				.post(MyBean.class, form);
		System.out.println(bean);
	}
}

5. The bean on the client side (ideally need to share it somehow)

package com.vvirlan;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class MyBean {
	private String name;
	private Integer age;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return "MyBean [name=" + name + ", age=" + age + "]";
	}
}

6. Client 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>com.vvirlan</groupId>
	<artifactId>jaxrsclientapi</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<properties>
		<jersey.version>1.19</jersey.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>com.sun.jersey</groupId>
			<artifactId>jersey-client</artifactId>
			<version>${jersey.version}</version>
		</dependency>

		<dependency>
			<groupId>com.sun.jersey</groupId>
			<artifactId>jersey-json</artifactId>
			<version>${jersey.version}</version>
		</dependency>
	</dependencies>
</project>

[JAX-RS] Implementing custom MessageBodyWriter for serialization

Say you want to serialize your object in a custom format. For XML you can use JAXB, for JSON you can use Jackson. But in case you have your own specific format, you need to implement your own MessageBodyWriter.

1. Maven web application – pom.xml (here jersey 1.19, feel free to upgrade):

<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.vvirlan</groupId>
	<artifactId>streamingoutput</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<name>streamingoutput Maven Webapp</name>
	<url>http://maven.apache.org</url>
	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>3.8.1</version>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>com.sun.jersey</groupId>
			<artifactId>jersey-server</artifactId>
			<version>1.19</version>
		</dependency>
		<dependency>
			<groupId>com.sun.jersey</groupId>
			<artifactId>jersey-grizzly2</artifactId>
			<version>1.19</version>
		</dependency>

	</dependencies>
	<build>
		<finalName>streamingoutput</finalName>
	</build>
</project>

2. Application class. Note that besides the actual resource class, you need to also add your custom writer.

package com.vvirlan;

import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.ApplicationPath;
import com.vvirlan.resources.CustomerResource;
import com.vvirlan.resources.MyCustomWriter;

@ApplicationPath("rest")
public class Application extends javax.ws.rs.core.Application{
	@Override
	public Set<Class<?>> getClasses() {
		Set<Class<?>> classes = new HashSet<Class<?>>();
		classes.add(CustomerResource.class);
		classes.add(MyCustomWriter.class);
		return classes;
	}
}

3. The resource class (CustomerResource):

package com.vvirlan.resources;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("customers")
@Produces(MediaType.TEXT_PLAIN)
public class CustomerResource {
	@GET
	@Path("c")
	@Pretty
	public Customer getCustomer() {
		return new Customer("A",2,2);
	}
}

4. The Customer object:

package com.vvirlan.resources;

//My custom annotation (makes it eligible for my serialization)
@MyContent
public class Customer {

	private String name;
	private int age;
	private int size;

//Mandatory
	public Customer() {

	}

	public Customer(String name, int age, int size) {
		this.name = name;
		this.age = age;
		this.size = size;
	}

	// Getters and setters
}

5. My MyContent annotation

package com.vvirlan.resources;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyContent {

}

6. The actual custom body writer:

package com.vvirlan.resources;

import java.io.IOException;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Provider;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlRootElement;

@Provider
@Produces(MediaType.TEXT_PLAIN)
public class MyCustomWriter implements MessageBodyWriter<Customer> {

	public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
		boolean present = type.isAnnotationPresent(MyContent.class);
		return present;
	}

	public long getSize(Customer t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
		// Leave it to Jersey to put content-length
		return -1;
	}

	public void writeTo(Customer t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType,
			MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream)
					throws IOException, WebApplicationException {

		// Here reflection may be used to get the custom serialization
		StringBuilder sb = new StringBuilder();
		sb.append("Name: " + t.getName() + " Age: " + t.getAge() + " Size: " + t.getSize());

		entityStream.write(sb.toString().getBytes());

	}
}

7. Accessing the application at:
http://localhost:8080/yourprojectname/rest/customers/c/

And you will see:
Name: A Age: 2 Size: 2

[JAX-RS] ExceptionMapper example (Maven + Jersey + Glassfish)

Create a new Maven project (Web app archetype) in eclipse and add the dependencies on jersey. Also you will need Glassfish server.
1. 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.vvirlan</groupId>
	<artifactId>rsexampleresponse</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<name>rsexampleresponse Maven Webapp</name>
	<url>http://maven.apache.org</url>
	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>3.8.1</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>com.sun.jersey</groupId>
			<artifactId>jersey-server</artifactId>
			<version>1.19</version>
		</dependency>
		<dependency>
			<groupId>com.sun.jersey</groupId>
			<artifactId>jersey-grizzly2</artifactId>
			<version>1.19</version>
		</dependency>
	</dependencies>
	<build>
		<finalName>rsexampleresponse</finalName>
	</build>
</project>

2. Main Application

package com.vvirlan;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import com.vvirlan.exception.IllegalArgumentExceptionMapper;
import com.vvirlan.resources.ExceptionResource;
import com.vvirlan.resources.HelloResource;

@ApplicationPath("rest")
public class ApplicationMain extends Application {

	@Override
	public Set<Class<?>> getClasses() {
		Set<Class<?>> classes = new HashSet<Class<?>>();
		classes.add(ExceptionResource.class);
//Note that you need to add the exception mapper here, otherwise, it won't work
		classes.add(IllegalArgumentExceptionMapper.class);
		return classes;
	}
}

3. An example service

package com.vvirlan.resources;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;

@Path("e")
public class ExceptionResource {
//This is the default implementation	
	@GET
	@Path("nf")
	public Response getException () {
		throw new WebApplicationException(Response.Status.CONFLICT);
	}
	
//Throw the IllegalArgument and it will get mapped automatically to whatever you define in the mapper (next class)
	@GET
	@Path("il")
	public Response getIllegal() {
		throw new IllegalArgumentException();
	}
}

4. The Exception Mapping class. Here we’re mapping the IllegalArgumentException to a BAD_REQUEST

package com.vvirlan.exception;

import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;

@Provider
public class IllegalArgumentExceptionMapper implements ExceptionMapper<IllegalArgumentException> {

	public Response toResponse(IllegalArgumentException arg0) {
		return Response.status(Status.BAD_REQUEST).build();
	}

}

[JAX-WS] Basic Authnetication example (Glassfish) and the client

This example will demonstrate how to configure and use Container provided BASIC authentication for a JAX-WS web service. To note that this is the real 🙂 BASIC authentication.

There are 3 parts:

I. Configure Glassfish realms
II. Implement the actual web service class and configure the deployment descriptor
III. Test authentication from SoapUI
IV. Java Client

I. Configure Glassfish realms
In order to define the realms in Glassfish, it is necessary to do 2 things:
I.1. Enable Default Principal To Role Mapping
Go to the glassfish console: localhost:4848 And open:
Configurations->Server Config -> Security and set enabled for Default Principal To Role Mapping as shown in the picture

1

I.2. Define the file based realm user
Go to Security -> Realms -> file and click on Manage Users as shown in the picture
2

Then define your user name and password. And most importantly type into Group List the value USER. See picture

3

Now you have your user acv with password acv and who is in the Group USER.

II. Implement the actual web service class and configure the deployment descriptor
II.1. Create a new Dynamic web project in Eclipse and set Glassfish as the target runtime. Don’t forget to select create web.xml on the last step of the wizard

II.2. Create a new java class inside a package. Note the user of the @RolesAllowed annotation which should have the value of USER, the very one that you have just defined in the server configuration:

package com.vvirlan;
import javax.annotation.security.RolesAllowed;
import javax.jws.WebMethod;
import javax.jws.WebService;
@WebService
public class Main {
	@WebMethod
	@RolesAllowed("USER")
	public String sayHello() {
		return "Hello";
	}
	@WebMethod
	@RolesAllowed("USER")
	public String sayNothing() {
		return "";
	}
}

II.3 Edit web.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://xmlns.jcp.org/xml/ns/javaee"
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
	id="WebApp_ID" version="3.1">
	<display-name>JaxWsBasicSecurity</display-name>
	<servlet>
		<servlet-name>Main</servlet-name>
		<servlet-class>com.vvirlan.Main</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>Main</servlet-name>
		<url-pattern>/user</url-pattern>
	</servlet-mapping>
	<security-constraint>
		<web-resource-collection>
			<web-resource-name>WRCollection</web-resource-name>
			<url-pattern>/user</url-pattern>
			<http-method>GET</http-method>
			<http-method>POST</http-method>
		</web-resource-collection>
		<auth-constraint>
			<role-name>USER</role-name>
		</auth-constraint>
		<user-data-constraint>
			<transport-guarantee>NONE</transport-guarantee>
		</user-data-constraint>
	</security-constraint>
	<login-config>
		<auth-method>BASIC</auth-method>
	</login-config>
	<security-role>
		<role-name>USER</role-name>
	</security-role>
</web-app>

So what we do here. First we define a servlet and point it to our class: Main. Next we map this servlet called Main to a url pattern. From now on our web service will be available not at the usual MainService, but at the url /user. Now we define the security constraint and instruct the container to require authentication for GET and POST request for the path /user. Next we define the role name USER again and set auth-method to BASIC. Finally we again use the name USER to declare the security role.

III. Run the application and ideally you should be able to open it in the browser and see a BASIC authentication form requiring username and password. Type acv and acv and you should see the endpoint. Somewhere here:
http://localhost:8080/JaxWsBasicSecurity/user

To test in SoapUI:
III.1 Create a new SOAP project
III.2 Paste in the WSDL URL: http://localhost:8080/JaxWsBasicSecurity/user?wsdl
III.3 You will be required to type username and password put twice acv and acv (in 2 forms)
III.4 Now trying to run a request you need to define Auth as in the picture
4
Clicking on play should give you the response.

IV. Java Client
IV.1. The first step is of course wsimport. But you have authentication enabled so you need to do this: Create a file called myXauthFile.txt in tmp folder (anywhere you like). Set the content to:

http://acv:acv@localhost:8080/JaxWsBasicSecurity/user?wsdl

IV.2 Run wsimport from the tmp folder:

C:\tmp\wsbasic>wsimport -keep -Xauthfile myXauthFile.txt http://localhost:8080/JaxWsBasicSecurity/user?wsdl

You should get the client artifacts.
IV.2 Copy your newly generated artifacts into eclipse in your client project
IV.3 Implement the Client class:

package com.vvirlan;
import java.net.Authenticator;
import java.net.PasswordAuthentication;
public class TheClient {
	public static void main(String[] args) {
		TheClient cl = new TheClient();
		cl.run();
	}
	public void run() {
		Authenticator myAuth = new Authenticator() {
			@Override
			protected PasswordAuthentication getPasswordAuthentication() {
				return new PasswordAuthentication("acv", "acv".toCharArray());
			}
		};
		Authenticator.setDefault(myAuth);
		MainService service = new MainService();
		Main port = service.getMainPort();
		// This would work, but you will get a 401 error on MainService service
		// = new MainService();
		// BindingProvider bp = (BindingProvider) port;
		// bp.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "acv");
		// bp.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "acv");
		String result = port.sayHello();
		System.out.println(result);
	}
}

Troubleshooting.
In case you get 403, try setting the server realms for both default-config and server-config. Also try to set the password again in glassfish. After this you need to restart the server and redeploy the app.

[JAX-RS] Using CDI for dependency injection in JAX-RS

1. The resource class

package com.example.jaxrs;

import javax.annotation.PostConstruct;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
@Path("cdiexample")
@RequestScoped
public class StringResource {
	@Inject
	private MyService service;
	public StringResource() {
	}
	@Context
	private HttpHeaders httpHeaders;
	@PostConstruct
	private void postCons() {
	}
	@Produces(MediaType.TEXT_PLAIN)
	@GET
	public String get() {
		return service.getMessage();
	}
}

2. MyService interface

package com.example.jaxrs;
public interface MyService {
	public String getMessage();
}

3. MyServiceImpl

package com.example.jaxrs;
public class MyServiceImpl implements MyService{
	@Override
	public String getMessage() {
		return "THIS IS THE MESSAGE";
	}
}

4. web.xml (under /WEB-INF/)

<?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>javax.ws.rs.core.Application</servlet-name>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>javax.ws.rs.core.Application</servlet-name>
		<url-pattern>/rest/*</url-pattern>
	</servlet-mapping>
</web-app>

5. beans.xml (under /WEB-INF/)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/
XMLSchema-instance" xsi:schemeLocation="http://java.sun.com/xml/ns/javaee http://
java.sun.com/xml/ns/javaee/beans_1_0.xsd">
<!-- This is empty on purpose. -->
</beans>

6. Deploy on glassfish! and access it: http://localhost:8080/TestCDI/rest/cdiexample (given that the project name is TestCDI).