How to configure REST service method with NULL RequestDTO in ServiceStack - web-services

I am trying ServiceStack to develop few web services, but I am unable to configure method having null as input.
public class UserService : IService
{
public object Get()
{
//gets all users
//not working
}
public object Get(FindUser request)
{
//this works
}
}
public override void Configure(Container container)
{
Routes
.Add<FindUser>("/user/{id}") //this works
.Add(null, "/user");//how to configure this route
}

There is no concept of a null input, a client must call a specific Service and each Service in ServiceStack needs a request DTO which defines the service entry point and the Request that it receives - that Request DTO can be empty.

Related

JAX-RS Same #Path Identifier in two Services

I am having the below scenario while implementing JAX-RS web service.
Service A:
#Path("/customer/{customerId}")
public interface ICustomerDataUsageService{
#GET
#Path("/datausage")
public Response getCustomerDataUsage();
//other methods...
}
Service B:
#Path("/")
public interface IHelpDeskService{
#GET
#Path("/customer/{customerId}")
public Response getCustomer();
//other methods...
}
After deployment only the Service A is working (Its registered after the Service B). For the second one I am getting HTTP 404 error.
Unfortunately we cannot change the interfaces since its provided by another entity. We are only having control of the implementation classes for these.
I am using Jersey-2.22.
Is there any way out to have both these services working without changing the interfaces.
Thanks in Advance!
This was indeed a bug and was fixed by the API team by correcting the API.
The fix looks as below:
Service A:
#Path("/customer")
public interface ICustomerDataUsageService{
#GET
#Path("/{customerId}/datausage")
public Response getCustomerDataUsage();
//other methods also got /{customerId} added in path
}
Service B:
#Path("/")
public interface IHelpDeskService{
#GET
#Path("/customer/{customerId}")
public Response getCustomer();
//other methods...
}

Secure Restful Spring boot application

