Jackson Trasformation json data in bean - json

I have a problem with the transformation of json in bean whene the bean have a date.
The client send, for example, the date 2018-07-13 11:30:00 and jasckson store in the bean the date 2018-07-13 13:30:00.
Can you help me?
I'm using spring-boot 1.5.10 and jackson 1.9.10

Try create a #Configuration class and ad this 2 bean definitions:
#Bean
public JavaTimeModule timeModule(DateTimeFormatter dateTimeFormatter){
JavaTimeModule timeModule = new JavaTimeModule();
timeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(dateTimeFormatter));
timeModule.addSerializer(ZonedDateTime.class, new ZonedDateTimeSerializer(dateTimeFormatter));
return timeModule;
}
#Bean
public ObjectMapper objectMapper(JavaTimeModule timeModule) {
return Jackson2ObjectMapperBuilder.json()
.failOnUnknownProperties(false)
.featuresToEnable(com.fasterxml.jackson.core.JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS)
.featuresToDisable(com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.modules(timeModule)
.build();
}

Related

How to simulate a CDI #Produces annotation on a JUnit

I am writing a JUnit test for a class which does something like:
org.glassfish.jersey.client.JerseyClient client = getHTTPClient(SSLContextFactory.getContext(), connectTimeout, readTimeout, true);
client.register(CustomJAXBContextProvider.class); // subclass of javax.ws.rs.ext.ContextResolver<JAXBContext>
client.property(MarshallerProperties.JSON_INCLUDE_ROOT, true);
WebTarget webTarget = client.target(contextPath);
Response response = webTarget.request(MediaType.APPLICATION_JSON.get()
return response.readEntity(ResponseModel.class);
The application runs inside a WebLogic container and has another class with a CDI #Produces annotation:
public class ObjectMapperProvider {
private ObjectMapper objectMapper;
#Produces
public ObjectMapper objectMapper() {
objectMapper = new ObjectMapper();
objectMapper.registerModule(new JSR310Module());
objectMapper.configure(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES, false);
return objectMapper;
}
}
When I run the JUnit test from outside WebLogic I get an error
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:
Unrecognized field "fieldName" (class ResponseModel), not marked as
ignorable
Because the JSON response contains a field which is not declared in the model and the JUnit is not obtaining the ObjectMapper through the #Produces annotation but getting a default one. The JAXBContext is EclipseLink MOXy.
My question is: How do I get the code tested by my JUint to instantiate ObjectMapper as returned from ObjectMapperProvider instead of a default one lacking the DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES, false?
We cover this exact scenario using Mockito. Depending on how JaxBContext is created, you could use a spy to return a mock. Without posting your complete test code and the class under test, it's hard to give a more complete answer than that.

JPA non-entity with select database result to List<object[]>

I want to create a REST API for Android using my yii2 fremowork blocking site and its database.
I did not need to create a table in the database, but I would only SELECT and INSERT the information in the desired style.
How can I do this in the Java Spring boot application?
I need to download the information you need
This is my application.properties file
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost/uzaart_teda?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=
spring.jpa.hibernate.ddl-auto=update
spring.jpa.generate-ddl=true
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults = false
My Service implement class
#Service
public class ProductsServiceimpl implements ProductsService{
#Autowired
ProductsRepository productsRepository;
#Override
public List<ProductsDto> getProducts() {
List<ProductsDto> list=new ArrayList<>();
list.add(new ProductsDto(1,2,"anvar",4,5,6,7));
list.add(new ProductsDto(1,2,"sanjar",4,5,6,7));
/*this is my need --->*/
List<Object[]> objects=productsRepository.selectProducts();
/******/
System.out.println(objects.size());
return list;
}
}
This is my Repository
public interface ProductsRepository extends JpaRepository<Object[],Long> {
#Query(value = "SELECT a.id,a.tovar_id,t.nom_sh,a.kol_ost,a.kol_in_ost, a.opt1 AS sot,a.opt1_in AS sot_in FROM s_tovar t,asos_slave a,asos WHERE a.del_flag=1 AND (asos.tur_oper=1 OR asos.tur_oper=4 OR asos.tur_oper=5) AND a.asos_id=asos.id AND a.tovar_id=t.id AND (a.kol_ost>0 OR a.kol_in_ost>0) AND asos.client_id = 4 AND (((t.nom LIKE \"%0001%\") OR (t.nom LIKE \"%0001%\"))) ORDER BY t.nom,a.srok",nativeQuery = true)
public List<Object[]> selectProducts();
}
My result.
Error message
1.
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2019-07-16 16:20:19.006 ERROR 7328 --- [ main] o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'controller': Unsatisfied dependency expressed through field 'productsService';
2.
[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
3.
at com.uz.shopapi.ShopApiApplication.main(ShopApiApplication.java:10) [classes/:na]
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'productsServiceimpl':
This is wrong:
public interface ProductsRepository extends JpaRepository<Object[],Long> {
JpaRepository must be of type of class that is annotated with #Entity:
public interface ProductsRepository extends JpaRepository<Product,Long> {
like this:
#Entity
class Product {
…
}
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.multiple-modules.annotations
You have to create entities to use Spring Data JPA, because it needs the entity metadata to create query.
After that, you can use custom object to select result into it.
public interface ProductsRepository extends JpaRepository<Products,Long> {
#Query(select new com.xyt.CustomObject(a.tovar_id,t.nom_sh ... ) from ENTITY1 a, ENTITIY2 t where ...)
public List<CustomObject> selectProducts();
}
Alternatively, you can use simple JDBC template to create sql query with your custom object mapper. In this way you do not need to create those entities.

How to access java abc.properties file values in json formate using Spring framework

i'm trying to access the values of properties file in spring framework. now i have bean file and controller. so how to access properties file value in json formate using bean
For accessing single value can be used Spring annotations "PropertySource" and "Value".
#PropertySource("classpath:application.properties")
public class SomeClass {
#Value("${some.property}")
private String someProperty;
...
}
For accessing/looping all spring properties, check this solution looping-through-all-the-properties-in-a-file-with-spring-and-java
Controller sample code:
#RestController
public class PropertiesController {
#Autowired
Properties props;
#RequestMapping(value = {"/properties"}, method = RequestMethod.GET, produces= MediaType.APPLICATION_JSON_UTF8_VALUE)
public Set<Map.Entry<Object, Object>> getProperties() {
return props.entrySet();
}
}
if you are Using spring-boot then add spring-actuator dependency which by defaults expose /env endpoint and spits out all the properties loaded in the spring container in json format.

How to configure cloud datasource for MySQL on Bluemix?

How do I create a datasource for cloud in MySQL when running on Bluemix? If there are any Java configuration examples available, please share. How do I make Hibernate create tables and why do I get this error?
Error creating bean with name 'entityManagerFactory' defined in
com.covenant.app.config.root.DatabaseConfig: Unsatisfied dependency
expressed through constructor argument with index 0 of type
[org.springframework.jdbc.datasource.DriverManagerDataSource]: : No
qualifying bean of type
[org.springframework.jdbc.datasource.DriverManagerDataSource] found
for dependency: expected at least 1 bean which qualifies as autowire
candidate for this dependency. Dependency annotations: {}; nested
exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type
[org.springframework.jdbc.datasource.DriverManagerDataSource] found
for dependency: expected at least 1 bean which qualifies as autowire
candidate for this dependency. Dependency annotations: {}
My database Config class
#Configuration
#Profile("cloud")
#EnableTransactionManagement
public class CloudDatabaseConfig extends AbstractCloudConfig {
#Bean
public DataSource inventoryDataSource() {
return connectionFactory().dataSource("mysql");
}
#Bean(name = "namingStrategy")
public ImprovedNamingStrategy getNamingStrategy(){
ImprovedNamingStrategy namingStrategy = new CDCustomNamingStrategy();
return namingStrategy;
}
#Bean(name="dataSource")
public BasicDataSource dataSource() throws PropertyVetoException {
BasicDataSource bean = new BasicDataSource();
bean.setDriverClassName("com.mysql.jdbc.Driver");
bean.setUrl("jdbc:mysql://localhost:3306/bluemix?useUnicode=true&characterEncoding=UTF-8");
bean.setUsername("root");
bean.setPassword("root");
return bean;
}
#Bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource, ImprovedNamingStrategy ins) {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource);
entityManagerFactoryBean.setPackagesToScan(new String[]{"com.covenant.app.model"});
entityManagerFactoryBean.setLoadTimeWeaver(new InstrumentationLoadTimeWeaver());
entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
Map<String, Object> jpaProperties = new HashMap<String, Object>();
jpaProperties.put("database", "mysql");
jpaProperties.put("hibernate.hbm2ddl.auto", "update");
jpaProperties.put("hibernate.show_sql", "true");
jpaProperties.put("hibernate.format_sql", "true");
jpaProperties.put("hibernate.use_sql_comments", "true");
jpaProperties.put("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
jpaProperties.put("hibernate.ejb.naming_strategy", ins);
entityManagerFactoryBean.setJpaPropertyMap(jpaProperties);
return entityManagerFactoryBean;
}
}
My manifest.yml file on Bluemix:
---
applications:
- name: lordthankyou
path: target/ideals.war
services:
- mysql
env:
SPRING_PROFILES_ACTIVE: cloud
I get the following errors:
Error creating bean with name 'userService': Injection of autowired
dependencies failed; nested exception is
org.springframework.beans.factory.BeanCreationException: Could not
autowire field: private com.covenant.app.dao.UserRepository
com.covenant.app.services.UserService.userRepository; nested exception
is org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'userRepository': Injection of persistence
dependencies failed; nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type [javax.persistence.EntityManagerFactory] is
defined
Finally I got It working I just added an environment variable to activate cloud profile in manifest.yml and removed extends AbstractCloudConfig as it was also searching for mongodb .After these changes It Started working and now I can run spring mvc on blue mix.

getContext() method of CustomContextResolver is not called by Jackson

I am struggling with this issue for days now and have no clue how to solve this. Any quick help will be grateful.
I need to convert LocalDate from JSON string which I am receiving from REST service build using apache CXF and jackson. I wrote custom ContextResolver and registered JavaTimeModule in Mapper object.
When I run the application, default constructor is called, that means it has been loaded, but getContext() method which returns ObjectMapper never gets called.
I have registered same ContextResolver in server and client side.
All dependencies are in place(jackson databind, core, annotation, datatype-jsr310).
I am able to fetch JSON response when I hit REST URI directly in browser. Issue comes when I call same URI annotated method from client code
Below is my client code.
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
#Provider //makes this bean a Provider
public class LocalDateObjectMapperContextResolver implements ContextResolver<ObjectMapper>{
private final ObjectMapper MAPPER;
public LocalDateObjectMapperContextResolver() {
MAPPER = new ObjectMapper();
MAPPER.registerModule(new JavaTimeModule());
MAPPER.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
}
#Override
public ObjectMapper getContext(Class<?> type) {
return MAPPER;
}
}
<jaxrs:client id="testclient"
serviceClass="package1.RESTService"
username="abc"
password="abc"
address="$serviceURL">
<jaxrs:features>
<bean class="org.apache.cxf.transport.common.gzip.GZIPFeature"/>
<cxf:logging/>
</jaxrs:features>
<jaxrs:providers>
<bean class="org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider"/>
<bean class="mypackage.LocalDateObjectMapperContextResolver"/>
</jaxrs:providers>
</jaxrs:client>
Same way, This contextResolver is registered on server side also under
<jaxrs:server>
.....
<jaxrs:providers>
<bean class="org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider"/>
<bean class="mypackage.LocalDateObjectMapperContextResolver"/>
</jaxrs:providers>
</jaxrs:server>
Any reason why getContext is not called?
I also tried by extending ObjectMapper and registering javaTimeModule there, but dont know how to register customObjectMapper in Jackson flow. I just put default constructor for testing, And it does get called while application startup, but then again, No results, I still get same error.
Error: No suitable constructor found for type [simple type, class java.time.LocalDate]: can not instantiate from JSON object (need to add/enable type information?)
I had exactly the same problem #peeskillet describes in question comment.
I was using Jackson dependencies from version 2 and jackson-jaxrs from version 1.
All solved when moved all dependencies to version 2.
If you are using Maven you can add following two maven dependency.
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
</dependency>
And Add following code snippet.
#Configuration
public class CxfConfig {
#Component
#javax.ws.rs.ext.Provider
public static class JacksonJaxbJsonProvider
extends com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider {
#Autowired
private ObjectMapper objectMapper;
#PostConstruct
public void init() {
objectMapper.registerModule(new Jdk8Module());
}
}
}