Spring mvc - get data from other server, what object to use and how to reuse it? - spring

I have some url that I need to read data from there and use it in my controller.
Usually in java application I use http client, to get data from some url.
My questions are:
What object to use in spring mvc to get data from some url (like http client) ?
How to reuse this objects, so every time not to create it ?
Thank you!

In agreement with the comment by #Evgeny and #Beau above, you can use any client library you like. HttpClient is VERY bean friendly and, for cases where it might be difficult to construct the configuration, you can always provide a Spring factory bean to construct the object.
If you are looking to abstract away the plumbing of the HttpClient API usage, utilize the RestTemplate suggested by #Evgeny (I believe that it is also his brainchild) It is a VERY rich and simple API to leverage.

Related

Spring: `RequestScope` vs `RequestContextHolder`

I am writing a Spring Boot service and wanted to include some form of RequestContext available to the controllers that might store things like the authenticated user and a request id. However, I see multiple approaches:
Use an #RequestScope bean
Use ServletRequest.setAttribute
Use Spring RequestContextHolder
What are the tradeoffs between these approaches?
Broadly speaking, RequestScope is the Spring magic way. It internally uses a RequestContextHolder which in turn depends on ServletRequest.setAttribute.
Said differently, the Spring way, is IMHO RequestScope. RequestContextHolder makes sense if you prefer limit the magic of Spring annotations.
Finaly, ServletRequest.setAttribute is still lower level, and should mainly be used if you want the code to be compatible with a non Spring application.
Moreover, for the first two ways, Spring uses a thread scoped object to store a reference to the request context, which allows the programmer to access the beans even in methods that do not explicitely receive the Request object.

spring rest doc - service layer mocking

recently i saw the blog post say that "for documentation purpose, we use mocking for service layer (in environment using spring rest doc)", so this post use annotation like spring's #MockBean to service layer object.
but i think, if i mock service layer -> spring rest doc always success to test because mocked service object always return intended result and spring rest doc test always receives same intended result from mocked service object.
so i think that is not right but,
i want to know about what is better or how you use service object with spring rest doc
pleas answer
Whether or not it's a good idea to mock the service layer when using Spring REST Docs is largely down to personal preference.
A possible disadvantage of mocking the service layer is that it may be possible for the documentation to get out of sync with the service's actual behaviour. This undermines REST Docs' ability to help you to keep your documentation and service in sync.
An advantage of mocking the service layer is that it can make it easier to document error scenarios or scenarios that would otherwise require quite a lot of setup. In the case of errors, I think you are better adopting a common approach across your whole API and making consistent use of standard HTTP error codes. If you do this, the need to document error responses for each endpoint in a service is reduced.
This leaves documenting more complex scenarios that require a lot of setup. In this case, limited use of mocks may be worthwhile but I would still aim to produce as much of your documentation as possible without relying on mocks.

File upload with SPQR Graphql

I'm using spring boot and spqr graphql library. I need to upload a file(s) via graphql. I don't know what object type to expect in the service and I'm assuming that this isn't even supported.
Has anyone tried this? Any advice?
Thanks.
(Assuming you're using SPQR Spring Starter)
Uploading/downloading binaries is currently inconvenient in SPQR, but not impossible. You'd need to override the provided controller with your own and decide how you want to receive the queries and binaries, and how you want to send the results and binaries back. To override the controller, just provide your own bean of GraphQLController type.
Your best bet is implementing the GraphQL multipart request spec which thanks to Spring shouldn't be too complicated.
Btw you can always get to the raw request by injecting #GraphQLRootContext DefaultGlobalContext<NativeWebRequest> request as a method argument. From there you can obtain input and output streams.
You can also wire in a custom ArgumentInjector that can inject something more precise if you want.
In the near future, the starter will support the GraphQL multipart request spec out of the box.
If you're not using the starter, the situation is similar in that you're kind of on your own with implementing the transport for binaries and queries.
But, with all that said, it is generally a best practice to handle dealing with binaries outside of GraphQL completely (only send download URLs and such using GraphQL), so I highly recommend that approach if possible. The reason is that requiring optional specs breaks out-of-the-box compatibility with most clients.

Spring Data Rest modify Repository method URI

This may be a bit of a rudimentary question, but I have a repository where I can do a find by username as follows:
....../items/search/byUsername/?username=myusername
However, this is generally inconsistent with how AngularJS Resources treat queries. Is there a way to instead make the request URI for the same thing to be
....../items/?username=myusername
Or does that functionality not exist with spring data rest? custom methods can be made in the angular resource but it is tedious to do that for every possible search category
If Angular (read: a client library) defines what URI's have to look like, then it's fundamentally violating a core REST principle — which is that clients follow links and URI templates.
That said, if you're using Querydsl and let your repository extend QuerydslPredicateExecutor, collection resources can be filtered by using property expressions. See the reference documentation for details.
Another option would be to manually expose resources under the URIs expected and manually forward the calls. But again, I'd argue you're better off teaching Angular to behave like a proper REST client in the first place 🙃.

Using java beans in AJAX

I am asking because I have only seen java beans used with a framework like struts or JSF.
Is it possible to send and access a java bean over an AJAX request?
Servlet myServlet creates and fills a java bean instance, and sets it in the request scope. An already loaded jsp/html page uses AJAX to request data from myServlet. Can this bean be accessed in any way? After thinking for a while, I have come to accept that this cannot be done.
If it can't be done, what would be the best practice when trying to transmit data from a model (i.e. user information from a database) asynchronously to a client when using Tomcat/Servlets and JSP?
It's technically possible if you serialize the javabean to a byte array or even a base64 encoded string using the usual Java Serialization API.
But how would it ever make sense to use a proprietary format to transfer data around? How would non-Java clients (e.g. JavaScript!) ever be able to consume the serialized Java object? These days XML, JSON and even CSV are much more widely supported and accepted. Practically every self-respected programming language has tools to easily convert between XML/JSON/CSV and the model as definied in the programming language in question. E.g. Java has JAX-RS API to easily convert between javabeans and XML or JSON. JavaScript has —obviously— builtin support for JSON (guess what "JS" in JSON stands for).
To learn and play around with the basic concept, head to this answer: How to use Servlets and Ajax?
To learn about the advantages of JAX-RS over servlet, head to this answer: Servlet vs RESTful
You can still use struts or jsf as you would normally to construct markup(html). And then consume the markup that was constructed via ajax and then append to the dom. If you are familiar with jQuery, something like jQuery('#selector').load('actionUrl.action');
But if you are looking to examine a java bean, then you will have to serialize it to xml or json. If you are using a web framework like struts2 or spring, there is likely a mechanism for doing this serialization for you. If you want to edit the bean you will have to serialize, then edit the serialized bean, and then deserialize back to the java bean.

Resources