I'm developing a Spring boot application and my endpoints are not working at all. I'm getting the next issue:
{
"timestamp": "2020-06-21T21:12:39.716+0000",
"status": 404,
"error": "Not Found",
"message": "No message available",
"path": "/prduct/jjjk"
}
This is the structure of my project:
As you can see the controller is in the same path a subpackage of the Application class, but it is not scanned.
package com.mercadolibre.mutants.controllers;
import com.mercadolibre.mutants.entities.Product;
import com.mercadolibre.mutants.repositories.ProductRepository;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class ProductController {
#Autowired
ProductRepository productRepository;
#GetMapping("/prduct/{id}")
public ResponseEntity<Product> findById(#PathVariable("id") String id) {
Optional<Product> p = productRepository.findById(id);
return ResponseEntity.ok(p.orElse(null));
}
#PostMapping(value = "/products", consumes = "application/json")
public ResponseEntity<Product> save(#RequestBody Product p) {
Product result = productRepository.save(p);
return ResponseEntity.ok(result);
}
}
This is my Application class:
package com.mercadolibre.mutants;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication(scanBasePackages = "com.mercadolibre.mutants")
public class MutantsApplication {
public static void main(String[] args) {
SpringApplication.run(MutantsApplication.class, args);
}
}
I'm not able to identify the issue or what I'm missing. Any ideas?
Related
I'm getting a error like:
Request method 'GET' not supported for a method (deleteProductById)
using the #DeleteMapping annotation whenever I visit the URL mapped to said method (http://localhost:8083/deleteproductbyid/1). The app works when I change the annotation for the method to #GetMapping but that causes other issues.
Here's the relevant code:
package com.democrudexample.controller;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.democrudexample.model.Product;
import com.democrudexample.services.CrudService;
#RestController
#RequestMapping("/")
public class CrudRestController {
#Autowired
private CrudService service;
#GetMapping("/getproductlist")
#CrossOrigin(origins = "http://localhost:4200")
public List<Product> fetchProductList() {
List<Product> products = new ArrayList<Product>();
//logic to fetch list from database
products = service.fetchProductList();
return products;
}
#PostMapping("/addproduct")
#CrossOrigin(origins = "http://localhost:4200")
public Product saveProduct(#RequestBody Product product) {
return service.saveProductToDB(product);
}
#GetMapping("/getproductbyid/{id}")
#CrossOrigin(origins = "http://localhost:4200")
public Product fetchProductById(#PathVariable int id) {
return service.fetchProductById(id).get();
}
#DeleteMapping(value = "/deleteproductbyid/{id}")
#CrossOrigin(origins = "http://localhost:4200")
public String deleteProductById(#PathVariable int id) {
return service.deleteProductById(id);
}
}
package com.democrudexample.services;
import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.democrudexample.model.Product;
import com.democrudexample.repository.CrudRepo;
#Service
public class CrudService {
#Autowired
private CrudRepo repo;
public List<Product> fetchProductList(){
return repo.findAll();
}
public Product saveProductToDB(Product product) {
return repo.save(product);
}
public Optional<Product> fetchProductById(int id) {
return repo.findById(id);
}
public String deleteProductById(int id) {
String result;
try {
repo.deleteById(id);
result = "Product sucessfully deleted";
System.out.println(result);
}catch(Exception e) {
result = "Product id is not valid";
System.out.println(result);
}
return result;
}
}
EDIT: I commented out the result and everything related to it in the deleteProductById method and it seems to be working just fine now. After having looked at the console, the error seems to have been some issues with parsing the text.
By annotating the method as #DeleteMapping, you are making this a HTTP DELETE operation. Refer this documentation for more details about different HTTP requests.
However, when you access an URL in browser, browser always sends a GET request, whereas your Resource is expecting a DELETE request. Hence you are getting the error.
You can use tools like Postman or you can write a small code in Javascript to send a DELETE request to the server.
I build spring boot application, but the problem is I want to upload images on the web browser but it does not work, I run the app on IntelliJ IDEA, here is the code: https://github.com/rmalav15/siamese-tf-java
please help, here is the code that backs the error (Unable to Enroll Due to some error)
package com.tensorflow.siamese.controllers;
import com.tensorflow.siamese.models.User;
import com.tensorflow.siamese.services.EnrollmentService;
import com.tensorflow.siamese.services.ImageProcessingService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
#RestController
#RequestMapping("/enroll")
#Slf4j
public class EnrollmentController {
#Value("${images.save.path:src/main/resources/Images}")
private String path;
#Autowired
private EnrollmentService enrollmentService;
#RequestMapping(value = "/new", method = RequestMethod.POST)
ResponseEntity enrollNew(#RequestParam("name") String name,
#RequestParam("files") List<MultipartFile> images) {
try {
List<Path> imagePaths = new ArrayList<>();
for (MultipartFile file : images) {
imagePaths.add(ImageProcessingService.write(file, path));
}
User user = enrollmentService.enrollNew(imagePaths, name);
return ResponseEntity.ok(user);
} catch (Exception e) {
log.debug("Exception in enrollNew Apia", e);
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Unable to Enroll Due to some error.");
}
}
}
In Login class #Autowired is not null but when I try to use postman call Logout class #Autowired get null. I copy code from Login to Logout class just change variable name all code is same pattern I don't know what happening
package xxx.api.login
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import com.fasterxml.jackson.databind.ObjectMapper;
import xxx.api.domain.logout.LoginRequest;
import xxx.api.domain.logout.LoginResponse;
import xxx.converter.FieldValidation;
import xxx.dto.log.MessageLog;
import xxx.logging.LogFactory;
#Component
public class LoginClient {
#Autowired
FieldValidation fieldValidation;
public LoginResponse login(LoginRequest loginRequest) throws Exception {
ObjectMapper mapper = new ObjectMapper();
final String url = "http://localhost:xxx/xxx/login";
LoginResponse responseObject = null;
try {
String requestData = mapper.writeValueAsString(loginRequest);
responseObject = login(url, requestData);
fieldValidation.validateResponse(responseObject, "login");
// 'fieldValidation' not null
This is my Login class. Return result as I expect.
package xxx.api.logout;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import com.fasterxml.jackson.databind.ObjectMapper;
import xxx.api.domain.logout.LogoutRequest;
import xxx.api.domain.logout.LogoutResponse;
import xxx.converter.FieldValidation;
import xxx.dto.log.MessageLog;
import xxx.logging.LogFactory;
#Component
public class LogoutClient {
#Autowired
FieldValidation fieldValidation;
public LogoutResponse logout(LogoutRequest logoutRequest) throws Exception {
ObjectMapper mapper = new ObjectMapper();
final String url = "http://localhost:xxx/xxx/logout";
LogoutResponse responseObject = null;
try {
String requestData = mapper.writeValueAsString(logoutRequest);
responseObject = logout(url, requestData);
fieldValidation.validateResponse(responseObject, "logout");
// 'fieldValidation' is null then throws nullPointerException
This is my Logout class
package xxx.api.logout;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import xxx.api.domain.logout.LogoutRequest;
import xxx.api.domain.logout.LogoutResponse;
import xxx.dto.log.MessageLog;
import xxx.exception.common.ErrorException;
import xxx.api.logout.LogoutClient;
import xxx.converter.FieldValidation;
#RestController
#RequestMapping(path = "/xxx")
public class LogoutServer {
#Autowired
FieldValidation fieldValidation;
#Autowired
WSLogFactory wsLog;
#PostMapping(value = "/logout", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
public ResponseEntity<?> logout(#RequestHeader(value = "requestId") String requestId,
#RequestBody(required = true) LogoutRequest logoutRequest) throws ErrorException, Exception {
writeLogRequest(logoutRequest, logoutRequest.getClientIP(), "Request", "/xxx/logout");
fieldValidation.validateRequest(logoutRequest, "logout");
try {
LogoutClient logoutClient = new LogoutClient();
LogoutResponse response = logoutClient.logout(logoutRequest);
return new ResponseEntity<LogoutResponse>(response, HttpStatus.OK);
} catch (Exception e) {
throw e;
}
}
This is Logout Controller
#org.springframework.context.annotation.Configuration
#PropertySource("file:${layout.properties_file}")
public class FieldValidation {
// do somethings
}
This is my FieldValidation class.
{
"timestamp": 1550490230074,
"status": 500,
"error": "Internal Server Error",
"exception": "java.lang.NullPointerException",
"message": "No message available",
"path": "/umm/logout"
}
This is return when I call my Logout class.
This is my project structure
xxx.api.login <<< LoginClient.java
xxx.api.logout <<< LogoutClient.java
xxx.converter <<< FieldValidation.java
This is my main program
package xxx;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
I try to replace #Component to #Configuration but still doesn't works.
I don't need 'fieldValidation' in Logout class or another class be a null value.
package xxx.converter;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.Year;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.format.ResolverStyle;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import org.springframework.context.annotation.Configuration;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.validator.routines.BigDecimalValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import com.fasterxml.jackson.databind.ObjectMapper;
import xxx.exception.common.ErrorException;
#Configuration
#PropertySource("file:${layout.properties_file}")
public class FieldValidation {
public void validateObject(Object objResponse, String config) throws Exception {
try {
List<Configuration> confs = objectMapper.readValue(config,
objectMapper.getTypeFactory().constructCollectionType(List.class, Configuration.class));
for (int i = 0; i < confs.size(); i++) {
Configuration configuration = confs.get(i);
Object objValue = getValue(configuration.getFieldName(), objResponse);
Validation validation = new Validation();
BeanUtils.copyProperties(validation, configuration);
isValid(objValue, validation);
if (configuration.getType().equalsIgnoreCase("object")) {
List<Validation> validations = configuration.getValidation();
Class<?> act = Class.forName(configuration.getClassName());
Object objectConfig = act.cast(objValue);
validateObject(objectConfig, validations);
}
}
} catch (Exception e) {
throw e;
}
}
This is full import of FieldValidation class and replace #Configuration and I get this error.
configuration.getFieldName() << error The method is undefined for type Configuration
configuration.getType() << error The method is undefined for type Configuration
configuration.getValidation() << error The method is undefined for type Configuration
configuration.getClassName() << error The method is undefined for type Configuration
I am building RESTAPI in Spring boot+JPA(MYSQL). If I serach for an user id which is not present in the db, I get below response as error:
{
"timestamp": 1545657449608,
"status": 500,
"error": "Internal Server Error",
"exception": "**org.springframework.http.converter.HttpMessageNotWritableException**",
"message": "Could not write content: Unable to find com.bookmyshow.user.User with id asd (through reference chain: com.bookmyshow.user.User_$$_jvst809_0[\"username\"]); nested exception is **com.fasterxml.jackson.databind.JsonMappingException**: Unable to find com.bookmyshow.user.User with id asd (through reference chain: com.bookmyshow.user.User_$$_jvst809_0[\"username\"])",
"path": "/users/asd"
}
UserRegistrationController
package com.bookmyshow.user;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
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;
#RestController
public class UserRegistrationController {
#Autowired
private UserDAO userDAO;
#RequestMapping("/users/{id}")
public ResponseEntity<?> getUser(#PathVariable String id) {
User user= userDAO.getUser(id);
if(user==null) {
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok().body(user);
}
UserDAO
package com.bookmyshow.user;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
#Service
public class UserDAO {
#Autowired
UserRepository userRepository;
public User getUser(String id) {
System.out.println("USERDAO:"+id);
return userRepository.getOne(id);
}
The getOne methods returns only the reference from DB (lazy loading). So basically you are outside the transaction (the Transactional you have been declare in service class is not considered), and the error occur. see documentation
Use findOne instead.
Also see when-use-getone-and-findone-methods-spring-data-jpa
I'm quite new to Spring and I have created a small webservice with Spring-boot, Hibernate and Swagger. Here is my HomeController:
package io.swagger.configuration;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* Home redirection to swagger api documentation
*/
#Controller
public class HomeController {
#RequestMapping(value = "/")
public String index() {
System.out.println("swagger-ui.html");
return "redirect:swagger-ui.html";
}
}
Everything is working well, excepting I don't understand why when I have an Internal Server Error I get a status 200 with this body for example:
{
"timestamp": "2017-12-12T23:52:02.306+0000",
"status": 500,
"error": "Internal Server Error",
"exception": "javax.persistence.PersistenceException",
"message": "org.hibernate.exception.ConstraintViolationException: could not execute statement",
"path": "/example/members/1031/subscriptions"
}
And there is the launcher :
package io.swagger;
import org.apache.commons.logging.LogFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.ExitCodeGenerator;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
#SpringBootApplication
#EnableSwagger2
#ComponentScan(basePackages = "io.swagger")
public class Swagger2SpringBoot extends SpringBootServletInitializer implements CommandLineRunner {
#Override
public void run(String... arg0) throws Exception {
if (arg0.length > 0 && arg0[0].equals("exitcode")) {
throw new ExitException();
}
}
public static void main(String[] args) throws Exception {
LogFactory.getLog(Swagger2SpringBoot.class).warn("test");
new SpringApplication(Swagger2SpringBoot.class).run(args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Swagger2SpringBoot.class);
}
class ExitException extends RuntimeException implements ExitCodeGenerator {
private static final long serialVersionUID = 1L;
#Override
public int getExitCode() {
return 10;
}
}
}
with the configuration :
package io.swagger;
import java.util.List;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
#Configuration
public class WebConfiguration extends WebMvcConfigurerAdapter {
/**
* Make sure dates are serialised in
* ISO-8601 format instead as timestamps
*/
#Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
for (HttpMessageConverter<?> converter : converters) {
if (converter instanceof MappingJackson2HttpMessageConverter) {
MappingJackson2HttpMessageConverter jsonMessageConverter = (MappingJackson2HttpMessageConverter) converter;
ObjectMapper objectMapper = jsonMessageConverter.getObjectMapper();
objectMapper.disable(
SerializationFeature.WRITE_DATES_AS_TIMESTAMPS
);
break;
}
}
}
}
Another one for Swagger:
package io.swagger.configuration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
#Configuration
public class SwaggerDocumentationConfig {
ApiInfo apiInfo() {
return new ApiInfoBuilder().title("**** API").description("No description").license("").licenseUrl("")
.termsOfServiceUrl("www.****.com").version("1.0.0")
.contact(new Contact("", "", "****#****.com")).build();
}
#Bean
public Docket customImplementation() {
return new Docket(DocumentationType.SWAGGER_2).select()
.apis(RequestHandlerSelectors.basePackage("io.swagger.api")).build().apiInfo(apiInfo());
}
}
So why do I have this 200 status if I got a server error? At least I'd like to generate a status 500, 200 means everything was fine, and obviously it's not. Any idea ?
It appears I had implemented a custom error controller generating code from my swagger file, I deleted it and now everything is ok.