How Do You Configure Spring MVC #PathVariables to Accept Strings Containing Dashes? - java

Given the following request mapping on a Spring MVC controller:
#RequestMapping(method=GET, value="/users/{name}")
ModelAndView findUser(#PathVariable String name) {
...
}
How can I make it accept a #PathVariable with a dash in it?
The following works, passing in fred as the name:
GET /users/fred
However the following does not work, passing in null in place of the name:
GET /users/u-fred
I would appreciate suggestions on how to define the #PathVariable so it can accept dashed strings, for example, u-fred.
Thanks.

I just tested that with my spring-mvc 3.0.5 application and it works fine with a dash:
make sure you are running the latest version
make sure you are tracking the correct request (and not some fake one, for example a forgotten ajax request)

Related

Spring Security SAML: Extract Attributes from a saml2p:Response as user attributes

I have been digging into spring security yaml a little bit yesterday to make it work with Okta SAML. Logging in works, but the response XML contains user attributes that apparently cannot be extracted automatically into an attribute map. The response contains a fields like this
<saml2:Attribute Name="user.lastName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
<saml2:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">
Surname
</saml2:AttributeValue>
</saml2:Attribute>
Once an authentication is successful, I would like to put those in the authentication information. When logging in via github/oauth, the OAuth2AuthenticatedPrincipal class has an attributes map, however the Saml2AuthenticatedPrincipal only features a name.
What would be the correct way to solve this?
Right now I am thinking of a custom AuthenticationSuccessHandler that populates a custom Saml2AuthenticatedPrincipalWithAttributes class which contains all the attributes by parsing the provided XML response (via .getDetails()) a second time (or put them into the session).
I have a hunch that this is probably not the spring way to do things and would love to get a second opinion. When googling around you mainly find examples of spring security saml, before it got merged into spring security, which seems to handle things a little bit different, as the mentioned classes do not exist anymore.
Thanks for helping everyone!
In the next release of Spring Security (5.4.0) you should be able to do something like this:
#GetMapping("/")
public String index(Model model,
#AuthenticationPrincipal Saml2AuthenticatedPrincipal principal) {
String emailAddress = principal.getFirstAttribute("emailAddress");
model.addAttribute("emailAddress", emailAddress);
model.addAttribute("userAttributes", principal.getAttributes());
return "index";
}
For now, I don't know a better workaround than yours.

Dynamic URL from database and MVC in JSP

I am learning JAVA and Spring Framework. I wanted to know that is it possible in java to create Dynamic URL in spring framework using values from url and fetching from database.
I am trying to make URL Shortner in Java and I will need to lookup for url's short code in my database and as we all know, url shortner will look like "url/ShorTCode" and my script will look for "ShorTCode" keyword in database and will redirect to associated weblink.
So I wanted to know that is it even possible in JAVA and Spring? And one more thing, if I make something like this "url/yt/VIdeoCode" or "url/fb/UserProfile"
So it will look at yt object which will redirect to youtube link only and fb object which will redirect to facebook user profile.
I want to clarify that I am still learning JAVA, JSP and Spring but I want to keep this thing in my mind while I am learning so I can focus on some particular things.
Thank you all fro helping me.
If you're asking how your controller could respond with a dynamic redirect, the answer is either:
(1) Have the controller return a "redirect:" result instead of view name. It must be followed with an absolute url, and behavior might depend on your spring version and configuration, but basically it looks like this:
#RequestMapping(...)
public String myMethod(){
String url=... // database lookup, e.g. "http://myUrl"
return "redirect:"+url;
}
(2) Less elegant but sometimes useful: get direct access to the response. If your controller method has a parameter of type HttpServletResponse spring will automatically inject it. So:
#RequestMapping(...)
public String myMethod(HttpServletResponse resp){
...
response.sendRedirect(...)
}

Handling special characters in post parameters for Spring-mvc