I have developed a RESTful web service using Spring Boot. Once a URL is entered, a JSON resource is returned. The server side is not perfectly JSON API conformed but it works.
Now I want to secure the RESTful service with simple HTTP basic authentication. Simply put, if a client send a HTTP GET in order to access
http://mycompany.com/restful/xyz
it will receive a HTTP unauthenticated error, unless the request is configured with proper Authorization basic XXXXXXXX. The xxxxxx is the encrypted form of user:pwd
I wanted to do it with Spring Security. After some googling I might need to create some class like:
#Configuration
#EnableGlobalMethodSecurity(prePostEnabled = true)
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
....
}
#Override
protected void configure(HttpSecurity http) throws Exception {
....
}
}
There are two things I need to understand:
Most Spring Security sample I found were somehow related to web application using Spring MVC, but I am sure that it can be used in a scenario as shown above - a standalone web service (in a Tomcat all right, but not a web app);
Can anyone show some code snippet in the two methods above that work to the effect that only certain user/pwd is allowed to pass the filter to the resource,
http://mycompany.com/restful/xyz
otherwise a HTTP authentication error code is returned.
Can anyone help?
You can have something like this:
#Configuration
#EnableGlobalMethodSecurity(prePostEnabled = true)
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/restful/**").hasRole("ROLE_USER").and().httpBasic();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("john").password("mypass").roles("ROLE_USER");
}
}

Setting MTOM-enabled property dynamically in Apache CXF

I'm developing SOAP web service using Apache CXF framework. My web-method returns either binary data or plain XML depending on request parameters. Most of requests return binary data, so I configured CXF to use MTOM in service responses.
But this is not always useful: when XML is returned, caller side expects to get plain text/xml document rather than multipart one. So I'd like my web service to dynamically change its binding.
CXF documentation has following example:
Endpoint ep = ...; // example does not explain how to get it
SOAPBinding binding = (SOAPBinding)ep.getBinding();
binding.setMTOMEnabled(true); // or false
Question: how can I get Endpoint instance?
I'm using Spring annotation #Endpoint for web-service and #PayloadRoot for web-method.
You can use the following code if you are using on server,
you need to add import javax.xml.ws.Endpoint;
HelloWorldImpl implementor = new HelloWorldImpl();
String address = "http://localhost:9000/helloWorld";
Endpoint.publish(address, implementor);
From client side
TestMtomService tms = new TestMtomService(wsdlURL, SERVICE_NAME);
TestMtomPortType port = (TestMtomPortType)tms.getPort(PORT_NAME,TestMtomPortType.class);
Binding binding = ((BindingProvider)port).getBinding();
((SOAPBinding)binding).setMTOMEnabled(true);
Refer
If you are downloaded the cxf bundle, code samples for MTOM Server/Client available on following path
apache-cxf-2.7.2\samples\mtom
I created my own marshalled class extended from org.springframework.oxm.jaxb.Jaxb2Marshaller. Only single method is overriden:
public class Marshaller extends Jaxb2Marshaller {
#Override
public void marshal(Object graph, Result result, MimeContainer mimeContainer) throws XmlMappingException {
if ( disableMtom() ) {
super.marshal(graph, result, null);
} else {
super.marshal(graph, result, mimeContainer);
}
}
private boolean disableMtom() {
return ... // depends on response context
}
}
The disableMtom detects if MTOM is disabled from response context. Web service endpoint takes care to pass this context to marshaller somehow.
By default MTOM is enabled.

Create Web Service from struts2 Web Application

First, I'm new to Web Services. I have a didactical task at university about developing web application and web service for something like managing distribuited drug stores.
I've developed a working Web Application using struts2 framework, but now I'd like to extend it to a Web Service. I found that I could implement a class (named for example WSManager) which is a wrapper of the various Web App Controllers.
It would have to make calls to static methods of those Controllers. Web Application is designed to provide a Controller for each use case.
for example a Controller is like this:
public class AdminLocaleController extends AbstractController {
private static final long serialVersionUID = -6266455088438602574L;
private static Logger logger = Logger.getLogger(AdminLocaleController.class);
private List<Prodotto> prodotti;
#Override
public String execute() {
prodotti = initializeAdminLocaleView();
return "success";
}
public List<Prodotto> getProdotti() {
return prodotti;
}
public void setProdotti(List<Prodotto> prodotti) {
this.prodotti = prodotti;
}
public static List<Prodotto> initializeAdminLocaleView() {
logger.info("Recupero lista di prodotti da ordinare");
DBController dbController = new DBControllerImpl();
return dbController.getProdottiDaOrdinare();
}
}
and the WSManager class makes a call to the initializeAdminLocaleView(), just like this:
/* AdminLocaleController */
public List<Prodotto> initializeAdminLocaleView(){
return AdminLocaleController.initializeAdminLocaleView();
}
I would create a Web Service in Eclipse providing that service class.
If I'm doing something wrong I ask you the proper way to extend the web application to a web service.
Otherwise, my matter is if I have to (and how to) manage parameters and attributes between Views (jsp) and Controllers.
Finally I have some Controllers (each of these implement SessionAware) which process data and store returned object in Session (for example a LoginController which saves a User bean in request session). Deeper, my question is how I should manage Web App's session stored attributes in case of a Web Service. If I have method calls in WSManager which passes a User bean as parameters, how could I obtain it from a session. Or simply, do I have necessity of obtaining something from a session from a Web Service perspective?
I'm sure I've written a confusionary question, but confusionary is my state of mind at this point too.

Unable to deploy ejb-based WSDL web-service in Glassfish 3

