Config RestEasy service using Spring - java

I have recently wrote a very simple Restful service deployed to JBoss AS 7.
I have a JAX-RS interface defiled as (using scala):
#Provider
#Path("/customers")
trait ICustomerService {
#GET
#Path("/{id}")
#Produces(Array("application/xml"))
def getCustomer(#PathParam("id") id: Int): StreamingOutput
}
And a class implements it (using scala):
class ServiceFacade extends ICustomerService {
val ctx = new ClassPathXmlApplicationContext("orderservice.xml")
val customerService = ctx.getBean("customerService").asInstanceOf[CustomerService]
def getCustomer(id: Int): StreamingOutput = {
customerService.getCustomer(id)
}
}
Here the problem comes. Everytime I issue a request from a client browser, a new ServiceFacade is created by Jboss, thus the Spring xml file is parsed once.
Is there anyway I can create the ServiceFacade myself in a spring config and simply let JBoss uses it rather than create for every single clieng request?
Many thanks.

You are creating a new Spring context on every instance creation of your ServiceFacade, Try either injecting the context or creating a singleton. I don't believe JAX-RS or RestEasy gurantees only a single instance of a annotated class is created.
Also, I am just getting up to speed on Scala myself, but should you not place the annotations on the implementation and not the trait?

Related

Spring boot - rest client from rest controller interface

With spring boot 2.6.0 (or above) is it possible to generate a rest client from a a controller interface?
Im wondering if its possible to build spring application like this following use case.
Spring application A needs to call spring application B rest interface
Spring application B is a multimodule project that produces server jar, and a api jar
Spring application A imports the B's API jar
Spring application A uses controller interface from B Api jar to make a rest client based on spring annotations.
B Api jar:
#RestsController
public interface MyApplicationAPI {
#GetMapping("/api/some-endpoint)
public SomeDto someEndpoint(SomeDTO obj);
}
B server jar:
public class BApplicationAPIImpl implements MyApplicationAPI {
public SomeDto someEndpoint(SomeDTO obj) {
return xxx;
And finally within A application:
MyApplicationAPI restClient = Some.magic(MyApplicationAPI.class, "http://bappurl.com")
SomeDto response = restClient.someEndpoint(param);
I believe that framework RestEasy supports similar approach, but you have to rely on JAXRS annotations.
Is there anything like that for spring framework? Or even better is there anything like this within spring already - i would prefer to rely on spring inhouse libraries and tools, rather than importing entire resteasy and jaxrs.
Spring Framework 6 (and Spring Boot 3) will have declarative HTTP interfaces (see documentation). However, they won't use the same annotations as controllers, but separate ones. So your example where you use the same interface for both controller and client won't be possible.
Code snippet from the documentation:
interface RepositoryService {
#GetExchange("/repos/{owner}/{repo}")
Repository getRepository(#PathVariable String owner, #PathVariable String repo);
// more HTTP exchange methods...
}
Initialization (the Some.magic() part in your question) can be done with WebClient. As can be seen in the same documentation:
WebClient client = WebClient.builder().baseUrl("https://api.github.com/").build();
HttpServiceProxyFactory factory = WebClientAdapter.createHttpServiceProxyFactory(client);
factory.afterPropertiesSet();
RepositoryService service = factory.createClient(RepositoryService.class);

Spring - Automatically Mapping DTO to Entity For SOAP Services

I have read an article about mapping an DTO class to an entity. In the article, it manages to create a very general and extensible way of mapping DTO using annotations and RequestResponseBodyMethodProcessor. I have been creating a SOAP service using Spring Boot + Apache CXF. The service is still in an early stage, but it will get really big in the following months. The DTO pattern in the article seems to be a good choice for separating what the client sends and what is stored in the database. I have tried multiple ways of implementing it in the project, but none worked properly. I know RequestResponseBodyMethodProcessor is only used for #RequestBody and #ResponseBody, so I tried putting it in the SOAP Service, but Spring seems to ignore it completely. I have also done some search and maybe the problem comes from the fact CXF uses JAXB and Spring uses Jackson. If this is the case, is there any way to integrate CXF to use Jackson? If the problem isn't JAXB and Jackson, is there any other way of implementing the above pattern for a SOAP service? Just for completeness, the project is Java 1.8, the SOAP service is created using #WebService and the service is published through an WebServiceConfiguration class. Example code of how the code looks like:
#WebService
#Service
public interface MyService {
#WebMethod
public void myEndpoint(#WebParam(name = "someClass") SomeClass someClass);
// others endpoints
}
#Configuration
public interface WebServiceConfiguration {
#AutoWired
private MyServiceImpl myServiceImpl;
#Bean
public ServletRegistrationBean<CXFServlet> servletRegistrationBean(ApplicationContext context) {
return new ServletRegistrationBean<>(new CXFServlet(), "/service/*");
}
#Bean(name = Bus.DEFAULT_BUS_ID)
public SpringBus bus() {
return new SpringBus();
}
#Bean
public Endpoint myService() {
Edpoint endpoint = new EndpointImpl(bus(), myServiceImpl);
endpoint.publish("/myService");
return endpoint;
}
}

Dynamically configuring remote web service endpoint in Spring

I want to call a remote SOAP/CXF web service from a Spring app. The complication is I cannot pre-configure invocation params (remote endpoint URL) at app startup via XML or Java config. Instead I need to obtain them dynamically from an external configuration, taking a fresh value each invocation. (Actually the config is backed by LDAP and accessbible via a custom Java library.)
¿Does Spring 4 offers a common way to achieve that?
For now, I came with the following custom solution, but I don't like it much beacause I need to define a dummy proxy class DynamicallyConfiguredMyService at least.
#Component
class ParentBean {
#Inject
MyService service;
...
service.doAction(); // calling WS
}
interface MyService {
void doAction();
}
#Component
class DynamicallyConfiguredMyService implements MyService {
void doAction() {
getRealService.doAction();
}
private MyService getRealService() {
String url = get URL from external config
MyService endpoint = new MyServiceHelper().getMyService();
Map<String, Object> ctx = ((BindingProvider) endpoint).getRequestContext();
ctx.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, url);
return endpoint;
}
}
Spring 4, Java 7, JBoss EAP 6.4.x

How to create RESTful service with customizable notification in spring boot

I'm new to spring, but not new to java.
I'd like to create base class for all REST services that would send notification through some messaging protocol on requests with chosen methods (POST, PUT, PACTCH) (when resource is changed basically)
So for example If I would create interface
public interface RestService<T, I> {
T get(I id);
T create();
T patch(I id);
T put(I id);
}
How can I use that in spring RestController and somehow decorate it with notifications?
All this spring #Autowire and configuration files is somewhat confusing to me, because while I'm familiar with dependency injection and used constructor dependency injection I haven't used IOC much.
I believe that the best option for you will be to use Spring AOP and put some annotation to the required methods. Please check this:
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html
You can use any interface or base class for any restcontroller or for any other Spring stereotype. The annotations are just clues for Spring itself to use the class as an endpoint for a rest service for example. Your class otherwise can be anything, like:
#RestController
class MyController {
#Autowired
private MyService myService; //If you use the spring sterotypes you dont need to do anything to use a bean but just to use the autowired annotation
}
#RestController
class AnyotherController extends AbstractController {...}
#RestController
class YetAnotherController extends AbstractController implements Something {}
Are all valid resources (i.e. web-components) for Spring to use.

How to design beans in spring framework

I am new to Spring framework. Maybe this is more of a Java EE bean design question than related to Spring framework. Anyway, I just shoot it and see how clear I can make myself.
So I have a service. The service takes a connection string as constructor parameter. Then you can use the service to upload files to the location indicated by the connection string.
So you will start with something like:
public class MyService{
public MyService(String connectionStr){ ... }
}
When you need such a service, you call:
MyService service = new MyService("xxx");
...
That's what I used to do. Nothing fancy. Now if I do it in Java under Spring, I somehow want the service to be a bean. I need to do this:
#Component
public class MyService{
#Autowired
public MyService(#Value(...some connection string...) String connectionStr) {...}
}
But I get confused how you can inject dependency in compile time? I never know what connection string I will pass to create the service. When I read Spring tutorials, most of them have parameters coded in XML config file. Can I design a Spring bean like the one above but require the parameters to be passed in runtime?
Thanks.
You can design a method like this:
void upload(String location,XXX other parameters);
I didnt really get your question but will try to answer.
Check here or google to check if you really want to go for spring.
Coming to your query, For your service you would have to define some thing like this in your spring context.
<bean id="myService" class="com.blah.MyService">
<constructor-arg>
<value>http://HOST/test/</value>
</constructor-arg>
</bean>
Your service class will be,
public class MyService{
public MyService(String connectionString) {...}
}
This is how you will call your service in your application
ApplicationContext context = new ClassPathXmlApplicationContext(
new String[] { "context.xml" });
MyService service = (MyService) context
.getBean("myService");
The above can be implemented using annotations also. Check here for more details

Categories

Resources