Spring 5 - How to get path variables from ServerHttpRequest object? - spring

Hi I would like to get a path variable from the ServerHttpRequest object - what's the easiest way to do it ?

Related

URI within endpoint

I have a URI string inside the request that I am supposed to make. How to extract it and write a proper controller.
markerURI = marker://markerType/markerValue
Request:
POST /books/123/markers/marker://big/yellow
I have written below rest controller for the above request:
#PostMapping("/books/{id}/markers/{markerURI:^marker.*}")
public void assignMarker(
#PathVariable("id") String id,
#PathVariable("markerURI") String markerURI
)
but i'm not able to get markerURI=marker://big/yellow inside markerURI variable. The request show 404 Not found error. Is there any way to do this. It's a requirement so can't do any hacks.
Edit:
markerURI can contain attributes like marker://markerType/markerValue?attr1=val1&attr2=val2
As per https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-requestmapping-uri-templates
You can have your url pattern in below pattern
"/resources/ima?e.png" - match one character in a path segment
"/resources/*.png" - match zero or more characters in a path segment
"/resources/**" - match multiple path segments
"/projects/{project}/versions" - match a path segment and capture it as a variable
"/projects/{project:[a-z]+}/versions" - match and capture a variable with a regex
but your url pattern is defined as a url inside a url, for that I suggest you to use below method and concatenate your result after fetching the values from uri as pathvariable.
#PostMapping("/books/{id}/markers/{marker:[a-z]+}://{markerType:[a-z]+}/{markerValue:[a-z]+}")
public void assignMarker(#PathVariable("id") String id,#PathVariable("marker") String marker,
#PathVariable("markerType") String markerType,
#PathVariable("markerValue") String markerValue) {
String markerUri = "/"+marker+"://"+markerType+"/"+markerValue;
System.out.println(markerUri);
}

Spring boot request mapping

I have following request parameters.
a
b
c
d
e
f
Request can contain all the parameters or some of them. I am currently using regex /** to resolve this.
Is there any way to explicitly mention the request mapping instead ** and say it is optional. And any order also should match.
/a/1/b/f2
and
/b/f2/a/1
Both should match that mapping.
There is no way to achieve this via #PathVariable's. If you want the flexibility of random order & number of path variables. You can just do the following;
#GetMapping("/myEndpoint/**")
public void theEndpoint(HttpServletRequest request) {
String requestURI = request.getRequestURI();
Stream.of(requestURI.split("myEndpoint/")[1].split("/")).forEach(System.out::println);
}
You can put a .filter(StringUtils::isNotBlank) in case /myEndpoint/a///b/c
Will give you
a
1
b
f2
d
x
when you call /myEndpoint/a/1/b/f2/d/x
b
f2
1
when you call /myEndpoint/b/f2/1
Also, be aware that you'd need some anchor base in your endpoint, e.g. /myEndpoint. Otherwise all your other endpoints will be conflicted with this endpoint.
ps. Better to use request params for such inputs tbh, not sure your requirement here, but just FYI. It is not the best to have such a hacky structure really...
You can make a RequestParam optional by adding the required flag false.
#RequestParam(value = "a", required=false)
For PathVariables i would try to use the Optional type but i have never done this before.
#PathVariable Optional<String> a for /path/{a}

How to serialize empty string to selfclosing tag

Using JMS Serializer
I need to get self closing tag setting empty string
<logout/>
I always get
<logout></logout>
I can't use
->setSerializeNull(true)
because the class I'm serializing has many properties that if they are null they can't be serialized
Any idea how to get it done ?

Spring mvc it, compare payload and header values

We have some intergation tests over #RestController with a common pattern to verify that an Xpath expression exists and that an Http header is set. But I would like to go further and verify that the XPath value is equald or contained into the header.
mvc.perform(..)
.andExpect(xpath("Item/#id/").isIn(header("Location")))
Is it something for that or should I create my own ResultMatcher ?
org.springframework.test.web.servlet.result.MockMvcResultMatchers.xpath(xpathExpress, args) is what you want.
For example:
ResultActions resultActions = mvc.perform(..);
String location = resultActions.andReturn().getResponse().getHeader("Location");
resultActions.andExpect(MockMvcResultMatchers.xpath("Item/#id/", null)
.string(org.hamcrest.Matchers.containsString(location)));
If you need to compare by Node, XMLUnit for Java 2.x offers more usefule Matcher.

how to set the message attribute of the exception variable in Ruby?

I have an Exception type variable in Ruby. How can I set the value of attribute "message" of the exception variable?
Is there any method to set the attribute (like rb_attr_set()..)?
I got the answer for above question myself. We can set the "message" attribute of Exception object as follows:
rb_iv_set(*objeException, "mesg", current);
whereas current in VALUE type variable in which ruby string is stored..

Resources