spring The request sent by the client was syntactically incorrect() issue - spring

I am getting exception mentioned in subject line. Could you please explain what is wrong:
package mvc;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
#Controller
#RequestMapping("/req")
public class Req {
#RequestMapping(method = RequestMethod.GET)
#ResponseBody
public String get(#RequestBody String body) {
return body;
}
}
SpringMVC-servlet.xml
<?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:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<!--It tells the Spring framework to look for annotations and then do appropriate dependency injections.-->
<context:annotation-config/>
<!--used to provide base package to scan components-->
<context:component-scan base-package="mvc"/>
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
</mvc:message-converters>
</mvc:annotation-driven>
</beans>
When i tries to access http://localhost:8080/SpringMVC/req
HTTP Status 400 -
type Status report
message
description The request sent by the client was syntactically incorrect ().
Apache Tomcat/7.0.16
Kindly help me in figure out the cause of this issue.
Thanks,
Sandip

Change method to POST and send some data with HTTP POST so the (#RequestBody String body) binding works.
You could use SoapUi or HTTP Requester plugin for browsers to conveniently send HTTP POST.
Otherwise define method as:
#RequestMapping(method = RequestMethod.GET)
#ResponseBody
public String get() {
return "Some string";
}

Related

Spring MVC validation ignored

I have Spring MVC app on Tomcat. I'm trying to add validation in it.
For some reason my validation is ignored and not checked.
Here is my POJO
import org.hibernate.validator.constraints.Range;
public class Goal {
#Range(min = 1, max = 15)
private int minutes;
public int getMinutes() {
return minutes;
}
public void setMinutes(int minutes) {
this.minutes = minutes;
}
}
And controller
import org.springframework.validation.BindingResult;
import javax.validation.Valid;
#Controller
#SessionAttributes("goal")
public class GoalController {
#RequestMapping(value = "addGoal", method = RequestMethod.POST)
public String updGoal(#ModelAttribute("goal") #Valid Goal goal, BindingResult result) {
System.out.println(goal.getMinutes());
System.out.println(result.hasErrors());
if(result.hasErrors()) {
return "addGoal";
}
return "redirect:addMinutes.html";
}
}
But even if I try to put any negative values as "minutes" there no errors produced.
Added configuration
<?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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<mvc:annotation-driven/>
<context:component-scan base-package="com.xlab.ice.mvc.controller"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" />
<mvc:resources mapping="/pdfs/**" location="pdf"/>
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource" p:basename="messages"/>
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver" p:defaultLocale="en"/>
<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" p:paramName="lang"/>
</mvc:interceptors>
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" p:order="0"/>
</beans>
Can you please also confirm that you have a JSR 303 implementation in your classpath - say hibernate-validator jar files.
You need <mvc:annotation-driven /> to enable jsr-303 validation, This is needed for the #Valid annotation to actually do anything.
try adding <mvc:annotation-driven/> in servlet context XML if not done.
schemaLocation the mvc entry should contain these two:
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
Solution is simple.
Validation libraries must be placed into classpath.
DISCLAIMER : In the absence of complete relevant controller code and the suspicion that Validator library might be missing in classpath, here is a small test to just check the configuration. You can use this very quickly to find if all configurations are in place with just removing the session attribute part.
Let's give it a try. To simplify testing with a REST Client and also incomplete code I have not used SessionAttributes. Also there is Hibernate validator library on my runtime classpath. Also I have used ResponseBody annotation to let the Spring automatically convert the String to response text without making use of alternate view technology (like jsp).
import org.hibernate.validator.constraints.Range;
public class Goal {
#Range(min = 1, max = 15)
private int minutes;
public int getMinutes() {
return minutes;
}
public void setMinutes(int minutes) {
this.minutes = minutes;
}
}
Then my controller
#Controller
public class GoalController {
#RequestMapping(value = "/addGoal", method = RequestMethod.POST)
public #ResponseBody String updGoal(#ModelAttribute("goal") #Valid Goal goal, BindingResult result) {
System.out.println(goal.getMinutes());
System.out.println(result.hasErrors());
if(result.hasErrors()) {
return "Errors !";
}
return "No Errors !";
}
}
Hitting the application with a rest client on http://localhost:8080/testApp/addGoal with POST parameters as minutes=1 gives me response as No Errors ! while with minutes=-1 gives me Errors !

