everybody,
I am testing using spock in Grails for certain methods that need a CommonMultipartFile as input parameters.
My problem is how to create these files so that no local ones are generated. Some of them must use a request.getFile and so I thought I would use the MockMultipartFile class in all these methods.
The problem is that it tells me that you can't cast from MockMultipartFile to CommonsMultipartFile at the following casting:
CommonsMultipartFile commonsMultipartFile = (CommonsMultipartFile) request.getFile("filecsv")
Does anyone know how to do such a casting?
P.S.: Prior to this I have only done the following:
MultipartFile multipartFile = new MockMultipartFile("filecsv","filecsv", "")
request.addFile(multipartFile)
You did not mention that you are using types from Spring, I had to do a web search first. Don't keep people trying to help you guessing. Instead, please explain or at least tag the question accordingly (I just did that for you).
You cannot cast incompatible types. Both CommonsMultipartFile and MockMultipartFile directly extend Object and implement the MultipartFile and InputStreamSource interfaces. So you can only cast to something they have in common, i.e. one of those interfaces.
BTW, I have never used Grails, but its API seems to have a GrailsMockMultipartFile which extends the Spring MockMultipartFile and provides an implementation of transferTo that doesn't use the file system.
Related
I've a service called InformationService. It optionally depends on ReleaseService. If the property external.releaseservice.url is set, the InformationService shall make a request to it and enrich it's own response with aggregate data.
If however the url is not defined, the response shall simply return a string like not available for the fields in question.
What's the spring boot way to achieve this? Inject an Optional<ReleaseService> into the InformationService? Is there another pattern for this?
You have three ways to achieve this.
#Autowired(required = false)
This works, but it requires field injection, which is not great for unit tests as is well known.
#Autowired(required = false)
private ReleaseService releaseService;
Java Optional type
As you said, Optional will also do the job and it allows you to stick to constructor injection. This is my suggested approach.
Spring's ObjectProvider
There is also an ObjectProvider designed specifically for injection points which you can use to achieve this as follows.
public InformationService(ObjectProvider<ReleaseService> releaseServiceProvider) {
this.releaseService = releaseServiceProvider.getIfAvailable();
}
It is more cumbersome and therefore I would avoid it. There is an advantage that allows you to specify a default instance if none is available but I guess that is not what you need.
With reference to my previous linked in question I'm bit confused with the usability of #JsonAutoDetect.
I solved the problem by adding #Getter to FieldValues class and removed the #JsonAutoDetect.
So now it let me thinking, what would be the scenario where #JsonAutoDetect can be used, as I can achieve the same result without having it. What is the purpose of having #JsonAutoDetact annotation over having getter methods. Am I missing something.
Not able to write any comment for previous question so created a new one.
Here is an article that I think can help you. The url is https://www.baeldung.com/jackson-jsonmappingexception .
At my point, if you use jackson-databind jar, spring underlying use ObjectMapper to serialize JavaBean. If neither javaBean's field nor getter method is public, spring could not serialize JavaBean automaticlly. Annotation #JsonAutoDetect is used to custom your javaBean, by which way you can set field limits to any level (e.g. protected public private... so that you can serialize the javaBean successfully).
If I don't understand wrong, the #Getter is from lombok that automaticlly help you generate public getter method.
I have a Controller with the following method:
#RequestMapping(method = POST)
public ModelAndView emailRegister(EmailParameter parameters, ModelMap model) {}
Where EmailParameter is an interface. I understand Spring (magically?) maps the incoming HTTP parameters to my object fields by name, and it can't do this as I have declared an Interface.
Is it possible to declare an interface here, if so is there additional config I need somewhere?
I don't have extensive programming experience so I may be wrong in trying to use an Interface type here, but I believe this is what I should be doing?
Additionally if someone could explain how Spring maps the request parameters to my object fields, that would be much appreciated. Or a link to where this is explained, as I haven't been able to find one!
Thanks
You shouldn't use Interface because Spring needs to instantiate that object, otherwise you will be requiring the property editors OR converters.
Read the following post to know about How Spring MVC Binds Parameter?
Read section "Binding Domain Object" in following link.
https://web.archive.org/web/20160516151809/http://www.jpalace.org/document/92/binding-and-validation-of-handler-parameters-in-spring-mvc-controllers
Scenario: I have a web application that uses Spring 3 MVC. Using the powerful new annotations in Spring 3 (#Controller, #ResponseBody etc), I have written some domain objects with #XML annotations for marhalling ajax calls to web clients. Everything works great. I declared my Controller class to have a return type #ResponseBody with root XML object - the payload gets marshalled correctly and sent to Client.
The problem is that some data in the content is breaking the XML compliance. I need to wrap this with CDATA when necessary. I saw a POST here How to generate CDATA block using JAXB? that recommends using a custom Content Handler. Ok, fantastic!
public class CDataContentHandler extends (SAXHandler|XMLSerializer|Other...) {
// see http://www.w3.org/TR/xml/#syntax
private static final Pattern XML_CHARS = Pattern.compile("[<>&]");
public void characters(char[] ch, int start, int length) throws SAXException {
boolean useCData = XML_CHARS.matcher(new String(c,start,length)).find();
if (useCData) super.startCDATA();
super.characters(ch, start, length);
if (useCData) super.endCDATA();
}
}
Using Spring MVC 3, how do I achieve this? Everything was "auto-magically" done for me with regards to the JAXB aspects of setup, Spring read the return type of the method, saw the annotations of the return type and picked up JAXB2 off the classpath to do the marshalling (Object to XML conversion). So where on earth is the "hook" that permits a user to register a custom Content Handler to the config?
Using EclipseLink JAXB implementation it is as easy as adding #XmlCDATA to the Object attribute concerned. Is there some smart way Spring can help out here / abstract this problem away into a minor configuration detail?
I know Spring isn't tied to any particular implementation but for the sake of this question, please can we assume I am using whatever the default implementation is. I tried the Docs here http://static.springsource.org/spring-ws/site/reference/html/oxm.html but it barely helped at all with this question from what I could understand.
Thanks all for any replies, be really appreciated.
Update:
Thanks for the suggested answer below Akshay. It was sufficient to put me on right tracks. Investigating further, I see there is a bit of history with this one between Spring version 3.05 and 3.2. In Spring 3.05 it used to be quite difficult to register a custom MessageConverter (this is really the goal here).
This conversation pretty much explains the thinking behind the development changes requested:
https://jira.springsource.org/browse/SPR-7504
Here is a link to the typically required class override to build a cusom solution:
http://static.springsource.org/spring/docs/3.1.0.M1/javadoc-api/org/springframework/http/converter/AbstractHttpMessageConverter.html
And the following Question on stack overflow is very similar to what I was asking for (except the #ResponseBody discussion relates to JSON and jackson) - the goal is basically the same.
Spring 3.2 and Jackson 2: add custom object mapper
So it looks like usage of , and overriding MarshallingHttpMessageConverter is needed, registering to AnnotationMethodHandlerAdapter. There is a recommended solution in link above to also get clever with this stuff and wrap the whole thing behind a custom defined Annotation.
I haven't yet developed a working solution but since I asked the questions, wanted to at least post something that may help others with the same sort of question, to get started. With all due respect, although this has all improved in Spring 3.2, it's still bit of a dogs dinner to get a little customization working... I really was expecting a one liner config change etc.
Rather than twist and bend Spring, perhaps the easiest answer for my particular issue is just to change JAXB2 implementation and use something like Eclipse Link JAXB that can do this out of the box.
Basically you need to create a custom HttpMessageConverter. Instead of relying on the Jaxb2RootElementHttpMessageConverter that spring uses by default.
Unfortunately, customizing one converter means you are telling spring that you will take care of loading all the converters you need! Which is fairly involved and can get complicated, based on whether you use annotations, component scanning, Spring 3.1 or earlier, etc.. The issue of how to add a custom converter is addressed here: Custom HttpMessageConverter with #ResponseBody to do Json things
In your custom message converter you are free to use any custom JAXB2 content handlers.
Another, simpler approach to solve your original problem would be to use a custom XmlJavaTypeAdapter. Create a custom implementation of javax.xml.bind.annotation.adapters.XmlAdapter to handle CDATA, in the marshal method wrap the return value with the cdata braces. Then in your mapped pojo, use the XmlAdapter annotation, pass it the class of your custom adapter and you should be done.
I have not myself implemented the adapter approach, so couldn't provide sample code. But it should work, and won't be a lot of work.
Hope this helps.
Posted in spring forum with no response.
I have the following code snippet (from here), which is part of my pet project.
#Controller
#RequestMapping("/browse")
public class MediaBrowser {
...
#RequestMapping("/**")
public final ModelAndView listContents(final HttpServletRequest request) {
String folder = (String) request.getAttribute(
HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
...
}
I access the following url:
http://localhost:8080/myapp/browse
In spring 3.0.6.RELEASE, I got the folder variable as null, which is the expected value.
In spring 3.1.RC1, the folder variable is /browse.
Is this a bug or has something changed in spring-3.1?
As skaffman said, you probably shouldn't use PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE. Take a look at How to match a Spring #RequestMapping having a #pathVariable containing "/"? for an example of using AntPathMatcher to accomplish what you are trying
This looks very much like an internal implementation detail of the framework, one that you should not be relying on.
The javadoc for PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE says:
Note: This attribute is not required to be supported by all HandlerMapping implementations. URL-based HandlerMappings will typically support it, but handlers should not necessarily expect this request attribute to be present in all scenarios.
I wouldn't be surprised if the behaviour changed slightly between 3.0 and 3.1.