How to Log all Incoming Request in Spring REST Services - spring

Hi I am using Spring framework to build REST full web services . I want to log all the incoming request to my service. Is there any way I can log all the incoming request to my web service.

You could use Filter or Interceptor if you need very basic solution. Just inject your service into it, and override "preHandle(HttpServletRequest request..."
Problems will come when you decide that you need to:
log only some requests (E.g. only PUT and POST)
exclude some data (e.g. passwords, keys, etc)
exclude files
parse data to extract information to persist it
know if it return success or failure or exception
Then better solution would be to call that service directly from controllers.

Related

How to store request data and reponse data into database in spring boot application

I am working on to store request data and response data if there any exceptions encountered while sending response back to client I need to store the exception also.
My DB table will ID,RequestData,ResponseData,Exception,TimeTakenToRespond
lets say I have endpoint called /athenticateUser so my input data would be
RequestData :{"username":"mate","password":"swamy"}
ResponseData :{"FirstName":"mate","LastName":"swamy","Email":"manteswamy#gmail.com"}
Like the above way I need to store all the request data and response data if any exception while sending response back to client that also we need store and the web service time taken respond.
As I am beginner to spring boot please guide step by step
Though you can write Interceptors, Filters etc for this. But don't do it.
Please try to use Spring Boot feature Actuator for tracing. It provides HTTP request logging out of the box.
There's an endpoint mapped to /trace or /actuator/httptrace which will show you last 100 HTTP requests. You can customize it to log each request, or write to a DB.
You will need spring-boot-starter-actuator dependency.
You can also whitelist endpoints.
For the guide step by step, you can check this actuator tutorial.
You can do it by using spring boot actuator httptrace..
add below dependency:
implementation('org.springframework.boot:spring-boot-starter-actuator')
Look at this step by step guide..
The Spring-boot actuator doesn't support getting the request/response bodies, they even removed some mechanisms to do it.
Here's a blog post on how to do it with a Filter.

What is the differences between Spring Boot API without Filter and Spring Boot API with Filter?

From the beginning, I often write Spring Boot API with many API depend on what my application needs. I know there is a type like Filter Servlet, what is it? Can anyone help me to find the difference between API with Filter and without Filter?
I have go through some research: https://www.baeldung.com/spring-boot-add-filter and https://www.tutorialspoint.com/spring_boot/spring_boot_servlet_filter.htm
I have a sample for using Servlet Filter: https://help.shopify.com/en/api/reference/products/product#create-2019-10
A filter is an object used to intercept the HTTP requests and responses of your application. By using filter, we can perform two operations at two instances −
Before sending the request to the controller
Before sending a response to the client.
so its depends on requirement of your app if you need to do some work before sending request to controller or not.
Take an example below:
if we need to create an application where we need to authenticate and authorization of user with help of token so in each api we need to verify token before sending request to controller so we can use filter their.
and sending response back to client if we want to append some token then we can add same in filter.
example of filter:
https://www.javadevjournal.com/spring-boot/spring-boot-add-filter/
below method use for next call:
filterChain.doFilter(request, response);

Forward Spring HTTP Request

I have a restful web service written using Spring WebMVC that will mostly be used to orchestrate other services. In some cases these services are on the same server, in some cases they are not. I have a few requests (GET and POST) that will be direct pass throughs to another service. Is there a way to blindly forward all GET and POST data from a request for certain URLs without knowing anything about the data in the request?
Ideally, I would like to be able to say all requests for http://server1/myService/user/... should forward to http://server2/user/... with all of the GET and POST parameters forwarded with it.
For the services on the same server, if they're being served by the same Spring MVC application, you could use RedirectViews and/or the "redirect:" prefix.
For those on another server, the best thing I can think of would be to use a servlet filter, similar to the approach suggested by this post: spring mvc redirect path and all children to another domain

Request filter versus request interceptor?

My application exposes a RESTful API which when called calls out to a mailbox server and fetches data. I want to be able disable the service during application runtime in the event of some outage on the mailbox server. I wanted to do this in a way that the logic of deciding whether or not to call the mailbox server was abstracted from the actual code that calls the mailbox server. Two options which seem to fit this scenario are filters and interceptors however I'm looking for advice on which one best suits this requirement and what are the difference between each?
Thanks
If you are using Spring MVC then you can use an interceptor, which is like a filter but that has access to the Spring context. If you are using Jersey then you can't use interceptors.