404 Error on using Spring AOP Logging

I was trying to add AOP logger to the existing Spring(v3.1.3) application. Below is the code for the same.
Application launches successfully and am able to login. But, once the flow reaches the Controller that's specified in the ApplicationLogger.java, am getting 404 error in the screen and unfortunately aint getting any error trace in the console. Not getting any clue.
Kindly help me out to find where i have gone wrong.
TIA,
Arun
SERVLET.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd" >
<context:annotation-config />
<mvc:annotation-driven />
<!-- Enables the caching through annotations -->
<cache:annotation-driven />
<aop:aspectj-autoproxy />
<bean id="appLogger"
class="com.pmc.crm.risk.util.ApplicationLogger" />
.
.
.
ApplicationLogger.java
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
#Aspect
public class ApplicationLogger
{
/**
* Log method entry.
*
* #param joinPoint
*/
#Before("execution(* com.pmc.crm.risk.mvc.controller.SearchController.loadParamSearch(..))")
public void logEntry(final JoinPoint joinPoint)
{
System.out.println("*--*-*-*-* LOG ENTRY -*-*-*");
log("Entering method " + joinPoint.getSignature().getName() + "...");
}
/**
* Log method exit.
*
* #param joinPoint
*/
#After("execution(* com.pmc.crm.risk.mvc.controller.SearchController.loadParamSearch(..))")
public void logExit(final JoinPoint joinPoint)
{
System.out.println("*--*-*-*-* LOG EXIT -*-*-*");
log("Exiting method " + joinPoint.getSignature().getName() + ".");
}
SEARCHCONTROLLER.java
package com.pmc.crm.risk.mvc.controller;
import ....
#Controller
public class SearchController extends AbstractPolicyController{
private static final Logger LOG = Logger.getLogger(SearchController.class);
#RequestMapping(value = "/loadParamSearch.htm", method = RequestMethod.GET)
public ModelAndView loadParamSearch(HttpServletRequest request, HttpServletResponse response,ModelMap model) throws Exception{
try
{
System.out.println("...");
}
.
.
AbstractPolicyController was actually implementing an interface and servlet couldnt inject a proxy for the same (Investigating on the reason.) On removing the 'implements interfaceName' it worked good. Anyone who know the reason may pls let me know.

#TestExecutionListeners is not present for class

I will try to test one of methods in my endpoint (spring 3.1, junit 4.11) Here are my codes:
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns: p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schem...ng-mvc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schem...-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schem...ontext-3.0.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schem...ring-cache.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="app.controller, app.samples" />
<context:annotation-config/>
<annotation-driven />
</beans>
and test class:
package app.tests;
import app.samples.TableEndpoint;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autow ired;
import org.springframework.test.context.ContextConfigurat ion;
import org.springframework.test.context.junit4.SpringJUni t4ClassRunner;
#ContextConfiguration(locations = {"classpath:/WEB-INF/applicationContext.xml"})
#RunWith(SpringJUnit4ClassRunner.class)
public class TableTest {
public TableTest() {
}
#Autowired
TableEndpoint tableEndpoint;
#Test
public void testTableEndpoint(){
String result = tableEndpoint.getDane().get(0);
String expResult = "Learn python in 7 days";
if(!result.equals(expResult)){
fail("not equals");
}
assertTrue(result.equals(expResult));
}
}
If I run test I have got :
org.springframework.test.context.TestContextManage r retrieveTestExecutionListeners<br>
INFO: #TestExecutionListeners is not present for class [class app.tests.TableTest]: using defaults.
I searched about it but didn't find some informations. Thanks for help!
You miss the TestExecutionListeners. Add this annotation to your class
#TestExecutionListeners( { DependencyInjectionTestExecutionListener.class })
#ContextConfiguration(locations = {"classpath:/WEB-INF/applicationContext.xml"})
#RunWith(SpringJUnit4ClassRunner.class)
public class TableTest {
...
}

Inject property to spring bean using annotation

As explained here and here it is quite clear how to do it but still can't seem to make it work.
I simply like to use the #Value annotation in order to inject a property to a spring bean. I created a basic spring MVC project with one controller and one bean.
Here is my application context:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util" xmlns:beans="http://www.springframework.org/schema/beans"
xsi:schemaLocation="
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsd
http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.1.xsd">
<!-- Root Context: defines shared resources visible to all other web components -->
<context:component-scan base-package="me.co.fatsecret" />
<!-- Properties -->
<bean id="props"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:fatProperties.properties" />
</bean>
</beans>
I have one bean called Configuration:
package me.co.fatsecret;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
#Component
public class Configuration {
/*--- Members ---*/
#Value("${api_key}")
protected String API_KEY;
#Value("${api_secret}")
protected String API_SECRET;
#Value("${api_url}")
protected String API_URL;
/*--- Constructors ---*/
public Configuration() {
}
/*--- Getters & Setters ---*/
public String getAPI_KEY() {
return API_KEY;
}
public void setAPI_KEY(String aPI_KEY) {
API_KEY = aPI_KEY;
}
public String getAPI_SECRET() {
return API_SECRET;
}
public void setAPI_SECRET(String aPI_SECRET) {
API_SECRET = aPI_SECRET;
}
public String getAPI_URL() {
return API_URL;
}
public void setAPI_URL(String aPI_URL) {
API_URL = aPI_URL;
}
}
Now I have only one controller, injected with this Configuration class and as I call this controller I see that the values in the Configuration class are not populated right.
My properties file is located under the resources folder (src/main/resources) and is a part of my classpath (done by default since this is a maven project). Here it is:
api_url=http://platform.fatsecret.com/js?
api_key=SomeKey
api_secret=SomeSecret
The file name is fatProperties.properties.
As I debug my server when calling the controller I see that the content of the Configuration class is:
${api_key}
${api_secret}
${api_url}
This is the actual value of the Strings, wich means that the vales from the properties file are not getting injected for some reason.
Am I missing something here?
UPDATE1: I replaced the PropertyPlaceholderConfigurer bean with:
<context:property-placeholder location="classpath:fatProperties.properties"/>
Getting the same result
Ok, got it!
I'm using a spring MVC project, which means I have a separated context for my web layer (the controllers). The "Configuration" bean which hods the properties using the #Value annotation is injected to a controller. My property-placeholder is defined within my root-context hence it cannot be seen from my controller. To resolve the issue I simply added the property-placeholder definition to my DispatcherServlet context and it works like a charm :)
Add this to your application context file:
<context:property-placeholder location="classpath:fatProperties.properties" />
Try
#Value("#{props['api_key']}")
private String apiKey;

Spring AnnotationHandlerMapping not working

I'm new to spring controllers using annotated controllers.
Here is my configuration
Bean definition
<bean
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
Controller
package learn.web.controller.annotation;
import javax.servlet.http.HttpServletRequest;
import learn.web.controller.BaseController;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
#Controller
public class FirstController extends BaseController {
#RequestMapping("/annotation/first.ftl")
public ModelAndView first(HttpServletRequest request) {
if(messageSource instanceof ReloadableResourceBundleMessageSource){
ReloadableResourceBundleMessageSource m = (ReloadableResourceBundleMessageSource) messageSource;
m.clearCache();
}
messageSource.getMessage("learn.message.first", new Object[] {},
localResolver.resolveLocale(request));
return new ModelAndView("/annotation/first");
}
}
When tried to access the given URL Spring is throwing a warning org.springframework.web.servlet.PageNotFound - No mapping found for HTTP request with URI [/Learn/annotation/first.ftl] in DispatcherServlet with name 'springapp'
I think what you are missing is the component scan
<context:component-scan base-package="learn.web.controller" />
Add this to your configuration and try.
This will load all annotated components from the specified package
Your configuration may look like this
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:component-scan base-package="learn.web.controller" />
<bean
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
</beans>

Resources