I'm following http://www.java2blog.com/2015/09/spring-restful-web-services-json-example.html and as it's suggested in the article when I deploy my application to tomcat I get the warning:
WARNING: [SetContextPropertiesRule]{Context} Setting property 'source' to 'org.eclipse.jst.j2ee.server:restordering' did not find a matching property.
(restordering is my application context)
And when I try to access my application I get this warning:
WARNING: No mapping found for HTTP request with URI [/restordering] in DispatcherServlet with name 'restordering'
and I see a 404 error page!
I've tested this on tomcat 7 and 8. I've created the war and deployed outside of eclipse and followed all suggested solution including change in server definition (publish module context to separate XML files) and removing and adding and doing all the tricks it's described in the above article and on stackoverflow but nothing has worked so far.
Before I get "this is a warning and ..." yes it is a warning but also I get 404 error and can't access my services.
And yes I have the correct package name in my restordering-servlet.xml ( context:component-scan base-package="com.obp.restordering.controller" ).
As requested here is my web.xml:
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>restordering</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>restordering</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
and restordering-servlet.xml is:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<mvc:annotation-driven />
<context:component-scan base-package="com.obp.restordering.controller" />
</beans>
and my controller file is this:
package com.obp.restordering.controller;
import java.util.ArrayList;
import java.util.List;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.obp.restordering.bean.Country;
#RestController
public class CountryController {
#RequestMapping(value = "/countries", method = RequestMethod.GET, headers = "Accept=application/json")
public List<Country> getCountries() {
List<Country> listOfCountries = new ArrayList<Country>();
listOfCountries = createCountryList();
return listOfCountries;
}
#RequestMapping(value = "/country/{id}", method = RequestMethod.GET, headers = "Accept=application/json")
public Country getCountryById(#PathVariable int id) {
List<Country> listOfCountries = new ArrayList<Country>();
listOfCountries = createCountryList();
for (Country country : listOfCountries) {
if (country.getId() == id)
return country;
}
return null;
}
// Utiliy method to create country list.
public List<Country> createCountryList() {
Country indiaCountry = new Country(1, "India");
Country chinaCountry = new Country(4, "China");
Country nepalCountry = new Country(3, "Nepal");
Country bhutanCountry = new Country(2, "Bhutan");
List<Country> listOfCountries = new ArrayList<Country>();
listOfCountries.add(indiaCountry);
listOfCountries.add(chinaCountry);
listOfCountries.add(nepalCountry);
listOfCountries.add(bhutanCountry);
return listOfCountries;
}
}
Any idea?
This is embarrassing but I need to come clean and admit and provide an answer so if others have the same issue they don't circle around days as I did.
Arpit the author of the mentioned tutorial responded to my request for help and after checking my code confirmed all works as expected!
The issue was in how I was trying to access my service! If I go to /restordering/countries I get the 404 error. To access the service I need to go to /restordering/restordering/countries! As simple as that.
The warnings I still get and I can't resolve them at this time but at least the service is working and this seems more of a deployment/setting issue than actual spring development issue.
Anyways, I thought this may help some others.
Cheers
Related
I am new to EJB.
I am using Wildfly server.
I have session stateless Ejb as below.
#Stateless(name="PrintHandler")
#RunAs("TrustedExternalModule")
public class PrintHandlerBean extends ActivityBean implements PrintHandlerLocal {
The session ejb is packed to a server-ejb.jar and that jar is packed to .ear
I have created ejb-jar.xml and jboss-ejb3.xml inside META-INF folder in server-ejb.jar as below.
<ejb-jar xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd">
<enterprise-beans>
<session>
<ejb-name>PrintHandler</ejb-name>
<security-identity>
<run-as>
<role-name>TrustedExternalModule</role-name>
</run-as>
</security-identity>
</session>
</enterprise-beans>
</ejb-jar>
<?xml version="1.1" encoding="UTF-8"?>
<jboss:ejb-jar xmlns:jboss="http://www.jboss.com/xml/ns/javaee"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:s="urn:security:1.1"
xsi:schemaLocation="http://www.jboss.com/xml/ns/javaee http://www.jboss.org/j2ee/schema/jboss-ejb3-2_0.xsd http://java.sun.com/xml/ns/javaee http://www.jboss.org/j2ee/schema/jboss-ejb3-spec-2_0.xsd"
version="3.1"
impl-version="2.0">
<jboss:enterprise-beans>
<session>
<ejb-name>PrintHandler</ejb-name>
<session-type>Stateless</session-type>
<security-identity>
<run-as>
<role-name>TrustedExternalModule</role-name>
</run-as>
</security-identity>
</session>
</jboss:enterprise-beans>
<assembly-descriptor>
<s:security>
<ejb-name>PrintHandler</ejb-name>
<s:security-domain>other</s:security-domain>
<s:run-as-principal>TESTCONNECT</s:run-as-principal>
</s:security>
</assembly-descriptor>
</jboss:ejb-jar>
I am injecting SessionContext annotated with Resource in a non ejb class as below.
public abstract class AbstractBean {
protected AbstractBean() {
log = LogMgr.getFrameworkLogger();
clsLog = LogMgr.getClassLogger(FndAbstractBean.class);
if(clsLog.debug) {
clsLog.debug("Created bean [&1]", getClass().getName());
}
}
**#Resource
protected SessionContext sessionContext;**
But when I am calling String user = sessionContext.getCallerPrincipal().getName();
it is returning "anonymous" always.
How can I solve this.
I want to get caller principal as TESTCONNECT.
Hello, this seems to be an expected behavior. The only workaround I found would be to use Interceptor,so then you can propagate the information actually. Interceptors is explained here
I have a strange problem which is not reproducible at the moment.
I have the following endpoints:
#Path("/v1/")
#Produces(MediaType.APPLICATION_JSON)
public class EndpointVersion1Base
{
private BackendRestClient restClient;
#EJB
public void setRestClient(BackendRestClient restClient)
{
this.restClient = restClient;
}
#Path("/dataprivacy/")
public Object getDataPrivacy()
{
return new DataPrivacyEndpoint(restClient);
}
#Path("/crashreporting/")
public Object getCrashReport()
{
return new CrashReportEndpoint(restClient);
}
}
The endpoint crashreporting has a Basic authentication. The endpoint dataprivacy has no authentication. The dataprivacy endpoint looks like this:
#Path("/")
#Produces(MediaType.APPLICATION_JSON)
public class DataPrivacyEndpoint
{
private BackendRestClient restClient;
private Logger logger = LoggerFactory.getLogger(getClass());
public DataPrivacyEndpoint(BackendRestClient restClient)
{
this.restClient = restClient;
}
public DataPrivacyEndpoint()
{
}
#POST
#Path("/")
#Consumes(MediaType.APPLICATION_JSON)
public Response storeConsent(
#NotNull(message = ErrorCodes.ERR_QUERY_PARAM_NULL) #Valid String consentInputBo) throws ForbiddenException, BadRequestException
{
//some code
}
}
I achieved the Basic Auth of the crashreporting endpoint by the following web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
<display-name>publicapi</display-name>
<security-constraint>
<web-resource-collection>
<web-resource-name>Crash reporting</web-resource-name>
<description>crash reporting service</description>
<url-pattern>/v1/crashreporting/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>publicapi</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>UserRoles simple realm</realm-name>
</login-config>
<security-role>
<role-name>publicapi</role-name>
</security-role>
</web-app>
and jboss-web.xml
<?xml version="1.0" encoding="UTF-8"?>
<jboss-web xmlns="http://www.jboss.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.jboss.com/xml/ns/javaee http://www.jboss.org/j2ee/schema/jboss-web_5_1.xsd">
<context-root>publicapi</context-root>
<security-domain>other</security-domain>
</jboss-web>
Yesterday all this worked. Today I started the services. Suddenly, as I sent a POST request to the dataprivacy endpoint via http://192.168.0.80:8080/publicapi/v1/dataprivacy/ and I got an HTTP error response "HTTP POST is not allowed for this method".
I wondered why this happened because it worked yesterday. After I restarted the services it suddenly worked again?!. What is going on here? Why does it sometimes work and sometimes not? (Currently I can't reproduce it). Do I have some misconfiguration in here which could lead to some strange behaviour? I'm afraid that this could happen on my LIVE system as well.
I tried to develop a rest service and expose the same via Apache Camel's CXFRS. I followed all the steps given in http://camel.apache.org/cxfrs.html and also referred to many samples given. I already referred to the question Can't find the the request for url Observer, but in my case it is a simple rest request. Below are the Service class, Route class, and cxf context used:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camel="http://camel.apache.org/schema/spring"
xmlns:cxf="http://camel.apache.org/schema/cxf" xmlns:context="http://www.springframework.org/schema/context"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/spring
http://camel.apache.org/schema/spring/camel-spring.xsd
http://camel.apache.org/schema/cxf
http://camel.apache.org/schema/cxf/camel-cxf.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<context:annotation-config />
<!-- enable Spring #Component scan -->
<context:component-scan base-package="org.camelsample.rest" />
<cxf:rsServer id="rsServer" address="/rest"
serviceClass="org.camelsample.rest.service.SampleRestService"
loggingFeatureEnabled="true" loggingSizeLimit="20">
<cxf:providers>
<bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider" />
</cxf:providers>
</cxf:rsServer>
<camel:camelContext id="samplerestservice"
xmlns="http://camel.apache.org/schema/spring">
<contextScan />
<jmxAgent id="agent" createConnector="true" />
</camel:camelContext>
</beans>
The Service Class:
package org.camelsample.rest.service;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
public class SampleRestService {
#GET
#Path("/")
public String sampleService() {
return null;
}
}
The Route Class:
package org.camelsample.rest.route;
import org.apache.camel.spring.SpringRouteBuilder;
public class SampleRestRoute extends SpringRouteBuilder {
#Override
public void configure() throws Exception {
// TODO Auto-generated method stub
from("cxfrs:bean:rsServer").log("Into Sample Route").setBody(constant("Success"));
}
}
But when I try to hit and test using http://localhost:8080/rest, I always get the following error message:
2015-05-29 13:38:37.920 WARN 6744 --- [nio-8080-exec-2] o.a.c.t.servlet.ServletController : Can't find the the request for http://localhost:8080/favicon.ico's Observer
2015-05-29 13:38:40.295 WARN 6744 --- [nio-8080-exec-3] o.a.c.t.servlet.ServletController : Can't find the the request for http://localhost:8080/rest's Observer
Am using Spring boot to test the rest sample.
Does it work with this URL instead ?
http://localhost:8181/cxf/rest
If you just use address="/rest" as your address then you will probably get the default Jetty port 8181 and default CXF servlet path /cxf as the base URL.
If you specifically want to use the URL you have given then try this instead:
address="http://0.0.0.0:8080/rest"
i am facing problem while running example which shows how a parameter is passed to a servlet in request object from html page.
My index.html contails-
<form action="welcome" method="get">
Enter your name<input type="text" name="name"><br>
<input type="submit" value="login">
</form>
my .xml contains
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>FirstServlet</display-name>
<servlet>
<servlet-name>check</servlet-name>
<servlet-class>MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>check</servlet-name>
<url-pattern>/check</url-pattern>
</servlet-mapping>
</web-app>
and .java
package cmctest;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class MyServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
String user=request.getParameter("user");
out.println("<h2> Welcome "+user+"</h2>");
} finally {
out.close();
}
}
}
when i am running this on server i am getting error,
please help me out to resolve this problem.
error image here
(remove dot please ~ i am new here and running low with rep >.< )
stack.imgur.com/iN85H[dot]jpg
i have even tried to run downloaded example in/for eclipse but still same error
I'm trying to do a simple REST Web Application using Tomcat 7, Apache Wink, and the Jackson JSON Processor, but seem to be hitting a wall. If I look in my web.xml file, I see:
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Example Web Application</display-name>
<servlet>
<servlet-name>ExampleServlet</servlet-name>
<servlet-class>org.apache.wink.server.internal.servlet.RestServlet</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.dummy.example.server.ExampleApplication</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ExampleServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
</web-app>
Now, if I substitute /* for the URL pattern instead, the REST call works, but when I use /services/*, it fails.
In my ExampleApplication I see:
package com.dummy.example.server;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.core.Application;
import org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider;
import org.codehaus.jackson.map.AnnotationIntrospector;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.introspect.JacksonAnnotationIntrospector;
import org.codehaus.jackson.xc.JaxbAnnotationIntrospector;
public class ExampleApplication extends Application {
/**
* Get the list of service classes provided by this JAX-RS application
*/
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> serviceClasses = new HashSet<Class<?>>();
serviceClasses.add(com.dummy.example.server.services.Employee.class);
return serviceClasses;
}
#SuppressWarnings("deprecation")
#Override
public Set<Object> getSingletons() {
Set<Object> s = new HashSet<Object>();
// Register the Jackson provider for JSON
// Make (de)serializer use a subset of JAXB and (afterwards) Jackson annotations
// See http://wiki.fasterxml.com/JacksonJAXBAnnotations for more information
ObjectMapper mapper = new ObjectMapper();
AnnotationIntrospector primary = new JaxbAnnotationIntrospector();
AnnotationIntrospector secondary = new JacksonAnnotationIntrospector();
AnnotationIntrospector pair = new AnnotationIntrospector.Pair(primary, secondary);
mapper.getDeserializationConfig().setAnnotationIntrospector(pair);
mapper.getSerializationConfig().setAnnotationIntrospector(pair);
// Set up the provider
JacksonJaxbJsonProvider jaxbProvider = new JacksonJaxbJsonProvider();
jaxbProvider.setMapper(mapper);
s.add(jaxbProvider);
return s;
}
}
And in my Employee class, I have:
package com.dummy.example.server.services;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.json.simple.JSONObject;
#Path("/services/employee")
#Produces(MediaType.APPLICATION_JSON)
#SuppressWarnings("unchecked")
public class Employee {
#GET
public JSONObject get() {
JSONObject json = new JSONObject();
json.put("Name", "Example");
return json;
}
}
Any ideas? I've been banging my head against this for some time now
The url-pattern parameter for your servlet (in the web.xml) is independent from the path you specify in your Employee class.
<servlet-mapping>
<servlet-name>ExampleServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
means your servlet listens on the /services/ sub-path.
#Path("/services/employee")
means that your REST application listens on the /services/employee "sub-sub-path".
So your webservice is exposed at localhost:8080/example/services/services/employee (the concatenation of the url-pattern and the #Path annotation).
If you want to expose it at localhost:8080/example/services/employee with the mentioned url-pattern, you need to change the Employee class needs to have:
#Path("employee")
Where would you expect /services/* to go? The web-app states what URL patterns the web application is willing to service. This makes the application server (e.g., JBoss, GlassFish) route /services/foo/bar/whatever to your web application. The Employee class will be invoked in response to a request to /services/employee so you can make that request. Nothing else is registered so /services/* should result in either a 404 or 400 response. Since /services/* is registered to your web application, I would expect a 400.