-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRestWebservicesNotes.txt
More file actions
573 lines (420 loc) · 23.9 KB
/
RestWebservicesNotes.txt
File metadata and controls
573 lines (420 loc) · 23.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
notes on in 28 min - restful webServices
-> difference betweeen soap and rest
-> h2DataBase
-> To start server at different port at application.properties type -
server.port=8085
-> what is bean ?
Ans - A bean is an object that is instantiated, assembled, and otherwise managed by a Spring IoC container. Otherwise, a bean is simply one of many objects in your application.
Q . Auto-Configuration annotation
-> intialize dispatcher servlet
-> also convert bean object data from string to json - using jackson mapping
-> Error Mapping is also done by AutoConfiguration
- > @RestController = @Controller + @ResponseBody
-----------------------------
spring.jackson.serialization.write-dates-as-timestamps= false // for showing date in readable format
---------------------------------
protected User() { // no arg constructor is required basically to hit post request to save new user // but i tried without this also i was able to save .
}
------------------------------------------------------------------------------------------
Important -
Use of ResponseEntity , ResponseStatus , ResponseBody
- ResponseEntity represents an HTTP response, including headers, body, and status in a spring restful API. While @ResponseBody puts the return value into the body of the response of API, ResponseEntity also allows us to add headers and status code as well.
Prerequisite :
Let’s take a Java Entity Model Class called “Dependant” to be used in this example.
@Entity
@Table(name = "Dependant")
public class Dependant implements Serializable {
@Id
private int deptid;
@Column(name="firstname")
private String firstname;
@Column(name="lastname")
private String lastname;
// getter, setter methods ...
}
1. ResponseEntity ----
Example
Let’s create a simple REST API which returns Dependant class object which we made above, wrapped inside the ResponseEntity.
@GetMapping("/dependant/id/{id}")
public ResponseEntity<Dependant> getDependantbyId(@PathVariable int id){
Dependant dept = new Dependant();
dept = dependantRepository.findBydeptid(id);
HttpHeaders headers = new HttpHeaders();
headers.add("Custom-Header", "foo - Department");
return ResponseEntity.status(HttpStatus.OK).headers(headers).body(dept);
}
We give ResponseEntity a custom status code, headers, and a body.
OUTPUT
Status : 200 OK
Custom-Header →foo - Department
Content-Type →application/json;charset=UTF-8
Transfer-Encoding →chunked
Date →Tue, 25 Feb 2020 07:48:58 GMT
and body as shown below
{
"deptid": 1,
"firstname": "Donald",
"lastname": "T",
}
2. @ResponseBody ------
Example
In this example we try to achieve the same as as ResponseEntity but @ResponseBody only returns the body, in this case only the Dependant class object.
@GetMapping("/dependant/id/{id}")
@ResponseBody
public Dependant getDependant2byId(@PathVariable int id){
Dependant dept = new Dependant();
dept = dependantRepository.findBydeptid(id);
return dept;
}
With @ResponseBody, only the body is returned. The headers and status code are provided by Spring.
3. @ResponseStatus ---------
@ResponseStatus marks a method or exception class with the status code and reason message that should be returned. The status code is applied to the HTTP response when the handler method is invoked, or whenever the specified exception is thrown.
It overrides status information set by other means, like ResponseEntity or redirect.
Example : Custom Exceptions
@GetMapping("/dependant/id/{id}")
@ResponseBody
public Dependant getDependantbyId(@PathVariable int id){
if(id>10){
throw new MyCustomException("the id is not in range");
}
Dependant dept = new Dependant();
dept = dependantRepository.findBydeptid(id);
return dept;
}
@ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "No such dependant with this id")
public class MyCustomException extends RuntimeException {
public MyCustomException(String message){
super(message);
}
}
----------------------------------------------------------------------------------------------------------------------------
server.error.include-stacktrace=never ----- to remove the trace field from response add this in application field in postman // to check error trace hit exception
----------------------------------------------------------------------------------------------------------------------------
Why we Use toString method in java pojo class ?
Ans -- It depends on what you're going to use the POJO for. In general, it's certainly not required. toString() is not used in default Java binary serialization, although it may be used by some serialization frameworks. (I'm not aware of any that do this, but it's far from impossible.)
There's no performance benefit either.
There is potentially a diagnostic benefit though - that's the primary use of toString() - to get a string representation for diagnostic purposes, whether in a debugger or when logging. In some cases you may also wish to rely on toString() for non-diagnostic purposes, but you usually know about that when you do it... and normally such an implementation wouldn't just be StringUtil.toDetailString - that sounds like it's just going to produce something possibly-JSON-like which is more aimed at developers than anything else.
when logging we want to check whole object then logger.Error("hello world {}",object) -> this will show some random value hash value or reference if we donot put toString in
object file
---------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------
@ControllerAdvice In SpringBoot --
ControllerAdvice is an annotation provided by Spring allowing you to write global code that can be applied to a wide range of controllers — varying from all controllers to a chosen package or even a specific annotation.
Spring supports exception handling by a global Exception Handler (@ExceptionHandler) with Controller Advice (@ControllerAdvice). This enables a mechanism that makes ResponseEntity work with the type safety and flexibility of @ExceptionHandler:
@ControllerAdvice
public class ControllerExceptionHandler {
@ExceptionHandler(value = {ResourceNotFoundException.class, CertainException.class})
public ResponseEntity<ErrorMessage> resourceNotFoundException(ResourceNotFoundException ex, WebRequest request) {
ErrorMessage message = new ErrorMessage(
status,
date,
ex.getMessage(),
description);
return new ResponseEntity<ErrorMessage>(message, HttpStatus.NOT_FOUND);
}
}
The @ControllerAdvice annotation is specialization of @Component annotation so that it is auto-detected via classpath scanning. A Controller Advice is a kind of interceptor that surrounds the logic in our Controllers and allows us to apply some common logic to them.
Its methods (annotated with @ExceptionHandler) are shared globally across multiple @Controller components to capture exceptions and translate them to HTTP responses. The @ExceptionHandler annotation indicates which type of Exception we want to handle. The exception instance and the request will be injected via method arguments.
It declares @ExceptionHandler, @InitBinder, or @ModelAttribute methods to be shared across multiple @Controller classes.
-----------------------------------------------------------------------------------------------
For Validation use @Valid in controller and then in pojo class
Use like this ---------> @Size(min=2 , message="Enter min 2 Character.")
private String name ;
-----------------------------------------------------------------------------------------------
HATEOAS :- It is basically used if we want to send links also in the response so the nwe use hateoas
EntityModel<User> type method
and it has its own mothods to implement like linkTo , methodOn etc to use methodOn we have to import WebMvcLinkBuilder.* static
@GetMapping("/users/{id}")
public EntityModel<User> retrieveUser(@PathVariable int id) {
User user = daoService.findOne(id);
if(user==null) {
throw new UserNotFoundException("id - " + id);
}
EntityModel<User> model = EntityModel.of(user);
WebMvcLinkBuilder linkToUsers =
linkTo(methodOn(this.getClass()).retrieveAllUsers());
model.add(linkToUsers.withRel("all-users"));
return model ;
}
----------------------------------------------------------------------------------------------------------------
Internationalization -
This is use if we want to send any message in response in different language then we use Internationalization concept
In this We create messaages.properties file for different language
and in controller end
@Autowired
private MessageSource messageSource ; // provided by springboot framework
@GetMapping("/helloworld-international")
public String HelloInternational(
@RequestHeader(name="Accept-Language" , required=false)Locale locale) {
//return "Hello World International" ;
// en = hello world
// nl = goede Morgen
//fr = bonjour
return messageSource.getMessage("good.morning.message",
null , "Default Message" ,
locale);
// we can also use LocaleContextHolder.getLocale()
// in place of locale and remove the request header so that we
// do not have to call locale again n again
// we have created a messages.properties file having message with
// different language .
}
-------------------------------------------------------------------------------------------------
Content Negotiation - it is basically converting the type of the response - xml , json etc
To get Response in xml add the dependency in pom
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
thats it now in postman - add header accept --- application/json or application/xml
--------------------------------------------------------------------------------------------------
Configuring Auto Generation of Swagger Documentation
->
add dependency <!-- Open Api doc -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.5.9</version>
</dependency>
then hit link - > http://localhost:8085/swagger-ui.html
to check documentation - http://localhost:8085/v3/api-docs
--------------------------------------------------------------------------------------------------
Actuator ----> predefined endpoints like /health etc to check performance of service
-----------------------------------------------------------------------------------------------
HAL EXPLORER -> used to visualzie the apis
this add the dependency
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-rest-hal-explorer</artifactId>
</dependency>
then hit the localhost:8085 and check for the api
---------------------------------------------------------------------------------------------------
Why we use ComponentScan and Component in Spring ?
Ans - @ComponentScan ->
@ComponentScan tells Spring in which packages you have annotated classes which should be managed by Spring.
Spring needs to know which packages contain spring beans, otherwise you would have to register each bean individually in(xml file). This is the use of @ComponentScan.
Take a simple example, you have a class and annotated with @Controller in a package package com.abc.xyz; , you have to tell the spring to scan this package for Controller class, if spring didn't scan this package, then spring will not identifies it as a controller class.
Suppose if your dealing with configuration file,
<context:component-scan base-package="com.abc.xyz"> like this,
When spring loads the xml file, this tag will search the all the classes present in the package com.abc.xyz, so any of the class containing @controller, @Repository @Service etc.., if it found then spring will register these annotated class in the bean factory.
Suppose if your using spring boot application,
Then your spring-boot application is annotated with The@SpringBootApplication.
@SpringBootApplication annotation is equivalent to using @Configuration, @EnableAutoConfiguration and @ComponentScan with their default attributes.
One more point if you didn;t specify the base package name in @ComponentScan,
it will scan from the package, where the @Springbootapplication present
@Component ->
@Component is an annotation that allows Spring to automatically detect our custom beans.
In other words, without having to write any explicit code, Spring will:
Scan our application for classes annotated with @Component
Instantiate them and inject any specified dependencies into them
Inject them wherever needed
However, most developers prefer to use the more specialized stereotype annotations to serve this function like - > : @Controller, @Service, and @Repository. They all provide the same function as @Component. The reason they all act the same is that they are all composed annotations with @Component as a meta-annotation for each of them. They are like @Component aliases with specialized uses and meaning outside of Spring auto-detection or dependency injection.
Before we rely completely on @Component, we must understand that in and of itself, it's only a plain annotation. The annotation serves the purpose of differentiating beans from other objects, such as domain objects. However, Spring uses the @ComponentScan annotation to actually gather them all into its ApplicationContext.
If we're writing a Spring Boot application, it is helpful to know that @SpringBootApplication is a composed annotation that includes @ComponentScan. As long as our @SpringBootApplication class is at the root of our project, it will scan every @Component we define by default.
Let's define an out-of-scope @Component bean:
package com.baeldung.component.scannedscope;
@Component
public class ScannedScopeExample {
}
Next, we can include it via explicit instructions to our @ComponentScan annotation:
package com.baeldung.component.inscope;
@SpringBootApplication
@ComponentScan({"com.baeldung.component.inscope", "com.baeldung.component.scannedscope"})
public class ComponentApplication {
//public static void main(String[] args) {...}
}
---------------------------------------------------------------------------------------------------------------------------------
Q - what is IOC and Dependency Injection ?
Ans - Inversion of control- It means giving the control of creating and instantiating the spring beans to the Spring IOC container and the only work the developer does is configuring the beans in the spring xml file.
IoC is a design pattern that describes inverting the flow of control in a system, so execution flow is not controlled by a central piece of code. This means that components should only depend on abstractions of other components and are not be responsible for handling the creation of dependent objects. Instead, object instances are supplied at runtime by an IoC container through Dependency Injection (DI).
Dependency injection-
Consider a class Employee
class Employee {
private int id;
private String name;
private Address address;
Employee() {
id = 10;
name="name";
address = new Address();
}
}
and consider class Address
class Address {
private String street;
private String city;
Address() {
street="test";
city="test1";
}
}
In the above code the address class values will be set only when the Employee class is instantiated, which is dependency of Address class on Employee class. And spring solves this problem using Dependency Injection concept by providing two ways to inject this dependency.
Setter injection
Setter method in Employee class which takes a reference of Address class
public void setAddress(Address addr) {
this.address = addr;
}
Constructor injection
Constructor in Employee class which accepts Address
Employee(Address addr) {
this.address = addr;
}
In this way the Address class values can be set independently using either setter/constructor injection.
-----------------------------------------------------------
@SpringBootApplication include @ComponentScan , @EnableAutoConfiguration , @Configuration
@Configuration -- Use @Configuration annotation on top of any class to declare that this class provides one or more @Bean methods and may be processed by the Spring container to generate bean definitions and service requests for those beans at runtime.
@ComponentScan - check above
@EnableAutoConfiguration -- @EnableAutoConfiguration can be used to enable the auto-configuration feature of Spring Boot
----------------------------------------------------------------------------
@Transactional -- What is @transactional annotation in Spring boot?
The transactional annotation itself defines the scope of a single database transaction. ... The persistence context is just a synchronizer object that tracks the state of a limited set of Java objects and makes sure that changes on those objects are eventually persisted back into the database.
@Repository -- Spring @Repository annotation is used to indicate that the class provides the mechanism for storage, retrieval, search, update and delete operation on objects. used iin DAO
@Qualifier -- if we have two files having same work with different method then we can use Qualifier to select any one file from them .
----------------------------------------------------
Displatcher Servlet -
DispatcherServlet is the front controller in Spring web applications. It's used to create web applications and REST services in Spring MVC. In a traditional Spring web application, this servlet is defined in the web.xml file.
------------------------------------------
#jdbc properties for db connection
spring.datasource.url = jdbc:mysql://localhost:3306/employee_directory?useSSL=false&serverTimezone=UTC
spring.datasource.username=springstudent
spring.datasource.password=springstudent
-----------------------------------------------------------------------------
AOP breaks the program logic into distinct parts (called concerns). It is used to increase modularity by cross-cutting concerns.
A cross-cutting concern is a concern that can affect the whole application and should be centralized in one location in code as possible, such as transaction management, authentication, logging, security etc.
---------------------------------------------------------------
What is a Web Service?
Web Services work on client-server model where client applications can access web services over the network. Web services provide endpoint URLs and expose methods that can be accessed over network through client programs written in java, shell script or any other different technologies.
Web services are stateless and doesn’t maintain user session like web applications.
-------------------------------------------------------------------------------------------
Predicate<T> is single argument function and either it returns true or false.This can be used as the assignment target for a lambda expression or method reference.
Function<T,R> is also single argument function but it returns an Object.Here T denotes type of input to the function and R denotes type of Result.
This can also be used as the assignment target for a lambda expression or method reference.
--------------------------------------------------------------------------------------------------------
Consumer is single argument functional interface which does not return any value.
When we are using foreach in above example, we are actually passing Consumer functional interface to it.
accept method
-----------------------------------------------------------
To Check why we required no arg constructor for JPA , Hibernate etc refer this link
---> https://javarevisited.blogspot.com/2014/01/why-default-or-no-argument-constructor-java-class.html#axzz7ENeRJJvj
-----------------------------------------------
Rest API Response Codes
Here are some sample Response Codes which we will normally see while performing REST API testing over POSTMAN or over any REST API client.
#1) 100 Series
These are temporary Responses
100 Continue
101 Switching Protocols
102 Processing
#2) 200 Series
The client accepts the Request, being processed successfully at the server.
200 – OK
201 – Created
202 – Accepted
203 – Non-Authoritative Information
204 – No Content
205 – Reset Content
206 – Partial Content
207 – Multi-Status
208 – Already Reported
226 – IM Used
#3) 300 Series
Most of the codes related to this series are for URL Redirection.
300 – Multiple Choices
301 – Moved Permanently
302 – Found
303 – Check Other
304 – Not Modified
305 – Use Proxy
306 – Switch Proxy
307 – Temporary Redirect
308 – Permanent Redirect
#4) 400 Series
These are specific to client-side error.
400 – Bad Request
401 – Unauthorised
402 – Payment Required
403 – Forbidden
404 – Not Found
405 – Method Not Allowed
406 – Not Acceptable
407 – Proxy Authentication Required
408 – Request Timeout
409 – Conflict
410 – Gone
411 – Length Required
412 – Precondition Failed
413 – Payload Too Large
414 – URI Too Long
415 – Unsupported Media Type
416 – Range Not Satisfiable
417 – Expectation Failed
418 – I’m a teapot
421 – Misdirected Request
422 – Unprocessable Entity
423 – Locked
424 – Failed Dependency
426 – Upgrade Required
428 – Precondition Required
429 – Too Many Requests
431 – Request Header Fields Too Large
451 – Unavailable For Legal Reasons
#5) 500 Series
These are specific to the server-side error.
500 – Internal Server Error
501 – Not Implemented
502 – Bad Gateway
503 – Service Unavailable
504 – Gateway Timeout
505 – HTTP Version Not Supported
506 – Variant Also Negotiates
507 – Insufficient Storage
508 – Loop Detected
510 – Not Extended
511 – Network Authentication Required
----------------------------------------------------------------
How to mock the response NSA
->
create own method first
public NextBillSummaryResponse buildNBSMockResponse()
{
ObjectMapper mapper = new ObjectMapper();
NextBillSummaryResponse nbsTemplate = null ;
InputStream resources = null ;
try {
resources = new ClassPathResource("/cxp/getNbsData.json").getInputStream();
nbsTemplate = mapper.readValue(resources,NextBillSummaryResponse.class);
}
catch(IOException e){
LOGGER.error("Error in NBSResponseMock",e);
nbsTemplate = new NextBillSummaryResponse();
}
finally{
try{
resources.close();
}
catch(IOException e){
LOGGER.error("Error Occur while closing resource in reading request :: buildNBSMockResponse" + e);
e.printStackTrace();
}
}
return nbsTemplate ;
}
@Override
public Mono<NextBillSummaryResponse> execute(TokenDTO tokenDTO, Mono<NextBillSummaryRequest> extServiceRequestMono){
int flag =0;
return extServiceRequestMono.flatMap(req -> {
Mono<NextBillSummaryResponse> nextBillSummaryResponseMono ;
try{
if(flag==1){
nextBillSummaryResponseMono = services.getNBSData(req);
}
else{
nextBillSummaryResponseMono = Mono.just(buildNBSMockResponse());
}
return nextBillSummaryResponseMono ;
}
catch(SOEHTTPException e){
LOGGER.error("Case call failed for " + e);
throw new CxpRestServiceException("Next Bill Summary Exception :: " + e.getMessage(), CPCConstant.NBSAPI)}
});
}
------------------------------------------------------------------------------------------------------------