I would like to create a #Configuration with the object to format my dates in my API developed in Java (Spring boot), but it is returning some errors
Cannot resolve symbol 'LocalDateTimeSerializer'
Cannot resolve symbol 'LocalDateTimeSerializer'
'addSerializer(com.fasterxml.jackson.databind.JsonSerializer<?>)' in 'com.fasterxml.jackson.databind.module.SimpleModule' cannot be applied to '(LocalDateTimeSerializer)'
here the code
package com.api.parking_control.configs;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import java.time.format.DateTimeFormatter;
#Configuration
public class DateConfig {
public static final String DATETIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
public static LocalDateTimeSerializer LOCAL_DATETIME_SERIALIZER = new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DATETIME_FORMAT));
#Bean
#Primary
public ObjectMapper objectMapper() {
JavaTimeModule module = new JavaTimeModule();
module.addSerializer(LOCAL_DATETIME_SERIALIZER);
return new ObjectMapper()
.registerModule(module);
}
}
Related
I have the following config and java code to map the yml config however the rest, soap and javascript properties are not getting mapped.
Tried the approach given here in accepted answer but no luck
https://stackoverflow.com/a/50410542/10644550
Spring boot version: spring-boot-2.7.0
Any help would be appreciated.
application.yml
bpmn:
prop:
rest:
- http-rest-service
- REST
soap:
- http-soap-service
- SOAP
javascript:
- JAVASCRIPT
- JS-script-worker
test1: 1235
Java code:
package com.example.orchestration.properties;
import lombok.Data;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.List;
import java.util.Set;
#Configuration
#Component
#ConfigurationProperties(prefix = "bpmn.prop")
#PropertySource("application.yml")
#Setter
public class BpmnProperties {
//#Value("${rest}")
Set<String> rest;
//#Value("soap")
Set<String> soap;
// #Value("javascript")
Set<String> javascript;
String test1;
public boolean isRest(String str){
return rest.contains(str);
}
public boolean isSoap(String soap){
return this.soap.contains(soap);
}
public boolean isJs(String js){
return javascript.contains(js);
}
#PostConstruct
public void init(){
System.out.println(rest);
System.out.println("test "+test1);
}
}
Since Spring Boot 2.2 you can simplify your annotations to
#ConfigurationProperties(prefix = "bpmn.prop")
public class BpmnProperties {
and add
#ConfigurationPropertiesScan("com.example.orchestration.properties")
to your main class.
I am trying to connect spring boot application with MySQL for that I have created a interface with name FilterDao which extend JpaRepository class. but whenever I try to make object of implemented class in Service I got this error "Consider defining a bean of type 'com.example.filter.FilterDao' in your configuration" as I am new to spring boot I don't understand this error.
FilterApplication.java
package com.example.filter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
#SpringBootApplication(exclude = {DataSourceAutoConfiguration.class })
public class FilterApplication {
public static void main(String[] args) {
SpringApplication.run(FilterApplication.class, args);
}
}
FilterDao.java
package com.example.filter;
import com.example.filter.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.query.FluentQuery;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
//#Configuration
public interface FilterDao extends JpaRepository<Filter, Integer> {
}
FilterService.java
package com.example.filter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
#Service
public class FilterService {
#Autowired
private FilterDao filterDao;
public List<Filter> getData() {
System.out.println("----------------------HERE-------------");
return filterDao.findAll();
}
}
FilterConnector.java
package com.example.filter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
#RestController
public class FilterConnector {
#Autowired
private FilterService filterService;
#GetMapping("/home")
public List<Filter> home()
{
return this.filterService.getData();
}
}
Project Structure
Annotate FilterDao with #Repository
Seems spring has not created bean for FilterDao repository and you are trying to use that`
#Autowired
private FilterDao filterDao;`
There might different reasons for this exception. Please try the below solution.
Use #EnableJpaRepositories(basePackages = "com.example.filter") with your FilterApplication class.
Use #ComponentScan(basePackages = "com.example.*") with FilterApplication class
Use #Repoitory annotation with FilterDao interface.
Hope this helps. For more details check the below tutorial.
https://javatute.com/jpa/consider-defining-a-bean-of-type-in-your-configuration/
I'm trying to test my application, I've been trying to solve it for 3 days and I looked for stackoverflow and I still couldn't solve it.
My problem is that Autowired is always null, and even though I import everything suggested as
#RunWith( SpringRunner.class )
#SpringBootTest
public class ESGControllerTest {
#Autowired
private ESGController esgController ;
#Test
public void deveRetornarSucesso_QuandoBuscarLatLong(){
System.out.println(this.esgController);
}
}
or
#RunWith( SpringJUnit4ClassRunner.class )
#ContextConfiguration
public class ESGControllerTest {
#Autowired
private ESGController esgController ;
#Test
public void deveRetornarSucesso_QuandoBuscarLatLong(){
System.out.println(this.esgController);
}
}
is always null and gives this error
EDIT:
ESGController
package br.com.kmm.esgeniusapi.controller;
import br.com.kmm.esgeniusapi.dto.CargaDTO;
import br.com.kmm.esgeniusapi.dto.CargaFilter;
import br.com.kmm.esgeniusapi.entity.AreaEmbargada;
import br.com.kmm.esgeniusapi.entity.Carga;
import br.com.kmm.esgeniusapi.entity.ConfiguracaoCarga;
import br.com.kmm.esgeniusapi.exception.CargaException;
import br.com.kmm.esgeniusapi.inteface.HereReverseGeocode;
import br.com.kmm.esgeniusapi.inteface.HereSearch;
import br.com.kmm.esgeniusapi.service.CargaService;
import br.com.kmm.esgeniusapi.service.ConfiguracaoCargaService;
import br.com.kmm.esgeniusapi.service.IbamaService;
import br.com.kmm.esgeniusapi.service.ReverseGeocodeService;
import lombok.extern.slf4j.Slf4j;
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.stereotype.Component;
import org.springframework.web.bind.annotation.*;
import javax.annotation.security.RolesAllowed;
import java.beans.IntrospectionException;
import java.lang.reflect.InvocationTargetException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
#Slf4j
#RestController
#CrossOrigin(origins = "*", maxAge = 3600)
#RequestMapping("/api/")
#RolesAllowed("VIEW")
#Component
public class ESGController {
#Autowired
ReverseGeocodeService reverseGeocodeService;
#Autowired
IbamaService ibamaService;
#Autowired
CargaService cargaService;
#Autowired
ConfiguracaoCargaService configuracaoCargaService;
#GetMapping(path = "reverse-geocode")
public HereReverseGeocode getRoute(#RequestParam final String location) {
Double lat = Double.parseDouble(location.split(",")[0]);
Double lon = Double.parseDouble(location.split(",")[1]);
return this.reverseGeocodeService.getReverseGeocoding(lat, lon);
}
#GetMapping(path = "search")
public List<HereSearch> search(#RequestParam(name = "q") final String query) {
return this.reverseGeocodeService.search(query);
}
....{
//MORE FUNCTIONS
}
}
I edited and put the ESGController as code for more information.
Is ESGController decorated with #Controller or equivalent so that a bean of that class actually exist in the context?
Is the test class in the same package hierarchy as the rest of the application?
#SpringBootTest by default starts searching in the current package of
the test class and then searches upwards through the package
structure, looking for a class annotated with #SpringBootConfiguration
from which it then reads the configuration to create an application
context.
We are trying to externalize a date format in a bean for a field using the #JSONFormat so as to make it configurable.
#JsonFormat(pattern = "${application.date.format}")
private Date creationtime;
OR
#JsonFormat(pattern = "yyyy-MM-DD")
private Date creationtime;
It works when I give a standard String value. However when we externalize the value as shown in the first one, I am getting an exception saying :
java.lang.IllegalArgumentException: Illegal pattern character 'p'
to assign a variable value to the second approach we need a final String which is a constant expression. How can I make the pattern configurable?
Jackson uses JacksonAnnotationIntrospector to handle standard annotations. We can extend this mechanism providing our extra introspector together with default. To do that we can use pair method.
Simple custom implementation could look like below:
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.databind.AnnotationIntrospector;
import com.fasterxml.jackson.databind.introspect.Annotated;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import java.util.Objects;
public class SpringJacksonAnnotationIntrospector extends AnnotationIntrospector {
private final ApplicationContext context;
#Autowired
public SpringJacksonAnnotationIntrospector(ApplicationContext context) {
this.context = Objects.requireNonNull(context);
}
#Override
public JsonFormat.Value findFormat(Annotated memberOrClass) {
JsonFormat annotation = _findAnnotation(memberOrClass, JsonFormat.class);
if (annotation == null) {
return null;
}
String basePattern = annotation.pattern();
if (basePattern.startsWith("$")) {
String pattern = context.getEnvironment().getProperty(basePattern.substring(2, basePattern.length() - 1));
return JsonFormat.Value.forPattern(pattern);
}
return null;
}
#Override
public Version version() {
return new Version(1, 0, 0, "", "org.company", "spring-jackson");
}
}
Above implementation reuses JsonFormat annotation but we can introduce new one to avoid confusion. We need to register our custom introspector. There is many different ways how to do that and it depends from your Spring configuration. We can do that for example, like below:
import com.example.jackson.SpringJacksonAnnotationIntrospector;
import com.fasterxml.jackson.databind.AnnotationIntrospector;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.List;
#EnableWebMvc
#Configuration
public class WebConfig implements WebMvcConfigurer {
#Autowired
private ApplicationContext context;
#Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
//JSON
AnnotationIntrospector pairedIntrospectors = AnnotationIntrospector.pair(springJacksonAnnotationIntrospector(),
new JacksonAnnotationIntrospector());
converters.add(new MappingJackson2HttpMessageConverter(
Jackson2ObjectMapperBuilder.json()
.annotationIntrospector(pairedIntrospectors)
.build()));
}
#Bean
public SpringJacksonAnnotationIntrospector springJacksonAnnotationIntrospector() {
return new SpringJacksonAnnotationIntrospector(context);
}
}
Since now, Spring's global configuration should be used to override date format.
See also:
Configuring ObjectMapper in Spring
SpringBoot: Consume & Produce XML with a Custom Serializer + Deserializer
How config gson in Spring boot?
How do I get a property value from an ApplicationContext object? (not using an annotation)
Can you please provide me with an example of primitive type dependency injection in spring boot. I have tried once but TestConfiguration which is my custom bean definition class does not detect or does not recognize by spring boot application.
here is my code,
//Engine class
package com.test2.projectTest;
import org.springframework.stereotype.Component;
#Component
public class Engine {
private String msg;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
//Test Configuration
package com.test2.projectTest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
#Configuration
public class TestConfiguration {
#Bean("engine")
public Engine engine(){
Engine engine = new Engine();
engine.setMsg("Message is injected");
return engine;
}
}
//spring main application
package com.test2.projectTest;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
#SpringBootApplication
public class ProjectTestApplication {
public static void main(String[] args) {
SpringApplication.run(ProjectTestApplication.class, args);
}
}
//JUnit Test
package com.test2.projectTest;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.ApplicationContext;
import
org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.test.context.junit4.SpringRunner;
#RunWith(SpringRunner.class)
#SpringBootTest
public class ProjectTestApplicationTests {
#Test
public void contextLoads() {
ApplicationContext apc = new
AnnotationConfigApplicationContext(TestConfiguration.class);
Engine e = (Engine) apc.getBean("engine");
e.getMsg();
}
}
// Output - org.springframework.beans.factory.NoSuchBeanDefinitionException:
No bean named 'engine' available
Please suggest any solution to above issue
Add #componentscan annotation in main class and provide engine class package and it should work