I have an application using spring-mvc 3.0.
The controllers are configured like this:
#RequestMapping(value = "/update", method = RequestMethod.POST)
public ModelAndView updateValues(
#RequestParam("einvoiceId") String id){
...}
When posting an id that contains special characters (in this case pipe |), url-encoded with UTF-8 (id=000025D26A01%7C2014174) the string id will contain %7C. I was expecting spring-mvc to url decode the parameter. I am aware that I can solve this by using
java.net.URLDecoder.decode()
but since I have a large number of controllers, I would like this to be done automatically by the framework.
I have configured the Tomcat connector with URIEncoding="UTF-8" and configured a CharacterEncodingFilter, but as I understand it this will only affect GET requests.
Any ideas on how I can make spring-mvc url decode my post parameters?
http://wiki.apache.org/tomcat/FAQ/CharacterEncoding#Q3
This page says CharacterEncodingFilter can change POST parameters
I believe you encounter the same issue as I did.
Try using #PathVariable instead #RequestParam.
#PathVariable is to obtain some placeholder from the uri (Spring call it an URI Template) — see Spring Reference Chapter 16.3.2.2 URI Template Patterns
If you do, you have to change your url and don't provide parameter 'id'.
Just "/update/000025D26A01%7C2014174".
More information can be found where I found the solution for my problem #RequestParam vs #PathVariable

form:errors not displaying errors on JSP in Spring

I want to create simple form which will display errors if input is not proper means if validation fails. I am using spring 3.0 annotations.
I did following things
1 : Created JSP
2 : Created Controller
3 : Created DTO
4 : Created org.springframework.validation.Validator
(write an implementation the necessary methods)
int error = bindingResult.getErrorCount() returning the error count and even my page is not being submitted which is expected but my JSP is not showing error messages
I have write on JSP.
Please guide me how to do this.
If i miss on something please let me know i will paste it.
Have a look at this answer for the structure of the controller. The important think is to have a paramter BindingResult and if this binding result contains an error you must return the same view (not redirect) again.
In the jsp code you can use the spring errors tag.
#see Spring Reference chapter 16.2.4.14 The errors tag -- there is an example
I have solved this i have just mentioned dto object name in #ModelAttribute
public void myMethod(#Valid #ModelAttribute**("myDto")** MyDTO myDTO,
BindingResult bindingResult, ActionResponse response,
SessionStatus sessionStatus)

Using #RequestBody and #ModelAttribute together?

I'm trying to get at the body of a POST, and I'd like the parameters of my method to bind to an object.
Is this possible?
My current declaration doesn't ever get hit:
#RequestMapping(method = RequestMethod.POST)
public void doStuff(#RequestBody byte[] bodyData, #ModelAttribute Form form, Model model ) {
Looks like I'm getting this exception:
- 2011-02-25 16:57:30,354 - ERROR - http-8080-3 - org.springframework.web.portle
t.DispatcherPortlet - Could not complete request
java.lang.UnsupportedOperationException: #RequestBody not supported
For this to work correctly, you have to be sure you're using AnnotationMethodHandlerAdapter. This overrides HandlerMethodInvoker's createHttpInputMessage (which is throwing the exception you're seeing). (It does this in a private class.)
I believe you can just include the following in your *-servlet.xml
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
WARNING: The below answer is for the case of needing #RequestBody and #RequestParam in the same handler method. It does not answer this question, but could be of use to someone.
I've tested this out using Spring 3.0.1. This is possible, but it's somewhat precarious. You MUST have your #RequestBody method argument before your #RequestParam argument. I'm guessing this is because HandlerMethodInvoker reads the request body (along with the GET parameters) when retrieving parameters (and the request body can only be read once).
Here's an example (WARNING: I code in Scala, so I've not compiled this Java code)
#RequestMapping(value = "/test", method = RequestMethod.POST)
public String test(
#RequestBody String body,
#RequestParam("param1") String parma1,
Map<Object, Object> model: Map[AnyRef, AnyRef])
{
model.put("test", test)
model.put("body", body)
return "Layout"
}
An alternative is to use #PathVariable. I've confirmed that this works.
Unfortunately that is kind of impossible. If you are using portlet version of Spring MVC (and it looks like from the logs) then you might be interested in this JIRA issue.
AnnotationMethodHandlerAdapter uses PortletHandlerMethodInvoker internally and the second is a inner subclass of HandlerMethodInvoker - the place where you can configure HttpMessageConverter-s. But they're set to null. And the property is final.
That even would be to workaround if you could substitute HandlerMethodInvoker, but you can not.. it's constructor-created ;)
One thing to notice is that Servlet version of Spring MVC fully supports HttpMessageConverter-s and does not suffer this issue.

Categories