Rest-SOAP gateaway for external services (Spring + Camel)

I need to build REST-SOAP gateaway between 2 external services
First web services makes SOAP requests and awaits SOAP response. Second service (mine, written in Play Framework 1.2.4) works only using RESTful approach. I don`t want to integrate SOAP related things with second service for many reasons. So I need some third service to act between them.
I have looked into using Spring web-app with Apache Camel, but still can't get the full picture because there are so many modules for Camel. CXF-RS and SOAP components looks promissing, but I can't figure out how to implement proxying using them.
First of all, how to make Camel listen for the specified SOAP request. And then, how to route response from RESTful service back to calling service.
I tried to do it using only spring configuration.
Camel CXF will do the trick for your soap endpoint.
First you need to write an endpoint
#WebService
public interface QuoteInEndpoint {
#WebResult(name = "quote")
public Quote price(#WebParam(name = "symbol") String symbol);
}
Then you need to declare it
<cxf:cxfEndpoint id="quoteIn" address="http://localhost:9002" serviceClass="my.package.QuoteInEndpoint" />
You can then build a route from this endpoint
from("cxf:bean:quoteIn")//
.process(new Processor() {
#Override
public void process(Exchange exchange) throws Exception {
//do whatever you need to get your object and transform it for your rest service
}
})//
.to("http://myplayframeworkserver/myservice")//
Camel will start the route, expose the wsdl of your soap service at localhost:9002, and every soap request will be send to your rest server. The process method can be use to shape your objects to the correct format for your rest service (I assume json). Instead of using a processor, you might use another Camel component to do the job (Camel JSON if you need json)
There is no straight forward way to simply proxy between soap and rest. REST services, is all about resources and CRUD - create/read/update/delete. The payload can be whatever, often JSON, but XML, plain text or any orther format is valid. SOAP is XML only with custom definied methods.
I understand the confusion about all the components related to this in Camel.
There are a few aspects you need to have in mind, while chosing your approach.
How much of the SOAP stack do you really need? Most likely you only want the basic featuers, such as receiving a simple soap-envelope and extract the payload without WS-addressing, ws-security etc. etc.
Do you have a contract first or code first approach? That is, do you have your soap service already definied by java classes/interfaces or do you have a WSDL?
Do you have your camel instance deployed inside a servlet container (which is quite common), such as Tomcat, Jetty or a JavaEE app server? If you, you might need to use that servlet container to handle requests by some reason (to get all requests from the same port/server/Domain name by some reason such as web server virtual host, firewalls etc). Then CXF might ge a bit tricky. Otherwise, camel can put up listeners with the built-in jetty core.
So:
Contract first and camel inside serverletcontainer - I prefer spring-ws, since it's very easy to get started with. spring-ws component. Just do the initial wireing in spring and you do not even need to generate things from a WSDL, just simply point out which soap-action, uri or rootq name to get messages from:
from("spring-ws:soapaction:http://example.com/GetFoo?endpointMapping=#endpointMapping")
then you have the XML.
If you need to host the web service from camel, CXF in payload mode is quite decent and will behave pretty much the same.
from("cxf:somename:http://localhost:8765?wsdl=somewsdlfile.wsdl&dataFormat=PAYLOAD")
If you have the service definied in Java already, you could use the SOAP dataformat with the Jetty component to get a very lightweight solution.
SoapJaxbDataFormat soap = new SoapJaxbDataFormat("com.example.customerservice", new ServiceInterfaceStrategy(CustomerService.class));
from("jetty:http://localhost:9832/soapsrv")
.marshal(soap) // and other transforms here
.to("http://somerestservicehost/srv");
Or. go with the full CXF solution with CXF or CXF-bean. There are plenty of examples on the camel website. But the component is rather large and can be somewhat tricky.
For rest, there are also choices, but that part is more straight forward. Rest is very much about creating some content (by extracting it from the soap message, and perhaps map xml to json), which might be easiest to achieve with some plain old java code. Then just invoke a HTTP endpoint towards your rest server. The HTTP4 or HTTP component will do a lot of this for you.
CXFRS is good if you like CXF, and can provide some help, specifically if you want to model your rest service with classes

Resources