I'm not able to correctly configure json support with Spring 4.0.4. A json request results in:
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.getHandlerInternal(246): - Looking up handler method for path /equipments/datatable.json
org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver.resolveException(134): - Resolving exception from handler [null]: org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'GET' not supported
org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver.resolveException(134): - Resolving exception from handler [null]: org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'GET' not supported
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver.resolveException(134): - Resolving exception from handler [null]: org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'GET' not supported
org.springframework.web.servlet.PageNotFound.handleHttpRequestMethodNotSupported(198): - Request method 'GET' not supported
I have an applicationContext.xml and a my-servlet.xml:
web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/conf/applicationContext.xml
/WEB-INF/conf/my-security.xml
</param-value>
</context-param>
<servlet>
<servlet-name>losap</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/conf/my-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
applicationContext.xml
<mvc:annotation-driven />
<task:annotation-driven />
<tx:annotation-driven />
<context:component-scan base-package="com.htg.*">
<context:exclude-filter type="regex" expression="com\.htg\.myapp\.mvc"/>
</context:component-scan>
<bean id="messageAdapter"
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<util:list>
<bean
class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />
</util:list>
</property>
</bean>
my-servlet.xml
<mvc:annotation-driven/>
<context:component-scan base-package="com.htg.myspp.mvc" />
pom.xml
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
Controller
#Controller()
#RequestMapping(value = "/equipments")
public class EquipmentController extends BaseController {
#RequestMapping(value = "/datatable.json", method = RequestMethod.GET, headers = "Accept:*/*", produces = "application/json")
public #ResponseBody Equipment getEquipmentsDatatable(Model model) {
Equipment e = new Equipment();
e.setEquipmentName("Lathe 123");
e.setEquipmentNumber("12345TTY");
e.setId(89L);
return e;
}
}
jQuery
$.getJSON($('#ctxtrelurl').val() + 'equipments/datatable.json', function(e) {
console.log(e.equipmentName);
});
Chrome Dev. Tools output
I have a feeling it has something to do with having two separate context config. files. Any pointers will be greatly appreciated.
ok, my guess is, that spring doesn't map /datatable.json properly because of the "." I had similar problem at mapping this:
#RequestMapping(value="/somestuff/{fileName:.+}"
i had to put :.+ so spring can properly map the url.
spring seems to truncate ".something" in this case. I actually don't know if it's the case on regular mapping, without #PathVariable. But you could try to map your URL without the dot and check if it will help
And that's why spring try to call the {equipId} function, that is waiting for PUT request. That's why in the response header you see : allow:PUT
Related
I am trying to write a simple Spring MVC web application without using annotations. However, when I access specific URL, I am getting HTTP 404 error. The relevant code snippet is below:
web.xml changes done for front controller:
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:web="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.4">
<display-name>POCProject</display-name>
<servlet>
<servlet-name>FrontController</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>FrontController</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
The servlet name is --> FrontController
Hence, have the following configuration file --> FrontController-servlet.xml
<beans ...>
<bean id="HandlerMapping" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<bean name="/userdetails" class="com.example.controllers.UserDetailsController"/>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix"> <value>/WEB-INF/</value> </property>
<property name="suffix"> <value>.html</value> </property>
</bean>
</beans>
In above configuration file, the Handler mapping class is --> org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping
The controller class for URL /userdetails is --> com.example.controllers.UserDetailsController
The code for this controller is below:
public class UserDetailsController extends AbstractController {
#Override
protected ModelAndView handleRequestInternal(HttpServletRequest req, HttpServletResponse res) throws Exception {
ModelAndView mw = new ModelAndView("userInfo");
return mw;
}
}
So, for a request with /userdetails the controller should send the view userInfo.html
However when I invoke this, I am getting HTTP 404 error.
I have deployed this in Apache tomcat, and the below is the message that I get in the tomcat console.
WARNING: No mapping found for HTTP request with URI [/POCProject/WEB-INF/userInfo.html] in DispatcherServlet with name "FrontController"
Any inputs on what I am missing here?
The javadoc for InternalResourceViewResolver says that it is a (emphasize mine):
Wrapper for a JSP or other resource within the same web application. Exposes model objects as request attributes and forwards the request to the specified resource URL using a RequestDispatcher.
A JSP is internally converted in a true servlet by Tomcat (or by any servlet container) that is a resource suitable for forwarding. But a simple HTML is not.
That means that Spring InternalResourceViewResolver cannot use HTML views and you must convert them to JSP files.
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.
Now I have a controller like this
#RequestMapping("/content/delete.json")
#Security(auth = AuthType.REQUIRED)
public ModelAndView deleteIndex(User user, #RequestParam("id") long id) {
}
Now I am trying to get controller mapping method from interceptor and getting the annotation of the method.
Method method = RestRequestURLUtil.getInvokedMethod(handler, request);
Security security = method.getAnnotation(Security.class);
if(security.getAuth() == AuthType.REQUIRED) {
do some validate here
}
Are there any classes like RestRequestURLUtil in spring?
thanks in advance :)
edit:
web.xml
<servlet>
<servlet-name>rest</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/rest-servlet.xml,
/WEB-INF/interceptor-servlet.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>rest</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
interceptor-server.xml
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="com.test.web.interceptors.SecurityInterceptor" init-method="init">
...
</bean>
</mvc:interceptor>
The annotation on the controller's method can be inspected in the interceptor by means of the HandlerMethod object that the framework should pass as handler Object.
if (handler instanceof HandlerMethod) {
HandlerMethod method = (HandlerMethod) handler;
if (method.getMethod().isAnnotationPresent(Security.class)) {
//do processing
}
}
However, according to the spring documentation in HandlerMethod javadoc, HandlerMethod class was introduced in Spring 3.1. It seems that, in versions prior to 3.1, handler object was a Controller instance, which makes fetching the annotation of the invoked controller method difficult.
You can either upgrade to 3.1. and fetch the annotation from HandlerMethod object or attempt to parse all the RequestMapping annotations on the controller methods and then attempt to determine which method was invoked by comparing RequestMappings with request URI.
If upgrade is not an option, another alternative would be to use AOP instead of mvc interceptor.
I have a scenario where I'm making a simple get request through a link and my #RequestMapping configuration is not behaving as I'd expect.
Within an anchor tag I reference a url with the following pattern '/action-plan/export/pdf?token=xxx&taskId=1111&taskId=2222...'
Within my controller class I have this mapping at the class level:
#RequestMapping("/action-plan/export")
And this mapping at the method level
#RequestMapping(value="/pdf", method=RequestMethod.GET)
public String exportToPdf(#RequestParam("taskId") String[] taskIds,
#RequestParam("token") String[] encryptedEmplId, ModelMap model)
But every time I try this I get a 404 page not found error and the following Spring exception:
org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException: No matching handler method found for servlet request: path '/pdf', method 'GET', parameters map['taskId' -> array['1962326', '1962264', '1962317', '1962328', '1962324', '1962427', '1962325', '1962323', '1963147', '1962327', '1962318', '1962329', '1962330'], 'token' -> array['xxxx']]
I've noticed that when I remove the "/pdf?" portion of the link and remove 'value="/pdf"' from the method #RequestMapping it works fine. For the life of me I don't understand why adding /pdf to the url and RequestMapping is not working.
I think danny.lesnik's answer was pretty close but I'm writing my own answer so I can be more verbose.
I was working on a different project and figured out why the above doesn't work. In reference to my original question here is the relevant web.xml servlet mapping:
<servlet-mapping>
<servlet-name>spring-dispatcherServlet</servlet-name>
<url-pattern>/action-plan/export/*</url-pattern>
</servlet-mapping>
I noticed that whatever portion of the path I included in the of web.xml was not being included in the evaluation of RequestMapping values. I would have thought this bean configuration would have prevented that scenario (note the "alwaysUseFullPath" property):
<bean id="annotationHandlerMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="order" value="2"/>
<property name="alwaysUseFullPath" value="true"/>
</bean>
Maybe someone can shed some light on this detail for me.
In any case, thanks danny.lesnik
I recreated your problem and solved it by mapping servlet using .action extentions.
For example:
#Controller
#RequestMapping(value="/test")
public class DefaultController {
#RequestMapping(value="/pdf.action", method=RequestMethod.GET)
public ModelAndView indexView(#RequestParam("taskId") String[] taskIds,
#RequestParam("token") String[] encryptedEmplId){
ModelAndView mv = new ModelAndView("index");
return mv;
}
Spring XML mapping:
<context:annotation-config />
<context:component-scan base-package="com.vanilla.controllers" />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
and this web.xml servlet mapping
<display-name>SpringMvcServlet</display-name>
<servlet>
<servlet-name>SpringMvcServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringMvcServlet</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
This code resolves this url
/test/pdf.action?token=3&token=4&taskId=4
flawless.
I have a webapp based on Spring 3.0.6 which works fine on Tomcat 7.0.
The web.xml defines the dispatcher as following:
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
The dispatcher defines the view resolver in the usual way:
<bean id="tilesViewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.tiles2.TilesView" />
</bean>
<bean id="tilesConfigurer"
class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/tiles-def.xml</value>
</list>
</property>
</bean>
I have a controller annotated with #RequestMapping("/home") and a "home" view defined in tiles-def.xml. When I point my browser to the /myapp/home.html, the Tiles page is opened.
If I add <mvc:resources mapping="/resources/**" location="/resources/" /> or <mvc:view-controller path="/" view-name="home.html"/> to my dispatcher xml file, pointing the browser to /myapp/home.html results in a 404. The log says:
21:34:22,128 WARN PageNotFound:947 – No mapping found for HTTP request with URI [/myapp/home.html] in DispatcherServlet with name 'dispatcher'
What am I doing wrong?
Thanks a lot
The problem in my application was due to the automatic view name resolution. My annotated method in my #Controller returned void, and the framework tried to guess the tiles view name using the request path.
I modified my annotated method as following, returning a String:
#RequestMapping(value="/page", method = RequestMethod.GET)
public String showForm(HttpServletRequest request, Model model) {
// TO BUSINESS LOGIC
// return tiles view name as configured in 'tiles-def.xml'
return "my_tiles_view_name";
}
With this change, everything works fine.