1. Exposes set of resources through URIs
2. Stateless
3. Uniform interface[put|get|delete|post|]
- Apache CXF, an opensource Web service framework
- Jersey, the reference implementation from Sun (now Oracle)
- RESTeasy, JBoss's implementation
- Restlet
javax.ws.rs High-level interfaces and annotations used to create RESTful service resources.
javax.ws.rs.client The JAX-RS client API
javax.ws.rs.container Container-specific JAX-RS API.
javax.ws.rs.core Low-level interfaces and annotations used to create RESTful service resources.
javax.ws.rs.ext APIs that provide extensions to the types supported by the JAX-RS API.
ü REST
GET REQUEST CAN BE TESTED FROM BROWSER ITSELF
YOU CAN TRIGGER IT FROM FORM
CAN MAKE AJAX REQUEST
POSTMAN:You can set get|post|put|delete
ü can add headers
ü can add payload
you can write a java client
ü DEFAULT httpclient
ü OK HTTP
@Path | @Produces | @PathParam |
@Get | @Consumes | @QueryParam |
@Post | @MatrixParam | |
@Delete | @HeaderParam | |
@Put | ||
@Head |
JAX-RS is a Java-based standard API for REST Web Services over HTTP protocol. Representational state tra
Spring 5 WebClient and WebTestClient Tutorial with Examples
https://www.callicoder.com/spring-5-reactive-webclient-webtestclient-examples/
Spring BOOT Rest Client
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-webclient.html
Can you send boolean as responcetype in entity ? or How to send boolean as responceEntity?
public ResponseEntity<String> admin() {
if (isAdmin()) {
return new ResponseEntity<String>(HttpStatus.OK);
} else {
return new ResponseEntity<String>(HttpStatus.FORBIDDEN);
}
}
ResponseEntity
ResponseEntity
https://www.programcreek.com/java-api-examples/?api=org.springframework.http.ResponseEntity
https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/http/ResponseEntity.html
There are
@RequestMapping (...)
public String getBooks(@RequestParam(required = false, value = "sortby") String sortBy, @RequestParam(required = false, value = "year") String year) {...}
REST TEMPLATE
This example is not original work ,It has been saved purely for learning..
exchange() : Executes the HTTP method for the given URI. It returns
ResponseEntity
. It can communicate using any HTTP method.getForEntity() : It retrieves an entity by using HTTP GET method for the given URL. It returns
ResponseEntity
.headForHeaders() : Retrieves all headers. It uses HTTP HEAD method.
delete() : Deletes the resources at the given URL. It uses HTTP DELETE method.
put(): It creates new resource or update for the given URL using HTTP PUT method.
postForObject(): It creates new resource using HTTP POST method and returns an entity.
postForLocation(): It creates new resource using HTTP POST method and returns the location of created new resource.
postForEntity(): It creates news resource using HTTP POST method to the given URI template. It returns
ResponseEntity
. SPRING HATEOS[HYPERMEDIA AS ENGINE OF APPLICATION STATE]
____________________________________________________________________
Dependency : spring-hateoas
ControllerLinkBuilder
Builder to ease building
Link
instances pointing to Spring MVC controllers.linkTo(Class controller)
ControllerLinkBuilder
with a base of the mapping annotated to the given controller class.Its not easy to remember and maintain the complete list of services and state transition by the clients.
- Model classes for link, resource representation models
- Link builder API to create links pointing to Spring MVC controller methods
- Support for hypermedia formats like HAL
self
one) we provide a base class to actually inherit from when designing representation classes.add(Iterable<Link> links)
Adds all given Link
s to the resource.getLink(String rel)
Returns the link with the given rel.removeLinks()
Removes all Link
s added to the resource so far.hasLinks()
Returns whether the resource contains Link
s at all.removeLinks()
Removes all Link
s added to the resource so farPerson person = new Person(1L, "Dave", "Matthews");
// /person / 1
Link link = linkTo(PersonController.class).slash(person.getId()).withSelfRel();
assertThat(link.getRel(), is(Link.REL_SELF));
assertThat(link.getHref(), endsWith("/people/1"));
{ accountId: 1000, accountHolder: { userId: 5115, name: "Arnav", address: "Noida" }, amount: 1039.13, ifscCode: "AA992QA", _links: { accounts: { href: "http://localhost:1111/accounts" }, accountHolder: { href: "http://localhost:1111/accounts/1000/5115" } } }
{ userId: 5115, name: "Arnav", address: "Noida", _links: { account: { href: "http://localhost:1111/accounts/1000" } } }
References https://docs.spring.io/spring-hateoas/docs/current/reference/html/ https://www.dineshonjava.com/spring-hateoas-hypermedia-driven-restful-web-service/@RequestMapping(value= "/accounts/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) public ResourcebyId(@PathVariable("id") Long id) { logger.info("accounts byId() invoked: " + id); Account account = accountRepository.getAccount(id.toString()); Resource findAccountHolderById(@PathVariable("id") Long id, @PathVariable("userId") Long userId) { logger.info("accounts findAccountHolderById() invoked: " + id); Account account = accountRepository.getAccount(id.toString()); AccountHolder accountHolder = account.getAccountHolder(); Resourceresource = new Resource (account); resource.add(linkTo(methodOn(AccountController.class).all()).withRel("accounts")); resource.add(linkTo(methodOn(AccountController.class).findAccountHolderById(account.getAccountId(), account.getAccountHolder().getUserId())).withRel("accountHolder")); logger.info("accounts byId() found: " + account); return resource; } @RequestMapping(value= "/accounts/{id}/{userId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) public Resource resource = new Resource getAccountResource(Account account) { Resource(accountHolder); resource.add(linkTo(methodOn(AccountController.class).byId(account.getAccountId())).withRel("account")); logger.info("accounts findAccountHolderById() found: " + account); return resource; } private Resource resource = new Resource (account); resource.add(linkTo(methodOn(AccountController.class).byId(account.getAccountId())).withSelfRel()); resource.add(linkTo(methodOn(AccountController.class).findAccountHolderById(account.getAccountId(), account.getAccountHolder().getUserId())).withRel("accountHolder")); return resource; }
CONFIGURATION
package com.websystique.springmvc.configuration; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; @Configuration @EnableWebMvc @ComponentScan(basePackages = "com.websystique.springmvc") public class HelloWorldConfiguration { }
ADDING FILTER
package com.websystique.springmvc.configuration; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletResponse; public class CORSFilter implements Filter { public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { System.out.println("Filtering on..........................................................."); HttpServletResponse response = (HttpServletResponse) res; response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Credentials", "true"); response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE"); response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Allow-Headers", "X-Requested-With, Content-Type, Authorization, Origin, Accept, Access-Control-Request-Method, Access-Control-Request-Headers"); chain.doFilter(req, res); } public void init(FilterConfig filterConfig) {} public void destroy() {} }
INITIALIZER
package com.websystique.springmvc.configuration; import javax.servlet.Filter; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; public class HelloWorldInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class[] getRootConfigClasses() { return new Class[] { HelloWorldConfiguration.class }; } @Override protected Class[] getServletConfigClasses() { return null; } @Override protected String[] getServletMappings() { return new String[] { "/" }; } @Override protected Filter[] getServletFilters() { Filter [] singleton = { new CORSFilter()}; return singleton; } }
RESTCONTROLLER
package com.websystique.springmvc.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.util.UriComponentsBuilder; import com.websystique.springmvc.model.User; import com.websystique.springmvc.service.UserService; @RestController public class HelloWorldRestController { @Autowired UserService userService; //Service which will do all data retrieval/manipulation work //-------------------Retrieve All Users-------------------------------------------------------- @RequestMapping(value = "/user/", method = RequestMethod.GET) public ResponseEntity<List> listAllUsers() { Listusers = userService. findAllUsers(); if(users.isEmpty()){ return new ResponseEntity>(
HttpStatus.NO_CONTENT);//You many decide to return HttpStatus.NOT_FOUND } return new ResponseEntity>(users,
HttpStatus.OK); } //-------------------Retrieve Single User-------------------------------------------------------- @RequestMapping(value = "/user/{id}", method = RequestMethod.GET, produces = {MediaType.APPLICATION_JSON_VALUE,MediaType.APPLICATION_XML_VALUE}) public ResponseEntitygetUser(@PathVariable("id") long id) { System.out.println("Fetching User with id " + id); User user = userService.findById(id); if (user == null) { System.out.println("User with id " + id + " not found"); return new ResponseEntity ( HttpStatus.NOT_FOUND); } return new ResponseEntity(user, HttpStatus.OK); } //-------------------Create a User-------------------------------------------------------- @RequestMapping(value = "/user/", method = RequestMethod.POST) public ResponseEntity<Void> createUser(@RequestBody User user, UriComponentsBuilder ucBuilder) { System.out.println("Creating User " + user.getName()); if (userService.isUserExist(user)) { System.out.println("A User with name " + user.getName() + " already exist"); return new ResponseEntity( HttpStatus.CONFLICT); } userService.saveUser(user); HttpHeaders headers = new HttpHeaders(); headers.setLocation(ucBuilder.path("/user/{id}").buildAndExpand(user.getId()).toUri()); return new ResponseEntity(headers, HttpStatus.CREATED); } //------------------- Update a User -------------------------------------------------------- @RequestMapping(value = "/user/{id}", method = RequestMethod.PUT) public ResponseEntityupdateUser(@PathVariable("id") long id, @RequestBody User user) { System.out.println("Updating User " + id); User currentUser = userService.findById(id); if (currentUser==null) { System.out.println("User with id " + id + " not found"); return new ResponseEntity ( HttpStatus.NOT_FOUND); } currentUser.setName(user.getName()); currentUser.setAge(user.getAge()); currentUser.setSalary(user.getSalary()); userService.updateUser(currentUser); return new ResponseEntity(currentUser, HttpStatus. OK); } //------------------- Delete a User -------------------------------------------------------- @RequestMapping(value = "/user/{id}", method = RequestMethod.DELETE) public ResponseEntitydeleteUser(@PathVariable("id") long id) { System.out.println("Fetching & Deleting User with id " + id); User user = userService.findById(id); if (user == null) { System.out.println("Unable to delete. User with id " + id + " not found"); return new ResponseEntity ( HttpStatus.NOT_FOUND); } userService.deleteUserById(id); return new ResponseEntity( HttpStatus.NO_CONTENT); } //------------------- Delete All Users -------------------------------------------------------- @RequestMapping(value = "/user/", method = RequestMethod.DELETE) public ResponseEntitydeleteAllUsers() { System.out.println("Deleting All Users"); userService.deleteAllUsers(); return new ResponseEntity ( HttpStatus.NO_CONTENT); } }
package com.websystique.springmvc.model; public class AuthTokenInfo { private String access_token; private String token_type; private String refresh_token; private int expires_in; private String scope; public String getAccess_token() { return access_token; } public void setAccess_token(String access_token) { this.access_token = access_token; } public String getToken_type() { return token_type; } public void setToken_type(String token_type) { this.token_type = token_type; } public String getRefresh_token() { return refresh_token; } public void setRefresh_token(String refresh_token) { this.refresh_token = refresh_token; } public int getExpires_in() { return expires_in; } public void setExpires_in(int expires_in) { this.expires_in = expires_in; } public String getScope() { return scope; } public void setScope(String scope) { this.scope = scope; } @Override public String toString() { return "AuthTokenInfo [access_token=" + access_token + ", token_type=" + token_type + ", refresh_token=" + refresh_token + ", expires_in=" + expires_in + ", scope=" + scope + "]"; } }
package com.websystique.springmvc.model; public class User { private long id; private String name; private int age; private double salary; public User(){ id=0; } public User(long id, String name, int age, double salary){ this.id = id; this.name = name; this.age = age; this.salary = salary; } public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + (int) (id ^ (id >>> 32)); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; User other = (User) obj; if (id != other.id) return false; return true; } @Override public String toString() { return "User [id=" + id + ", name=" + name + ", age=" + age + ", salary=" + salary + "]"; } }
package com.websystique.springmvc.security; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; import org.springframework.security.oauth2.provider.approval.UserApprovalHandler; import org.springframework.security.oauth2.provider.token.TokenStore; @Configuration @EnableAuthorizationServer public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter { private static String REALM="MY_OAUTH_REALM"; @Autowired private TokenStore tokenStore; @Autowired private UserApprovalHandler userApprovalHandler; @Autowired @Qualifier("authenticationManagerBean") private AuthenticationManager authenticationManager; @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory() .withClient("my-trusted-client") .authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit") .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT") .scopes("read", "write", "trust") .secret("secret") .accessTokenValiditySeconds(120).//Access token is only valid for 2 minutes. refreshTokenValiditySeconds(600);//Refresh token is only valid for 10 minutes. } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints.tokenStore(tokenStore).userApprovalHandler(userApprovalHandler) .authenticationManager(authenticationManager); } @Override public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception { oauthServer.realm(REALM+"/client"); } }
No comments:
Post a Comment