I have a java class which I need to annotate up for a web service. Everything is set up and compiles etc, the wsdl is generated using the maven plugin for wsprovide... the problem I have is that the class references an interface...
#WebService(name = "myWebService", targetNamespace = "......")
#SOAPBinding(style = SOAPBinding.Style.RPC)
public class MyClassImpl implements MyClass {
protected TheService m_theService;
/**
* #return the theService
*/
public TheService getTheService() {
return m_theService;
}
TheService is an interface, and so I get a JAXB error... TheService is an interface, and JAXB can't handle interfaces. The getTheService method does not need to be exposed in the web service, but I can't see how to get around it. Can anyone explain what to do in this situation?
Solved! Found this shortly after posting this message and managed to resolve my issues :-)
https://jaxb.dev.java.net/guide/Mapping_interfaces.html
You can annotate any method that does not require to be exposed with:
#WebMethod(exclude = true)
This way wsgen will ignore the method when generating the JAX-WS artifacts.
Related
I am using JBoss 7.1 and Java 1.6.
I would like to integrate a Guice service with by JAX-WS endpoint. Using the interceptor pattern described by Gunnar.Morling I am able to properly instantiate the Guice modules when using a stateless bean as a webservice. However i am not able to do the same with a simple POJO annotated webservice. Is this possible has anyone found a workaround. Below is a summary of my efforts so far.
#UsesGuice #Interceptor
public class GuiceInterceptor {
#Inject
private GuiceInjectorHolderBean injectorHolder;
#AroundInvoke
public Object aroundAdvice(final InvocationContext ctx) throws Exception {
if (ctx.getTarget().getClass().isAnnotationPresent(UsesGuice.class)) {
final Injector injector = injectorHolder.getInjector();
injector.injectMembers(ctx.getTarget());
}
return ctx.proceed();
}
}
The GuiceInjectorHolderBean is the a sinlgeton bean responsible for triggering the guice wiring. The annotation class required follows
#Retention(RUNTIME)
#Target(TYPE)
#InterceptorBinding
public #interface UsesGuice {}
the JAX-WS POJO class
#UsesGuice
#WebService(serviceName = "EchoServiceService", portName = "EchoServicePort", ame = "EchoServiceImpl", targetNamespace = "lala")
public class EchoServiceImpl implements EchoService
{
#Inject
MyGuiceInjection injection;
#Override
#WebMethod
public String sayHello(final String msg)
{
return "Hello " + injection.call(msg);
}
}
Thanks in advance
Dimitri
Your Current Approach
In your code, javax.interceptor annotations #Interceptor, #InterceptorBinding and #AroundInvoke are supported by CDI and EJB standards and not by Guice. Guice uses proprietary AOP interception via org.aopalliance.intercept.MethodInterceptor interface and calling the method AbstractModule.bindInterceptor.
So you're trying to bootstrap Guice injection on your endpoint by:
using a non-Guice interceptor on the endpoint's method
within the #AroundInvoke method, programmatically invoking the Guice Injector, with injection target being the intercepted endpoint
That begs the Q, what to use for 1?
'Bootrap' Interception Mechanism for Your Current Approach
Obviously, an EJB interceptor works, as you've stated.
Other than an EJB or Guice AOP interceptor... an obvious alternative would be the standard, a CDI interceptor.
But that would make it all rather circular and heavy-weight... Why use CDI just to boostrap, so that you can configure and execute to your desired DI competitor: Guice?
Suggested Alternative Solution - JAX-WS Support for Manual Endpoint Instance Initialisation
If you want POJO web services, maybe consider back-tracking a bit, instead of interceptor-driven Guice initialisation, maybe this could be what you need:
javax.xml.ws.Endpoint.publish(String address, Object implementor)
Endpoint.publish javadoc
Initialise Guice in the standard way, use injector.getInstance() to construct your endpoint instance, and then use Endpoint.publish to set the endpoint instance against the port. The following gives a good example:
Using Guice 3 with JAX-WS in Java 6 outside web container
We have a Play! application where we need to expose a set of REST interfaces to an intranet and a set of REST interfaces we have to expose to the public internet. They share a data layer so we would like to run them together if possible. My assumption is that they will be running on different ports. Being new to Play!, I don't know if this is possible to do within a single Play! instance. I have looked at modules but that didn't seem to fit what we are doing. Has anyone had any experience with this sort of scenario?
Forgot to mention we are using Play! 2.
You could restrict/permit access to resources by checking the ip.
public class IPLocalSecurity extends Controller {
#Before
public static void checkAccess() throws Exception {
if (!request.remoteAddress.matches("192\.168\.1\.*")) {
forbidden();
}
}
}
and use that in the resources controller.
#With(IPLocalSecurity.class)
public class IntranetController extends Controller{
....
}
I've try to expose to the client(gwt) an aspectJ method through gwt-rpc, but the gwt client can't find the method defined in an aspect. The class that i expose implements IsSerializable and only it's method are visible to the client interface...the method added by their aspect contrariwise no. How i can fix this? thanks in advice.
p.s. i post a little example for more clarity:
this is the class...
public class Example implements IsSerializable{
private String name;
public setName(String name){
this.name=name
}
}
and this is the aspect...
privileged aspect Example_x{
public int Example.getVersion() {
return this.version;
}
}
The Example.getVersion() method is unavailable on the client side.
TNX
This won't work, as GWT needs access to the source of any Java class that is exposed to the client side. This is necessary to compile them from Java to Javascript. If you modify your classes using AspectJ, the added methods will not be visible to the GWT compiler and therefore not to the client.
I'd say AspectJ is simply the wrong tool for this task. If you want to add some methods to existing classes you could write a (possibly generic) container class that contains an instance of Example as well as the version information from Example_x.
I'm trying to implement dependency injection in our Zend Framework project.
In previous APS.NET based projects we've used StructureMap and overwritten the DefaultControllerFactory to inject the dependencies into the controllers.
I'm not sure where to do the injection in Zend Framework? I've looked into Zend_Controller_Plugin_Abstract and Zend_Controller_Action_Helper_Abstract but none of them seems to enable me to inject into the currently instantiated controller.
I would love to be able to inject into the constructor of the current controller like i do in ASP.NET, but setters are acceptable (I guess).
Any ideas as to how to accomplish this or something similar?
Ultimately i would like to be able to do something like this:
MyController extends Zend_Controller_Action {
// private vars
[...]
public function __constructor($authenticationService, $userRepository) {
$this->_authServ = $authenticationService;
$this->_userRepo = $userRepository;
}
}
I would like to do something like i do for stuctureMap:
For(authenticationService).Use(WhatEverClass);
or maybe:
$currentController->authServ = $authenticationService;
$currentController->userRepo = $userRepository;
In short: Where can we intercept the creation of (or get the instance of) the current controller?
Similar (unanswered) question here
Thanks!
/Jon
Zend Framework lead developer Matthew Weier O'Phinney has a post that seems to address the idea of injecting resources into controllers:
A Simple Resource Injector for ZF Action Controllers
Check out also PHP-DI, this is a dependency injection library that integrates with Zend Framework. It works with annotations.
It enables you to do things like:
MyController extends Zend_Controller_Action {
/**
* #Inject
* #var MyService
*/
private $myService;
public function helloAction() {
return $this->myService->sayHello();
}
}
I'm kind of new in web development with Java.
I am developing a web service and I've chosen REST / Jersey for it.
I want to init some stuff on startup of the service and to keep them
all along the life of the service.
First question : Is the constructor of the Jersey Servlet a good place to do that ?
Basically, what I want to do is to load a config.ini file located in my WEB-INF directory.
Following this help, I understand I need a ServletContext to load my file as a resource.
However, it is not clear to me how to get this ServletContext in a Jersey Servlet, as it is not really an instance of a servlet, but rather a POJO with some annotations.
I wanted to try this tip, but the attribute "context" is null in the constructor. I think that Jersey might populate it after the constructor. Right ?
So how is the right way to do this ?
Here is my code so far :
/** Main REST servlet */
#Path("/")
public class Servlet {
// ----------------------------------------------------
// Constants
// ----------------------------------------------------
static private final String CONFIG_PATH = "/WEB-INF/config.ini";
// ----------------------------------------------------
// Attributes
// ----------------------------------------------------
/** Context */
#Context ServletContext context;
// ----------------------------------------------------
// Constructor
// ----------------------------------------------------
/** Init the servlet */
public Servlet() {
// Load config.ini from WEB-INF
Config.config = new Config(
this.context.getResourceAsStream(CONFIG_PATH));
// FAIL! this.context is null ...
}
// ----------------------------------------------------
// URI Handlers
// ----------------------------------------------------
/** Welcome page */
#GET
#Path("/")
#Produces(MediaType.TEXT_HTML)
public String welcome() {
return "<h1>Hi there.</h1>";
}
}
Any help would be much appreciated.
Thanks in advance,
Raphael
Using a ContextListener isn't the JAX-RS way to do this-- the ContextListener is the "next layer down," as it were, in the servlet API.
You can put the annotated declaration in the constructor parameters and it will be passed to the constructor:
public Servlet(#Context ServletContext context) {
Using the #Context annotation for a data member initializes that member after the object is constructed, as you discovered.
Another way to do this is to move the initialization of the Config object into some sort of init call, and only initialize it when it's needed, i.e. lazy initialization. Then the ServletContext data member will already have been set by the Jersey framework.
Good Luck!
Kirk
I am not familiar with Jersey, but generally in a Java web application, I think the right thing to do would be to create a ContextListener.
A context listener is a class that implements the interface javax.servlet.ServletContextListener and is configured in your web.xml. It has a method that is executed when the application is first loded into your container, and another one that is executed when the application is stopped, so it is the ideal place to put some one-time initialization stuff, and clean-up things before the application is stopped.
So the steps are :
create your Listener class, implement the contextInitialized(ServletContextEvent sce) method. In this method you receive a ServeltContextEvent that has getServletContext() method that gives you access to the ServletContext.
Configure your Listener in your web.xml
You'll find additional info here : tutorial
Or on Sun's, er, Oracle's site.
By the way, if your file will be in a JAR file I am not sure that the ServletContext method is the best way to load it. I think you're better off with somethinbg like :
this.getClass().getClassLoader().getResourceAsStream("com.company.my.file.properties");