How to configure SockJsHttpRequestHandler using XML in a working application - spring

From spring-websocket-portfolio-master WebConfig.java:
#Bean
public SimpleUrlHandlerMapping handlerMapping() {
DefaultSockJsService sockJsService = new DefaultSockJsService(sockJsTaskScheduler());
//sockJsService.setDummySessionCookieEnabled(true);
HttpRequestHandler requestHandler = new SockJsHttpRequestHandler(sockJsService, stompWebSocketHandler());
SimpleUrlHandlerMapping hm = new SimpleUrlHandlerMapping();
hm.setOrder(-1);
hm.setUrlMap(Collections.singletonMap("/portfolio/**", requestHandler));
return hm;
}
I want to add to XML configuration in current application. I have the following in web.xml:
<servlet>
<servlet-name>mximonitor</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mximonitor</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
I have this so far (and I hope it is right):
<!-- Following two beans were wrapped in a SimpleUrlHandlerMapping bean -->
<bean id="sockJsService" class="org.springframework.web.socket.sockjs.support.DefaultSockJsService">
<constructor-arg index="0" ref="sockJSTaskScheduler"/>
</bean>
<bean id="sockJsHttpRequestHandler" class="org.springframework.web.socket.sockjs.support.SockJsHttpRequestHandler">
<constructor-arg index="0" ref="sockJsService"/>
<constructor-arg index="1" ref="stompWebSocketHandler"/>
</bean>
I would like to be able to add new request handler to existing configuration. I guess I would use 'SimpleUrlHandlerMapping' but I am fairly new to Spring (and web programming in general). How would I configure? Is 'SimpleUrlHandlerMapping' additive (meaning it will not interfere with existing controllers?
Thanks in advance (and for your patience),
James

Related

Spring mvc #RequestMapping on class level and method level 404 Status

I know that there are lot of posts here with the same problem, but none of them seem to help me, so this will probably be a duplicate.
Im creating a spring mvc application using Maven, i have only one controller with one method. When i put the request mapping annotation only on the class level the application works fine but when i put it on the class level and the method level and i send a request like this:
localhost:8080/myapplication/planification/projet
i get 404 error: HTTP Status 404 - /myapplication/planification/WEB-INF/pages/test.jsp
here is my controller
#Controller
#RequestMapping("/planification")
public class PlanificationController {
#RequestMapping("/projet")
public ModelAndView projets (ModelAndView m){
m.addObject("projets", "All projects");
m.setViewName("test");
return m;
}
}
mvc-dispatcher-servlet.xml
<beans>
<context:component-scan base-package="com.smit"/>
<mvc:annotation-driven/>
<!-- **** VIEW RESOLVER BEAN **** -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>WEB-INF/pages/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
</beans>
web.xml
<web-app>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet- class>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/mvc-dispatcher-servlet.xml
</param-value>
</context-param>
</web-app>
Hold on, you are using / in front of RequestMapping value, which means from the root. You should removed it like this
#RequestMapping("projet")
Then go to localhost:8080/myapplication/planification/projet
Edit:
WEB-INF should have / in front!

spring-ws: no endpoint mapping found

I made a simple web service but when I'am trying to test it on soapui its giving this error:
WARN : [Oct-11 12:56:38,081] ws.server.EndpointNotFound - No endpoint mapping found for [SaajSoapMessage {http://www.servesy.com/api/v1/service}signupRequest]
I do not have any idea what should I do to make it correct, I saw many questions regarding this problem but did not find any solution.
My spring-ws configuration are follows:
(apart from this configuration I also tried to make simple input output example and that
also shows same warning)
web.xml
<web-app
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/config/servesy-config.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>servesyservices</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>servesyservices</servlet-name>
<url-pattern>*.wsdl</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>servesyservices</servlet-name>
<url-pattern>/endpoints/*</url-pattern>
</servlet-mapping>
</web-app>
servesy-config.xml
<beans
<context:component-scan base-package="com.servesy.webservices" />
<sws:annotation-driven />
<bean id="ServesyService" class="org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition" lazy-init="true">
<property name="schemaCollection">
<bean class="org.springframework.xml.xsd.commons.CommonsXsdSchemaCollection">
<property name="inline" value="true" />
<property name="xsds">
<list>
<value>schemas/ServesyServices.xsd</value>
</list>
</property>
</bean>
</property>
<property name="portTypeName" value="ServesyService"/>
<property name="serviceName" value="ServesyServices" />
<property name="locationUri" value="/endpoints"/>
</bean>
</beans>
Endpoint
#Endpoint
public class ServesyWebServiceEndpoint {
private static final String TARGET_NAMESPACE ="http://www.servesy.com/api/v1/service";
private ServesyWebService servesyservice_i;
#Autowired
public void setServesyWebService(ServesyWebService servesyservice_p)
{
this.servesyservice_i = servesyservice_p;
}
#PayloadRoot(localPart="SignupRequest", namespace=TARGET_NAMESPACE)
public #ResponsePayload SignupResponse response(SignupRequest signupRequest) {
SignupResponse signupResponse = new SignupResponse();
Signup signup = servesyservice_i.signupResponse( signupRequest.getMobileNumber(), signupRequest.getPassword(), signupRequest.getCustomerName(), signupRequest.getEmailId(), signupRequest.getPromoCode(), signupRequest.getDevice());
signupResponse.setSignup(signup);
return signupResponse;
}
#PayloadRoot(localPart="LoginRequest", namespace=TARGET_NAMESPACE)
public #ResponsePayload LoginResponse response(LoginRequest loginRequest) {
LoginResponse loginResponse = new LoginResponse();
String string = servesyservice_i.signinResponse( loginRequest.getEmailID(), loginRequest.getPassword(), loginRequest.getDevice());
loginResponse.setSessionId(string);
return loginResponse;
}
}
and my soupui gives this type of blank output:
The EndpointNotFoundException occurs when Spring-WS cannot find a suitable #Endpoint that can handle the incoming request.
In this case, the incoming message has namespace http://www.servesy.com/api/v1/service and local name signupRequest (as can be seen in the log). While your #PayloadRoot mapping does have the same namespace; it does not have the same local name, as it uses SignupRequest with a capital S. Chances are that if you change the uppercase S to a lower case s in the #PayloadRoot annotation, it will work.
context level parameters need to be reflected in MessageDispatcherServlet level also.
<servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class> <br>
<init-param> <br>
<param-name>transformWsdlLocations</param-name> <br>
<param-value>true</param-value> <br>
</init-param> <br>
<init-param> <br>
<param-name>contextConfigLocation</param-name> <br>
<param-value>/WEB-INF/config/servesy-config.xml</param-value> <br>
</init-param> <br>
For what's it worth, I was facing this issue 2021-02-17 14:13:52.810 DEBUG 204429 --- [nio-8080-exec-7] o.s.w.soap.server.SoapMessageDispatcher : Endpoint mapping [org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping#7f98f516] has no mapping for request while following - https://spring.io/guides/gs/producing-web-service/- was that I somehow missed to annotate the the endpoint with #Endpoint public class CountryEndpoint
I have faced a similar issue and the root cause was in the application servlet context path.
The best way how to approach this problem is, in my opinion, to set DEBUG logging level for "org.springframework.ws" and carefully watch logs. You should find a message like this:
o.s.w.s.e.mapping.UriEndpointMapping - Mapped key [/ws/CardInfoWS_v3] onto endpoint [bean 'cardInfoEndpointGateway_v3'; defined in: '...']
And the warn after sending request says:
o.s.w.s.e.mapping.UriEndpointMapping - Looking up endpoint for [/cms-ws/ws/CardInfoWS_v3]
o.s.ws.server.EndpointNotFound - No endpoint mapping found for [SaajSoapMessage {...}GetCardRequest]
So... it is looking for endpoint mapping under the key "/cms-ws/ws/CardInfoWS_v3" but the endpoint is registered under the key "/ws/CardInfoWS_v3".
You can also put the breakpoint to the method lookupEndpoint in your endpoint mapper (AbstractMapBasedEndpointMapping or AbstractMethodEndpointMapping) that looks like this:
protected Object lookupEndpoint(String key) {
return endpointMap.get(key);
}
and after sending the request, in the debug mode you will see all your registered endpoints and the key which is currently searched.

#Autowired not working in CXF interceptor + Spring application

Having an issue with how CXF interceptor is setup and used by Spring. I want to log the incoming SOAP requests to database for audit log. I have the setup as below, but whenever incoming SOAP request comes, I get NPE where the service layer class is being accessed. It looks from log that the web application context is being re-loaded again leading to null reference for service bean.
I had a look at the two entries - this and this - which are close, and tried out the solution in first link, but not working.
Any help is appreciated.
Thanks
Interceptor code:
public class AuditLogInterceptor extends AbstractLoggingInterceptor {
private AuditLogService auditLogService;
#Autowired
public void setAuditLogService(AuditLogService auditLogService) {
this.auditLogService = auditLogService;
}
private void saveAuditLogEntry() {
// some more code ...
auditLogService.logRequest(logEntry);
}
cxf-servlet.xml
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<bean id="jsonProvider" class="org.codehaus.jackson.jaxrs.JacksonJsonProvider" />
<!-- Add new endpoints for additional services you'd like to expose -->
<bean id="abstractLogInterceptor" abstract="true">
<property name="prettyLogging" value="true" />
</bean>
<bean class="com.xyz.interceptor.AuditLogInterceptor" id="logInInterceptor" parent="abstractLogInterceptor"/>
<jaxws:endpoint id="dataService" implementor="#masterDataService" address="/MasterDataService">
<jaxws:inInterceptors>
<ref bean="logInInterceptor" />
</jaxws:inInterceptors>
</jaxws:endpoint>
web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:/applicationContext-resources.xml
classpath:/applicationContext-dao.xml
classpath:/applicationContext-service.xml
classpath*:/applicationContext.xml
/WEB-INF/applicationContext*.xml
/WEB-INF/cxf-servlet.xml
/WEB-INF/security.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
I expect you're getting the contents of /WEB-INF/cxf-servlet.xml included in both the CXFServlet's context and the ContextLoaderListener's. Try removing the line /WEB-INF/cxf-servlet.xml from the ContextLoaderListener's contextConfigLocation attribute. You should also rename cxf-servlet.xml because the CXFServlet looks for a file with that exact name (see http://cxf.apache.org/docs/configuration.html) - or merge it into the rest of your applicationContext.xml.

I am trying to use spring application context and spring di in my scala vaadin app, but can't get a datasource to be injected

i am new to scala and vaadin, i'm just experimenting. I am trying to use spring application context and spring di in my scala vaadin app, but can't get a datasource to be injected. I dont know, maybe i'm doing something fundamentally wrong but here's my code:
web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<description>
Vaadin production mode</description>
<param-name>productionMode</param-name>
<param-value>false</param-value>
</context-param>
<servlet>
<servlet-name>Scalatest Application</servlet-name>
<servlet-class>com.vaadin.terminal.gwt.server.ApplicationServlet</servlet-class>
<init-param>
<description>Vaadin application class to start</description>
<param-name>application</param-name>
<param-value>com.example.scalatest.ScalaApp</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Scalatest Application</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
application context:
<bean id="main" class="com.example.scalatest.ScalaApp">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="url"/>
<property name="username" value="root"/>
<property name="password" value="pass"/>
</bean>
and in my scala class
var dataSource:DataSource = _;
def setDataSource(datasource:DataSource){
dataSource = datasource;
}
Isn't working, ds is null at launch.
Can anyone guide me please?
The main problem you have is your application (ScalaApp) is not instantiated by Spring container but by VaadinServlet - make sure it does. There are several strategies. Here is the example project that can help you: https://github.com/archiecobbs/dellroad-stuff-vaadin-spring-demo3
Few more pieces of advice...
Instead of writing a setter yourself, add #BeanProperty annotation to your variable. Scala compiler will generate setter and getter for your variable:
#BeanProperty private var dataSource:DataSource = _
There is even better way - using Spring's annotation based container configuration. If you have only one bean of type DataSource in your context, simply add #Autowired to your variable (no need for xml definition in the context file - your class should be annotated as a #Component ):
#Component
class ScalaApp {
#Autowired private var dataSource:DataSource = _
}
Here is more information: http://static.springsource.org/spring/docs/3.0.x/reference/beans.html#beans-annotation-config

The spring web mvc framework handle the jsp file dispatch as another request

I am new to spring web mvc framework,and I use struts 2 before.
I create a new dynamic web project using eclipse EE,and add all the jars to the /web-info/lib.
The whole hierarchy of the project is like this:
SpringMVCTest
WEB-INF
web.xml
example-servlet.xml
jsp
hello.jsp
lib
xxxx.jars
.....
This is the servlet definition:
<servlet>
<servlet-name>example</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>example</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
This is the example-servlet.xml:
<context:component-scan base-package="com.kk.web.controllers" />
<bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
And the controller:
package com.kk.web.controllers;
#Controller("example")
#RequestMapping("/example")
public class ExampleController {
#RequestMapping("/hello")
#ResponseBody
public String hello() {
return "hello";
}
#RequestMapping("/hello_jsp")
public ModelAndView hello_jsp(){
ModelAndView mv=new ModelAndView("hello");
mv.addObject("message", "welcome");
return mv;
}
}
It worked when I run:
http://localhost:8080/SpringMVCTest/example/hello
But when I run:
http://localhost:8080/SpringMVCTest/example/hello_jsp
I got the warn:
2011-10-17 10:36:15 org.springframework.web.servlet.DispatcherServlet noHandlerFound
Warn: No mapping found for HTTP request with URI [/SpringMVCTest/WEB-INF/jsp/hello.jsp] in DispatcherServlet with name 'example'
It seems that the ExampleController works,it dispatch the request "/example/hello_jsp" to the right view "jsp/hello.jsp".
But then the spring take the file dispatch "/jsp/hello.jsp" as another request,then it will not find the matched url mapping in the "example" controller.
Why?? IMO,a requst must come from the client to server,the controller receive only one request here "/exmaple/hello_jsp",isn't it?
And How to fix it?
BTW,I can set the url pattern to "/*.xxx",but I do not want the suffix in the url.
Any ideas?
Previous answer did not work...
This posting looks similar: http://forum.springsource.org/showthread.php?55982-No-mapping-found-for-HTTP-request-with-MVC-requests
Summary: change
<servlet-mapping>
<servlet-name>example</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
to
<servlet-mapping>
<servlet-name>example</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
and checking my latest Spring MVC app I use the latter pattern (no * on the end).

Resources