I'm trying to deploy a weeb-service, generated from an EJB into glassfish, but, for some reason, my web service is never visible in Glassfish. The web-service is defined from an EJB interface as follows :
#Remote
#WebService
public interface TemplateEJBRemote {
public abstract #WebResult(name="found") Template find(#WebParam(name="templateId", mode=Mode.IN) Long id);
}
This EJB interface has a Local implementation :
#Local
#Stateless
public class TemplateEJBImpl implements TemplateEJBRemote {
#PersistenceContext(unitName=NamingConstants.PERSISTENCE_CONTEXT)
private EntityManager entityManager;
#Override
public Template find(Long id) {
return entityManager.find(Template.class, id);
}
}
And they're both defined in a war module, which an ear module sends to Glassfish.
Those module produce correctly looking artefacts, including an ear with the correct application.xml :
<application xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_6.xsd"
version="6">
<description>This is the project that will deliver a full usable
EAR including all delivered components. All the project
dependencies here will be included in this</description>
<display-name>my-ear</display-name>
<module>
<web>
<web-uri>my-war-0.0.1-SNAPSHOT.war</web-uri>
<context-root>/my-war</context-root>
</web>
</module>
</application>
When deployed in Glassfish, all infos I can get is
E:\java-ext\glassfish3>bin\asadmin list-components --subcomponents
my-ear-0.0.1-SNAPSHOT <ear, ejb, webservices, web>
my-war-0.0.1-SNAPSHOT.war <WebModule>
Command list-components executed successfully.
it seems to me that, were my web-service really deployed, it would appear below my war submodule, no ?
If not, what can I do to ensure my web-service is correctly defined and deployed ?
[UPDATE 1] In order to give some more informations, i created a smaller web-service endpoint, the infamous Hello world, coded as such :
#WebService
public class Hello {
public String hello(String world) {
return "Salut, "+world+" !";
}
}
using this definition, it is a perfect Glassfiosh web-service :
But, as soon as I make it a bean, as such :
#WebService
#Stateless
public class Hello {
public String hello(String world) {
return "Salut, "+world+" !";
}
}
Things become a little different :
However, as log files told me, HelloService is still present :
[#|2011-03-31T17:55:55.059+0200|INFO|glassfish3.1|javax.enterprise.webservices.org.glassfish.webservices|_ThreadID=339;_ThreadName=Thread-1;|WS00019: EJB Endpoint deployed
autocat-ear-0.0.1-SNAPSHOT listening at address at http://perigee-567125f:8080/HelloService/Hello|#]
I tried to apply the same logic to my initial bean, but with an infortunate result (a 404 error, of course). So I guess there is another issue hidden beneath. But which on ? I can't have any idea.
[UPDATE 2] To make things clear, the EJb I try to deploy is not visible as a web-service in Glassfish console, and its URL can't be pinged by any web client.
I'm looking at my copy of "EJB 3 In Action" and it says:
"A careful look at the code reveals that the #WebService endpoint interface looks similar to the remote interface. You might be tempted to mark the same interface as both a web service and a remote interface, like this:
#WebService
#Remote
public interface PlaceBid {
public Long addBid(String bidderID, Long itemID, Double dibPrice);
}
Unfortunately, although some vendors allow this as an extension, this is not part of the specification, and code that uses this particular attribute combination won't be portable."
You're going to have to remove the #Remote
You need to do some more troubleshooting. Have a look at the logs in glassfish3/glassfish/domains/domain1/logs. Or if you have standalone or cluster nodes look in glassfish3/glassfish/nodes/<nodename>/<instancename>/logs.
Also, log into the admin page "http://localhost:4848", default username is admin, default password is adminadmin. On the left there is a tree, find Applications, then your Ear should be listed there. Click it and you'll see a list of modules and components. If your web service is listed there you can click View Endpoint. There is a built-in tester, and you can get the wsdl URL there too.
update 1:
You don't have any #WebMethod(operationName = "blah) on your hello(). Maybe if there are no WebMethods GlassFish decides it's not worth making your web service available.
update 2: More complete example of how my web service is put together inside the ear. I'm pretty sure you don't have to separate the #WebService and #Stateless classes, but I like it that way because it feels cleaner and seems to separate the concerns.
war:
SomePojo.java:
#WebService(targetNamespace="blah.com")
public class SomePojo {
#EJB
private BlahSessionLocal blahSession;
#WebMethod(operationName = "hello")
public String hello(#WebParam(name = "user_id") Integer userId) throws Exception {
return blahSession.hello(userId);
}
}
ejb jar:
BlahSessionLocal.java
#Local
public interface BlahSessionLocal {
String hello(Integer userId);
}
BlahSessionBean.java
#Stateless(mappedName = "BlahSession")
public class BlahSessionBean implements BlahSessionLocal {
public String hello(Integer userId) {
return "hello user " + userId);
}
}