I need to create a rest method to get a client by id in postman, I even created the method, but it doesn't return any information by id with spring boot.
ClientControle.java:
#GetMapping(value = "/clientes/{id}")
public Cliente listCliente(#PathVariable("id") long id){
return clienteService.getById(id);
ClienteService:
public interface ClienteService {
Cliente getById(long id);
List<Cliente> getAll();
Cliente save(Cliente cliente);
}
but i have the following error:
You have #RequestMapping("clientes") at the controller(class) level,
so your actual URL should be http://localhost:8080/clientes/clientes/1
As per your code in image, you shared you are having clientes on class level also either you can remove from here then localhost:8080/clientes/1 will work or you need to use localhost:8080/clientes/clientes/1
Related
Although this situation is easy for ready overrided methods, I couldn't find a way for my own query.
This is my repository :
public interface CommentRepository extends JpaRepository<User , Long >{
#Modifying
#Transactional
#Query( value="delete from users where first_name=:name" , nativeQuery=true )
public void delete( String name );
}
This is my controller :
#RestController
#RequestMapping(path="/api/v1/users")
public class CommentController {
#Autowired
CommentRepository repository ;
// Delete user
#DeleteMapping(path="/delete")
public void delete(#RequestParam String name) {
repository.delete(name) ;
}
}
For example, if I delete a user, I want to pass a status code of 200 to the developer if the query is successful.
However I want to pass different codes if the query fails.
ResponseEntity represents the whole HTTP response: status code, headers, and body. As a result, we can use it to fully configure the HTTP response.
Have a look at Response entity using which you will be able to configure everything including status codes .
https://www.baeldung.com/spring-response-entity
In the rest controller you can do something like:
#RestController
#RequestMapping(path="/api/v1/users")
public class CommentController {
#Autowired
CommentRepository repository ;
// Delete user
#DeleteMapping(path="/delete")
public ResponseEntity<Void> delete(#RequestParam String name) {
repository.delete(name);
return ResponseEntity.ok().build();
}
}
Since I don't know your database structure, let's say a SQLIntegrityConstraintViolationException can be thrown, you can create a service layer that will handle the exception. You will end up with something like:
#RequiredArgsConstructor
public class CommentServiceImpl implements CommentService {
private final CommentRepository commentRepository;
#Override
public void deleteUsersByName(String name) {
try {
commentRepository.delete(name); //consider changing the repo method name 'delete' to be more contextual like 'deleteAllByName(String name)'
} catch (Exception | SQLIntegrityConstraintViolationException e) //or other type, depending on your database structure
throw new MyCustomException("my message: " + e); //create new RuntimeException with the name you prefer
}
}
Then you have lots of ways to handle your new exception. Please read more here: https://www.baeldung.com/exception-handling-for-rest-with-spring
One of the ways is to have this inside your #RestController class
#ExceptionHandler({MyCustomException.class})
public ResponseEntity<Void> handleConstrainViolationException() {
return ResponseEntity.internalServerError(); //just an example
}
for the last part you can play around with the exceptions thrown on the service layer and return appropriate status code from the corresponding exception handler. Consider having a global exception handler as stated into the article on Baeldung above. Hope it helps a little bit.
I am a newbie in Spring development. I need to create a simple application, a controller that has a method that takes as parameter an object of a custom designed entity class into the project. The prototype looks like this:
#RestController
public class JobsController {
#PostMapping("/search")
public ResponseEntity<?> search() {
log.info("JobsController -> search method");
//JobSearchEntity jobSearchEntity = modelMapper.map(jobSearch, JobSearchEntity.class);
List<JobEntity> jobs = jobService.searchJobs();
//log.info(String.format("Job found: %s ", jobSearch));
return ResponseEntity.ok(jobs);
}
}
Can someone who is more advanced into this staff with Postman testing tell me how to do that , how to test a controller method which takes parameters?
You can use postman to submit parameters in JSON format after adding # requestbody annotation on the method, or submit parameters directly in form without annotation
You can use this example. Is very simple exemple.
#RestController
#RequestMapping("/root")
public class RootController {
private final RootService service;
public RootController(final RootService service) {
this.service = service;
}
#PostMapping("/exemple")
public void createRoot(#RequestBody final RootDto dto) {
service.createRoot(dto);
}
}
Then you can send request to POST host/root/exemple with your JSON.
More exampls you can find here: https://www.baeldung.com/spring-request-response-body
It seems you are missing an honest search on google about the subject.
You can make use of #RequestBody annotation to accept method arguments.
Check these page for examples --
#RequestBody and #ResponseBody annotations in Spring
https://stackabuse.com/get-http-post-body-in-spring/
https://www.twilio.com/blog/create-rest-apis-java-spring-boot
These set of playlist on youtube are very good starter course for SpringBoot -
https://www.youtube.com/c/JavaBrainsChannel/playlists
Postman Tutorial--
https://www.youtube.com/watch?v=VywxIQ2ZXw4
To get data from api is preferred to use GET method :
#RestController
public class JobsController {
#GetMapping("/search")
public ResponseEntity<?> search(#RequestParam("id") String id,#RequestParam("desc") String desc) {
log.info("JobsController -> search method");
//JobSearchEntity jobSearchEntity = modelMapper.map(jobSearch, JobSearchEntity.class);
List<JobEntity> jobs = jobService.searchJobs();
//log.info(String.format("Job found: %s ", jobSearch));
return ResponseEntity.ok(jobs);
}
}
you call this api with post man this way :
#PostMapping used usually to save new data (example : create job )
Take look on rest resource naming guide
I should migrate some code from jax-rs to spring mvc. We had a controller, which response with an object and set at the same time links in a list :
HateoasResponse.ok(content)
.selfLink(FieldPath.path("categories"), "some_controller_id", "id")
.build()
Did any one know, if there is something similar in spring mvc ?
I have checked spring-hateoas. If I use it , I should modify my models to something supported by this package (CollectionModel, EnitityModel..)
You have to make the response object extend ResourceSupport and then generate the links as follows.
org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo(methodOn(YourSpringMvcController.class)
.methodWhichHasMappingTo(param1,param2,paramN))
.withRel("relationOfThisLinkToTheRequestedResource").expand();
This link can then be added to the response object using the resource add method.
for example, let's say you have a controller like the following:
#RestController
public class OrderController {
#GetMapping(value = "/orders/{orderId}", method = RequestMethod.GET)
#ResponseBody
public ResponseEntity<Order> getOrder(#Valid #PathVariable Integer orderId) {
return getOrder(orderId);
}
#DeleteMapping(value = "/orders/{orderId}", method = RequestMethod.GET)
#ResponseBody
public ResponseEntity<Order> deleteOrder(#Valid #PathVariable Integer orderId) {
return orderRepo.deleteOrder(orderId);
}
}
then for a request to GET orders, you would build the response like the following:
Order which is a response entity will extend ResourceSupport
public Order getOrder(int orderId){
Order order = repo.findByOrderId(orderId);
Link deleteLink = ControllerLinkBuilder.linkTo(methodOn(OrderController.class)
.deleteOrder(orderId))
.withRel("delete").expand();
order.add(deleteLink);
Link selfLink = ControllerLinkBuilder.linkTo(methodOn(OrderController.class)
.getOrder(orderId))
.withSelfRel();
order.add(selfLink);
return order;
}
Hope this helps.
I have a spring mvc project, i want to convert spring rest api project.
Here my sample codes;
My Controller
#Controller
#RequestMapping("/student")
public class StudentController {
#Autowired
private StudentService studentService;
#Autowired
private SchoolService schoolService;
#GetMapping("/list")
public String ListStudents(Model model) {
List<Student> theStudent = studentService.getStudents();
model.addAttribute("students", theStudent);
return "List-student";
}
#GetMapping("/addNewStudent")
public String addNewStudent(Model model) {
Student theStudent = new Student();
model.addAttribute("student", theStudent);
List<School> theSchool = schoolService.getSchools();
model.addAttribute("schools", theSchool);
return "student-form";
}
#PostMapping("/saveStudent")
public String saveStudent(#ModelAttribute("student") Student theStudent) {
studentService.saveStudent(theStudent);
return "redirect:/student/list";
}
#GetMapping("/showFormforUpdate")
public String showFormForUpdate(#RequestParam("studentID") int theId, Model model) {
Student theStudent = studentService.getStudent(theId);
model.addAttribute(theStudent);
List<School> theSchool = schoolService.getSchools();
model.addAttribute("schools", theSchool);
return "student-form";
}
#GetMapping("/deleteStudent")
public String deleteStudent(#RequestParam("studentID") int theId, Model model) {
studentService.deleteStudent(theId);
return "redirect:/student/list";
}
}
My DAOImpl class
#Repository
public class StudenDAOImpl implements StudentDAO {
#Autowired
private SessionFactory sessionFactory;
#Override
#Transactional
public List<Student> getStudents() {
Session currentSession=sessionFactory.getCurrentSession();
Query<Student> theQuery = currentSession.createQuery("from Student", Student.class);
List<Student> students=theQuery.getResultList();
return students;
}
#Override
public void saveStudent(Student theStudent) {
Session currentSession=sessionFactory.getCurrentSession();
currentSession.saveOrUpdate(theStudent);
}
#Override
public Student getStudent(int theId) {
Session currentSession=sessionFactory.getCurrentSession();
Student theStudent=currentSession.get(Student.class, theId);
return theStudent;
}
#Override
public void deleteStudent(int theId) {
Session currentSession=sessionFactory.getCurrentSession();
Query theQuery=currentSession.createQuery("delete from Student where id=:studentID");
theQuery.setParameter("studentID", theId);
theQuery.executeUpdate();
}
}
Actually i know the places i need to change. But i don't know very well spring Rest Api. In my code i send many attributes in my view(jsp file) and i catch this attributes here . But RestApi does not have views. I need to delete attribute functions. But what can i add instead of attribute functions? I am new the RestApi please help me what should i do?
welcome to stack overflow.
Rest APIs work like this:
You expose an endpoint and a verb (for example GET at /students)
Some client calls your endpoint (makes a call to the server that holds your app)
Your server delegates the call to a controller function ( a function with a #GetMapping("/students") for example )
The controller function sends a response to the client (With spring, your method returns an object or a ResponseEntity)
REST APIs receive requests , process said request (and request data if present) and tipically return some data with a status code that indicates if the operation was successful.
With spring you do something like this:
#GetMapping("/students")
ResponseEntity<List<Student>> listStudents() {
List<Student> stds = getStudents(); // call some service or DB
return new ResponseEntity<>(stds, HttpStatus.OK);
}
When you make a GET request to /students, spring will delegate the handling of the request to the listStudents method which will get the students and return data.
REST APIs tipically work with JSON, so the list of students you'll be returning will be serialized into a json list.
If you want to customize the student json structure you can use Jackson:
public class Student {
#JsonProperty("cool_name") private String name;
// getters and setter
}
A rest api does not work with views or JSP. They tipically work with http requests and responses.
If you're working with spring mvc instead of spring boot, check this article:
https://viralpatel.net/blogs/spring-4-mvc-rest-example-json/
If you can use spring boot (which I highly recommend) , check this:
https://spring.io/guides/gs/rest-service/
You should also annotate your REST controllers with #RestController for them to automatically handle rest calls.
Hope this helps and welcome to stack overflow
I am using #RepositoryResource annotation on my Reposioptory interface with this code:
#RepositoryRestResource(collectionResourceRel = "rest", path = "rest")
public interface HoliDayRepository extends CrudRepository<HoliDayEntity, Integer> {
HoliDayEntity findOne(Integer id);
}
and i have alsoe added RequestMapping("rest) in controller class
#RestController
#RequestMapping("/rest")
public class DayController {}
but when i start spring boot application and try this link :http://localhost:8080/rest i got 404 error also while building application i have ResourceNotFoumd exceptions how should i manage these errors?
with spring boot you don't need to create your own controller; also make sure your web application mapping is different to the one you use for spring data, for example you can set in application.properties spring.data.rest.base-path: /api
Have a look at this example:
public interface PersonRepository extends JpaRepository<Person, UUID> {
List<Person> findByAddress(String address);
}
with just this code you should able to access spring data repositories here: http://localhost:8080/api and the person endpoint here http://localhost:8080/api/person
Have a look at this tutorial: https://spring.io/guides/tutorials/react-and-spring-data-rest/ or this example: https://github.com/Paizo/SpringBootCamelStreamsExample
You need a method which should be called when you hit your endpoint.
try below and also check spring example:
https://spring.io/guides/tutorials/bookmarks/
#Autowired
private HoliDayRepository holiDayRepository; //your repository to execute the query
#GetMapping(value = "/{id}")//you can use #RequestMapping(method = RequestMethod.GET, value = "/{holida}")
public ResponseEntity<HoliDayEntity > getHolidayById(#PathVariable("id") Integer id) {
HoliDayEntity holiDayEntityresponse = productOperations.getProductById(id);
return new ResponseEntity<>(holiDayEntityresponse , HttpStatus.OK);
}
EDIT:
As pointed by Gimby, this is not applicable when #RepositoryRestResource is used. Both the code and the tutorial attached are refering to creating new REST service by creating the controller