Spring MVC is dropping a #PathVariable - spring-mvc

If I hit the controller multiple times and hammer it, occasionally my modelCode parameter comes through as null. However the URL has the modelCode in it.
Using Spring Framework 3.0.5.RELEASE
#RequestMapping(value="ws/getallvariants/{channelCode}/{modelCode}/{regionId}/{year}")
public ModelAndView getAllVariants(#PathVariable("channelCode") String channelCode,
#PathVariable("modelCode") String modelCode,#PathVariable("regionId") String regionId,#PathVariable("year") String year){
if (modelCode == null)
{
int i = 0; // this should never hit, but does.
}

Yes, RegEx was the most reliable for me as well. Did this to grab an email address as a parameter:
#RequestMapping(value = "rest/userreadserv/search/{email:.+}", method = RequestMethod.GET)
public ResponseEntity getUserAccountByEmail(#PathVariable String email) {...}

Take a look at Spring MVC #PathVariable getting truncated . The regex approach worked for me:
#RequestMapping({ "/servers/{serverName:.+}" })

Updating the spring framework again to the latest version appears to have worked. Apparently when we updated our framework something didn't work correctly.
EDIT:
So this wasn't our issue at all... We had implemented a String Trimmer Editor incorrectly and it was keeping state. So when we put the call under load it would cross results.

//in your xml dispatcher add this property to your default annotation mapper bean as follow
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
<property name="alwaysUseFullPath" value="true"></property>
</bean>

Related

provide query string request mapping variable at class level

I am trying to make spring boot application & swagger. Application is for REST service provide. I have made application running each page.
I have made a simple controller that have RequestMapping("/group/user/contact").
Which is working fine.
I am trying to do something like RequestMapping("/group/{type}/contact") at class level.
So my question is that is it possible ?
If yes then just want some basic guidance. and if no then fine.
My all request working fine. All request came from CORS filter class.
You can do this, the handler method should look something like
#Controller
#RequestMapping("/group/{type}/contact")
public class ClassLevelPathVariableController {
#ResponseBody
#RequestMapping(method = RequestMethod.GET)
public String classLevelMapping(#PathVariable String type) {
return type;
}
}
In this setup a GET request like e.g. /group/test/contact would be handled by the classLevelMapping method and the type variable will be populated with the value "test"

How to pass single parameter to contoller in Spring MVC?

I have some questions from a design point of view in Spring Web MVC.
Is it good practice to use Request Object in controller? If not, then what is alternative way to pass pass one text fields value to controller? Do I need to create one new from bean for this single fields?
It depends of the situation, in a few cases I used the HttpServletRequest; for example for writing a file to the output stream.
If you want to get the Request Parameters you can use the annotation #RequestParam, that it´s more easy to get the parameters from the request.
Depends that you want to handle, for example for a form you can use #ModelAttribute and this attribute can be in a session or in the request.
For example:
#Controller
public class YourController {
#RequestMapping(value = "someUrl", method = RequestMethod.GET)
public String someMethod(#RequestParam("someProperty") String myProperty)
{
// ... do some stuff
}
}
Check the documentation here:
#RequestParam
#ModelAttribute
#PathVariable

ASP.NET WebService test form

Is it possible to configure default ASP.NET WebService test form to support JSON?
I mean the test form that built in in .NET framework...
Currently I have a WebService that decorated with [ScriptService], but when I testing it using built in test form page, it returns XML...I assume, this happens because test page sends Content-Type XML by default.
Thanks
EDIT (Example):
I have class:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
Now I have ASP.NET WebService:
[ScriptService]
public class PersonService : WebService
{
[WebMethod]
public Person GetDave()
{
Person dave = new Person();
dave.FirstName = "Dave";
dave.LastName = "Test";
return dave;
}
}
When I call this WebService from web page using jQuery AJAX, I receive JSON Person object {"FirstName":"Dave","LastName":"Test"} (not string) in JavaScript, but when I invoking this WebService from ASP.NET WebService Test Form (When I right click on ASMX file and use "Preview In Browser"),
It returns:
<?xml version="1.0" encoding="utf-8" ?>
<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://tempuri.org/">
<FirstName>Dave</FirstName>
<LastName>Test</LastName>
</Person>
What want, is when I invoke the service from test page, to see the same output:
{"FirstName":"Dave","LastName":"Test"}
You can use the code below
[WebMethod(Description = "Some Description")]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public string FunctionName()
{
// Return JSON data
JavaScriptSerializer js = new JavaScriptSerializer();
string retJSON = js.Serialize(Object);
return retJSON;
}
And also you need to add the reference.
Update
Here is the link which will explain about extending an existing ASP.NET Web Service to support JSON
Hope that helps
It looks like I found a solution...it still not complete solution, but this is the way to go :)
In [Drive]:\[WindowsDir]\Microsoft.NET\Framework\[Version]\CONFIG folder, exists the file named DefaultWsdlHelpGenerator.aspx. This file contains the whole code needed to automatically generate test page using WSDL. Now I can use this code to write my own test page and make requests using jQuery and not using HTML form...then I can put in config file and this should work.
<webServices>
<wsdlHelpGenerator href="WSTestPage.aspx"/>
</webServices>
Maybe somewhere exists more simple/ready way to do it, but I still not found it...
Add following references first
using System.Web.Script.Services;
using System.Web.Script.Serialization;
use the below code in your method, for converting any data into JSON Data format in end
JavaScriptSerializer serializer = new JavaScriptSerializer();
return serializer.Serialize(dr);
dr is array of DataRows from DataTable.Hope this will help You.

Spring MVC handler returns String with extra quotes

I'm using Spring 3.1 and I have a handler that should return a String value.
Here's how my handler looks like:
#RequestMapping(value = TEST_HANDLER_PATH, method = RequestMethod.POST)
public ResponseEntity<String> handleTest(HttpServletRequest request,
#RequestParam("parma1") String param) throws Exception {
String ret = ...
...
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "text/plain;charset=utf-8");
return new ResponseEntity<String>(ret, headers, HttpStatus.CREATED);
}
I also tried annotating method with #ResponseBody with return ret; at the end.
In both cases, when I hit the service, I get extra quotes around String value (e.g. "This is a test").
I'm guessing this is due to message conversion. That's why I tried defining Content-Type header, to hit StringHttpMessageConverter explicitly, to no avail.
Had the same problem.
Just make sure you register a org.springframework.http.converter.StringHttpMessageConverter as well as your Jackson one so that Strings are treated literally and not attempted to be converted to JSON (with extra quotes).
Just instantiate with default constructor or constructor with your preferred Charset. The media types should be set for you with the standard internal defaults. If you're configuring via code extending WebMvcConfigurerAdapter then you just add the converters in the configureMessageConverters(List<HttpMessageConverter<?>> converters) method.
In my case, I had over-engineered =)
Had introduced a converter for bean's toString Operations like this:
class SerializableToString implements Converter<Serializable, String>
restricting that (only to my beans), resolved the issue X)
Note: debugging with a breakpoint # org.springframework.core.convert.support.GenericConversionService.getConverter helped.
In a related scenario, I had an IntegrationFlow for a GET that incorrectly requested a transform. Basically the target service would receive the #PathVariable as a quote escaped string
return IntegrationFlows.from("getThing")
.transform(Transformers.toJson())
.handle(
The .transform(Transformers.toJson()) was forcing the strings to be escaped in the URI, so simply removing it - it shouldn't have been there - fixed the issue.
Turns out there was a JSON message converter registered in one of the imports.

How to handle SizeLimitExceededException from CommonsMultipartResolver in Spring WebFlow?

I have the following situation. I have a CommonsMultipartResolver bean configured the following way.
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="2100000" />
And I have a few file upload fields in a Spring Web Flow view state jsp.
Everything works fine if the file is under the limit, but if the file exceeds the limit of 2MB-s I have to add a validation error to the binding result on my form.
My problem is that the multipart file resolver throws a org.apache.commons.fileupload.FileUploadBase.SizeL imitExceededException exception when the file limit is exceeded and I can't find a way to catch this in Spring Web Flow and add my FieldError to the form.
I tried using the on-exception attribute of the transition tag, but if I understand correctly it only works for exceptions that are thrown within Spring Web Flow.
I've also tried to use SimpleMappingExceptionResolver in spring mvc, but I do not want to redirect to a page, I want to handle this exception.
I also found this: https://jira.springsource.org/browse/SWF-158
But it's from version 1.0 and I'm assuming that this has been incorporated since or that a better way was found to handle these situations.
Any ideas on how to deal with this would be greatly appreciated.
Thanks.
In your SimpleMappingExceptionResolver you should be able to override the resolveException method, determine the exception type being caught and handle appropriately.
I've found some old code in our project that seems to be a solution to a similar exception;
public class GeneralMappingExceptionResolver extends SimpleMappingExceptionResolver {
#Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception) {
if(exception instanceof MaxUploadSizeExceededException) {
MaxUploadSizeExceededException maxe = (MaxUploadSizeExceededException)exception;
String errorMessage = "Max filesize exceeded, please ensure filesize is too large.");
HashMap<String, Object> model = new HashMap<String, Object>(2);
model.put("errorMessage", errorMessage);
return new ModelAndView("verification/psv/consent", model);
} else {
return super.resolveException(request, response, handler, exception); // Do whatever default behaviour is (ie throw to error page).
}
}
Note that the "verification/psv/consent" is the flow where this exception would have been thrown from and where it needs to return to. We only have the one page that has a file upload.
Obviously the errorMessage is just a parameter passed into the view so will need to be handled and displayed like an error message. You may also need to re-populate any other form fields that were submitted. Hopefully this is a point in the right direction though.

Resources