I have a server and client pair. Server is written in java using Jersey for RESTful APIs. I am running it in Tomcat server. It is working fine for HTTP GET/POST/DELETE calls. But I want to make the calls using HTTPS. What do I need to change on server side?
<!-- language: lang-java -->
#Path("/article")
public class ArticleService {
EntityDao<Article> articleDao = new ArticleDaoImpl();
#GET
public Response greet() {
return Response.ok("Welcome to restroshop APIs...").build();
}
#GET
#Path("/read/{id}")
#Produces("application/json")
public Response readArticle(#PathParam("id") final long id) {
Article article = articleDao.read(id);
return article != null ?
Response.ok(article, MediaType.APPLICATION_JSON).build() :
Response.noContent().build();
}
#POST
#Path("/create")
public long create(Article article) {
return ((Long) articleDao.create(article));
}
#DELETE
#Path("/delete/{id}")
public Response delete(#PathParam("id") final long id) {
articleDao.delete(id);
return Response.ok("Article Deleted successfully").build();
}
}
My web.xml is as following:
<web-app>
<display-name>Restroshop Application</display-name>
<servlet>
<servlet-name>Restroshop-servlet</servlet-name>
<servlet-class>
com.sun.jersey.spi.container.servlet.ServletContainer
</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.restroshop.application</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Restroshop-servlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
My Client is an android application.
Of what you've shown, none of your code needs to change. But to enable SSL depends on your setup. If you've got Apache httpd in front of Tomcat, then you'll need to start with the Apache SSL docs. If you're running only Tomcat then you'll need to take a look at the Tomcat SSL docs. Both of these processes are very well documented.
Related
I'm using Jersey and I implemented a ContainerRequestFilter.
Now I also want to add a ContainerResponseFilter to add a header to each request but nothing happens when the webservice is accessed.
This is how the filter looks like:
public class ResponseFilter implements ContainerResponseFilter {
#Override
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
MultivaluedMap<String, Object> headers = responseContext.getHeaders();
headers.add("Cache-Control", "whatever");
}
}
My jersey dependencies:
compile 'org.glassfish.jersey.core:jersey-client:2.18'
compile 'org.glassfish.jersey.containers:jersey-container-servlet-core:2.18'
compile 'org.glassfish.jersey.media:jersey-media-json-jackson:2.18'
I register the providers in an xml like this:
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>controller.webservice</param-value>
</init-param>
//This is the request filter, which is working fine
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>model.filter.AuthenticationFilter</param-value>
</init-param>
//Response filter, does not work
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>model.filter.ResponseFilter</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
This didn't work, so I tried to register the provider with the annotation #Provider and in the webservice like this:
register(TokenModifier.class);
But none of these worked. I read several other posts but I couldn't find an answer to it. Does anyone have a thought on this?
This init-param
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>controller.webservice</param-value>
</init-param>
is used by Jersey to scan package(s) listed for #Path and #Provider annotated classes, and register them. The package(s) listed will be recursively scanned. So for example, with your current configuration, all the following packages will get scanned
controller.webservice
controller.webservice.x
controller.webservice.x.y
controller.webservice.x.y.z
The value of the param can also be multiple values separated by a comma or semi-colon. So if your filter is in a different package base, you can add that package to the list of packages to scan
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>controller.webservice, com.my.filters</param-value>
</init-param>
Personally though, if I'm using web.xml, I will just use one base package, and have all other packages extend from that package. Something like
com.company.app
com.company.app.domain
com.company.app.filters
com.company.app.resources
Then you can just put the com.company.app as the init-param value, and all other sub packages will get scanned also.
I'trying to create simple WS project in Spring and Spring WS without any XSD. Deploy on jetty.
Is possible to populate WS endpoint and generate WSDL only from java classes (no static XSD or WSDL - I went throught many tutorials but all requiered).
For any help, hint or link highly appreciated.
I have something like this:
1) Request
#XmlRootElement
public class MessageWSRequest {
#XmlElement
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
2) Endpoint
#Endpoint
public class MessageWS {
#PayloadRoot(namespace = "http://message.com/ws/message" ,localPart="MessageWSRequest")
public String handleMathServiceRequest(#RequestPayload MessageWSRequest messageWSRequest) {
return "ok";
}
}
3) springContext.xml
<sws:annotation-driven/>
<context:component-scan base-package="com.ws.message"/>
4) web.xml
<servlet>
<servlet-name>webservices</servlet-name>
<servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
<init-param>
<param-name>transformWsdlLocations</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>webservices</servlet-name>
<url-pattern>*.wsdl</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>webservices</servlet-name>
<url-pattern>/endpoints/*</url-pattern>
</servlet-mapping>
Now I would expect URL like this
localhost:8080/messageTest/endpoints/MessageWS.wsdl
with generated WSDL.
Did I miss some configuration or so?
Thanks all
Ok, next day a clear mind revelead me this fact:
Spring WS offers "only" contract-first, starting from an XSD Schema
I'll use CXF instead:
Apache CXF offers both contract-last (starting with Java) and Contract-first (starting with the WSDL) approaches.
As you have noted, Spring WS is designed for contract first services. However I think that you can still achieve what you want to do if you generate the XSD during the build process from your annotated classes. Here is one way to do that:
Generating XSD schemas from JAXB types in Maven?
Suppose we use tomcat as container and we have implemented a web service server using spring web-service framework.
Now we want to provide a web page for users to access some other functions of our product in a browser instead of the client software.
The logic processing web page requests is similar to that processing web service ones. So we want to write web-page-generating codes with in the same application context as the web service.
This might be a weird need, but it is a need.
I tried to write a servlet and refer to a Service loaded by Spring, but it feels dirty and sometimes does not work:
class ExampleServlet{
private FooService service = FooService.ins;
public doGet(HttpServletRequest request, HttpServletResponse response){
service.doSomething();
// ...
return someResponse;
}
}
#Service
class FooService{
public static FooService ins = null;
public FooService(){
ins = this;
}
#Transactional(rollbackFor = Exception.class)
public void doSomething(){
// ...
}
}
in web.xml :
<servlet>
<servlet-name>spring-ws</servlet-name>
<servlet-class>
org.springframework.ws.transport.http.MessageDispatcherServlet
</servlet-class>
<init-param>
<param-name>transformWsdlLocations</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<display-name>ExampleServlet</display-name>
<servlet-name>ExampleServlet</servlet-name>
<servlet-class>com.somepackage.ExampleServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ExampleServlet</servlet-name>
<url-pattern>/do_something</url-pattern>
</servlet-mapping>
I should wrap them up in spring mvc
ref:
http://docs.spring.io/spring-ws/docs/2.2.0.RELEASE/reference/htmlsingle/#d4e950
http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#mvc-servlet
We have an existing Jersey REST service in our application(URL: /rest/*).
A sample URL looks like: http://xxx:8080/app/rest/company/getdata
Based on a property we need to redirect the REST call to another context(URL: /newrest/*):
A sample URL would look like: http://xxx:8080/app/newrest/company/getdata
So, I added a servlet mapping in my web.xml.
So, My web.xml looks like the below snippet.
<servlet>
<servlet-name>ServletAdaptor</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>xxx.httpservice</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ServletAdaptor</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<filter>
<filter-name>secureRESTFilter</filter-name>
<filter-class>xxx.RESTSecurityFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>secureRESTFilter</filter-name>
<url-pattern>/rest/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>NewAdaptor</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>xxx.newhttpservice</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>NewAdaptor</servlet-name>
<url-pattern>/newrest/*</url-pattern>
</servlet-mapping>
I have written a filter(to check for the property on the ServletAdaptor servlet and I need to redirect to the NewAdaptor servlet, if needed. Also, the final response should be sent back by the Servlet Adaptor servlet using the response from NewAdaptor servlet, if necessary(based on the property).
I need directions for solving this issue. Please help.
The dofilter method in my filter class looks like:
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) req;
String productMode = "b";//hardcoded for this example
String url = request.getRequestURL().toString();
if(productMode.equals("a")){
chain.doFilter(req, res);
}else{
url=url.replace("rest", "newrest");
req.getRequestDispatcher(url).forward(req, res);
}
}
But the RequestDispatcher does not seem to forward the request to the new url.
From what i understand you are trying to create new services or integrate newer one.
Ideally you can version the URL's to support backward compatibilty in future.e.g.
http://{xxx}:8080/app/rest/v1_0/company/getdata,http://{xxx}:8080/app/rest/v2_0/company/getdata etc.
Why don't you wrap the new API call in the existing API call? So that the consumer talks to your API, internally you invoke the newer API and consume the response of it.Then you either return the new object or wrap your object around it.
You need to really re-look at the strategy you are trying to adopt!
How to pass pojo object as parameter to rest web service from prototypejs client.
Assume i have web service like this.
#Path("/postItem")
#Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Item postItem(Item item)
{
return new item;
}
From client side using prototypejs library how to pass pojo object as parameter to rest web service.
If parameter is of type string or integer i would have passed it as query param but it is pojo object in case.
I am about the syntax creation of the pojo object and then passing it to rest web service from prototypejs.
Which jax-rs implementation do you use? for Jersey, you can post json to the server by specify the jersey servlet:
<servlet>
<servlet-name>jersey-servlet</servlet-name>
<servlet-class>
com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>your package</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey-servlet</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
then in your client code, you can directly post a json to the server, which will be deserialized to an Item instance