cxf and spring MVC : No service was found - spring

I have spring application, in which I use org.apache.cxf for soap and spring MVC for displayng some pages.
My web.xml contains two servlets :CXFServlet and mvc-dispatcher
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/servlet-context.xml</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
When I has been used #ResponseBody in my controller everything was fine.
#Controller
#RequestMapping("/hello")
#ResponseBody
public class HelloController {
#RequestMapping(method = RequestMethod.GET)
public String printWelcome() {
return "hello" ;
}
}
but then i was needed to use jsp I have to use the following
#Controller
#RequestMapping("/hello")
public class HelloController {
#RequestMapping(method = RequestMethod.GET)
public ModelAndView printWelcome(ModelMap model) {
model.addAttribute("message", "hello");
return new ModelAndView("hello") ;
}
}
and when I request http://localhost:8080/hello I get "No service was found" instead of "hello"
I found that if I delete following from web.xml
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
my controller works fine.

The Servlet container you are using is matching CXFServlet instead of mvc-dispatcher for the URI http://localhost:8080/hello, resulting in your request being sent to CXFServlet, and the error message "No service was found" being returned by CXFServlet. To quote the Servlet 3.0 spec,
Versions of this specification prior to 2.5 made use of these mapping
techniques as a suggestion rather than a requirement, allowing servlet
containers to each have their different schemes for mapping client
requests to servlets.
http://download.oracle.com/otndocs/jcp/servlet-3.0-fr-eval-oth-JSpec/
You will likely need to configure you CXFServlet mapping to something else, e.g.
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
You might want to mention the container (Tomcat, Glassfish, etc.) that you are using, as there could also be a bug preventing this from working correctly.

Related

Spring servlet URL mapping

I need to add Restful URL in existing spring based web service.
Each URL is well mapped but after clicking Restful URL such as
http://localhost:9090/Mercury/rest/invoice,
all contextroot path is changed as http://localhost:9090/Mercury/rest
The point is that I want to use both restful(/rest) and *.do URL pattern
How can I set contextroot path up without /rest ?
web.xml
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>rest</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>rest</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Controller
#Controller
#RequestMapping("/rest")
public class InvoiceController {
#RequestMapping(value="/{name}", method=RequestMethod.GET)
public String getInvoice(#PathVariable String name, Model model) {
model.addAttribute("name", name);
return "rest.body";
}
Please refer Spring Pet Clinic on github, to learn how to configure various views.Sample view config xml. Here is the outline.
The ContentNegotiatingViewResolver delegates to the
InternalResourceViewResolver and BeanNameViewResolver, and uses the
requested media type (determined by the path extension) to pick a
matching view. When the media type is 'text/html', it will delegate to
the InternalResourceViewResolver's JstlView, otherwise to the
BeanNameViewResolver.

springmvc cannot call controller's method

Currently I got a problem when I configure my springmvc web project.
Below is my web.xml
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
And I defined my dispatcher-servlet.xml like this
<context:component-scan base-package="xxx.controller"
<mvc:annotation-driven />
And in package xxx.controller I define a class TestController
#Controller
#RequestMapping(value="/api")
public class TestController {
#RequestMapping(value = "/hello")
#ResponseBody
public String hello(){
System.out.println("comming hello");
return "hello world";
}
}
Now when I start tomcat, and want to access to localhost:8080/testproject/api/hello, The spring informs me
[10:10:58|WARN |(org.springframework.web.servlet.PageNotFound)]=[No mapping found for HTTP request with URI [/testproject/api/hello] in DispatcherServlet with name 'dispatcher']
But if I modify the url-pattern in web.xml to
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
It is ok to access to localhost:8080/testproject/api/hello. I do not know why this happens. I do want to use /api/* rather than /.
Could anyone helps me configure the controller path mapping? Many thanks!
You are telling your application to run in /api context when you define the following:
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
so to access your controller the URL would have to be localhost:8080/api/api/hello
Just get rid of the /api from your dispatcher as you have and then your mapping should automatically default to localhost:8080/api/hello and work.
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Otherwise if you want to run your application in /api context always you have the option of removing #RequestMapping(value="/api") from your controller.
That way it only recognises the mapping on method.

How can I redirect the user to a servlet instead of an index file on initial page load?

Here is what I have configured in web.xml :
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
But if I change it to a servlet :
<welcome-file-list>
<welcome-file>myservlet</welcome-file>
</welcome-file-list>
I receive a 404 error message.
How can I redirect the user to a servlet instead of an index file on initial page load ?
THe servlet is based on Spring :
#Controller
public class MyController {
#RequestMapping(value="redirect")
public String displaySearch(Model model) {
model.addAttribute("test" , "test");
return "mypage";
}
}
I just need the "redirect" servlet to be invoked by default.
Edit : the spring dispatcher servlet is mapped on the '/' url pattern, is this incorrect also ?
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Via a servlet mapping, e.g.:
<servlet-mapping>
<servlet-name>myservlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

Dispatcher servlet mapping

I am trying to use spring-security
Before all of the configuration
http://localhost:9090/app/login2.xhtml
request, works as i expected.
I added a controller:
#Controller
#RequestMapping("/auth")
public class LoginController {
#RequestMapping(value = "/login", method = RequestMethod.GET)
public String getLoginPage(#RequestParam(value="error", required=false) boolean error,
ModelMap model) {
return "login2.xhtnml";
}
}
I have in web.xml:
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:META-INF/spring-servlet.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
With this configuration when i call
http://localhost:9090/app/login2.xhtml
Error comes
WARN org.springframework.web.servlet.PageNotFound - No mapping found for HTTP request with URI [/app/login2.xhtml] in DispatcherServlet with name 'spring'
BUT when i change configuration mapping to
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
http://localhost:9090/app/login2.xhtml works as i expected
but
http://localhost:9090/app/auth/login
gives no error, no exception, no redirection, i think dispatcher servlet can not know about this request.
http://localhost:9090/app/app/auth/login
works with
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
My understanding:
dispatcher servlet use "http://localhost:9090/" as base for searching login2.xhtml
and use "http://localhost:9090/app" for /auth/login URL.
I do not know where to set this, and why they are different.
Have you added the SpringSecurityFilterChain to the web.xml?
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Could you past the registered "Request Bindings" if the container starts (from the logfile)?

Configuring Grizzly with a web.xml

I can start grizzly and deploy Jersey webservices on it with the following lines.
protected HttpServer create() throws Throwable {
ResourceConfig rc = new PackagesResourceConfig("com.resource", "com.provider");
HttpServer server = GrizzlyServerFactory.createHttpServer(uri, rc);
return server;
}
But is there a way to load a web.xml instead of a ResourceConfig?
<web-app>
<servlet>
<servlet-name>Jersey</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.resource, com.provider</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Jersey</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
It seems that there is currently no direct way to configure grizzly with a web.xml. However I have used a partial solution that may be a beginning.
web.xml
First to understand the solution, we must understand what is the meaning of using a web.xml. It is basically use for configure your web application (see this answer for a more detail). In this case we are configuring init-params for the servlet.
The (partial) solution
Instead of using the web.xml and instead of using ResouceConfig.class, we can use Grizzly as our servlet and initializing the parameters.
For example
<web-app>
<servlet>
<servlet-name>Jersey</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.resource, com.provider</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Jersey</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
would give something like :
protected HttpServer create() throws Throwable {
HashMap<String, String> initParams = new HashMap<>();
//ServerProperties.PROVIDER_PACKAGES is equal to "jersey.config.server.provider.packages"
initParams.put(ServerProperties.PROVIDER_PACKAGES, "com.resource,com.provider");
//Make sure to end the URI with a forward slash
HttpServer server = GrizzlyWebContainerFactory.create("http://localhost:8080/", initParams);
return server;
}
With this, we can therefore put all the init-params that we want to.
However this solution cannot replace a whole web.xml.

Resources