I am using Jasypt to encrypt some of the fields before saving into MongoDB, below are my codes.
In my code, I have included JaVers and I'm using it for audit purpose.
In the onBeforeSave() method, I have encrypted some of the fields before save in a index in MongoDB and this part is working fine. The part not working is, when JaVers create the audit, the fields that I encrypted are still in clear text, in jv_snapshot index. May I know how can I config JaVers so that it will be able to record the audit same as the onBeforeSave()?
PersonService.createPerson() this method should be creating a new record in Javers, but it is clear text. Can anyone please help or advise?
#Configuration
public class JasyptConfig{
#Bean
public AES256TextEncryptor aes256Encryptor(){
AES256TextEncryptor encryptor = new AES256TextEncryptor();
encryptor.setPassword("password");
return encryptor;
}
}
#Component
public class MongoBeforeSave extends AbstractMongoEventListener<Object>{
#Autowired
AES256TextEncryptor encryptor;
#Override
public void onBeforeSave(BeforeSaveEvent<Object> event){
Document eventObj = event.getDocument();
List<String> fields = Arrays.asList("address,creditcard".split(","));
for(String key: eventObj.keySet()){
if(fields.contains(key)){
String text = eventObj.get(key).toString();
eventObj.put(key, encryptor.encrypt(text));
}
}
super.onBeforeSave(event);
}
}
#Getter
#Setter
public class NewPersonDTO{
private String name;
private String address;
private String creditcard;
}
#Getter
#Setter
public class Person{
private String name;
private String address;
private String creditcard;
}
#RestController
#RequestMapping("/person")
public class PersonController{
private final PersonService personService;
#PostMapping
public void createPerson(#RequestBody NewPersonDTO newPerson){
personService.createPerson(newPerson);
}
}
#Service
#RequiredArgsConstructor
public class PersonService{
private final PersonRepository personRepository;
public void createPerson(NewPersonDTO newPerson){
Person p = new Person();
//then transfer the fields value from NewPersonDTO to Person
personRepository.save(p);
}
}
#Repository
#JaversSpringDataAuditable
public interface PersonRepository extends MongoRepository<Person, String>{
}
Related
I am trying to write an interface that extends CrudRepository that will return a list of a particular field. When I use that method, I get ConverterNotFoundException. I have two questions:
Is there a specific Spring Boot query if I want a list containing a specific field?
Am I implementing the converter correctly? I am not sure how to call WebConfig.
// EmployeeRepository.java
#Repository
public interface EmployeeRepository extends CrudRepository<Employee, Long> {
List<String> findByEmployeeId(String employeeId); // ConverterNotFoundException. Expecting list of employee's full name
}
// EmployeeToStringConverter.java
#Component
public class EmployeeToStringConverter implements Converter<Employee, String> {
#Override
public String convert(Employee source) {
return source.getFullName();
}
}
// WebConfig.java
#Configuration
public class WebConfig implements WebMvcConfigurer {
#Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new EmployeeToStringConverter());
}
}
// Employee.java
#Entity
#Data
#NoArgsConstructor
#Getter
#Table(name = "employees")
public class Employee {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="Id")
private Long id;
#Column(name="FullName")
private String fullName;
#Column(name="NickName")
private String nickName;
public HubKey(String fullName, String nickName) {
this.fullName = fullName;
this.nickName = nickName;
}
}
// Exception when calling EmployeeRepository.findByEmployeeId()
org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [com.jon.demo.domain.entity.Employee] to type [java.lang.String]
The converter you have registered in the WebMvcConfigurer is used for formatting data in the view(The view in MVC).
You should add converter to Spring Data related custom conversions beans, every Spring Data sub project has its own registration entry there.
Please read the Spring Data related docs.
I am trying to update my database (postgresql) in my spring boot app with some form information that I will get from an angular 8 form. How can I complete the code below to do so ?
PS : I have no access to the front devs, so no access to the angular code.
My Entity :
#Entity
#Data
#Table(name = "person")
#AllArgsConstructor
#NoArgsConstructor
public class PersonEntity implements java.io.Serializable {
#Id
#Column(name = "id_person")
private int idPerson;
#Column(name = "name")
private String name;
#Column(name = "alive")
private Boolean alive;
}
My Mapping class :
#Data
public class PersonForm {
#NotBlank
private String idPerson;
#NotBlank
private String name;
private boolean alive;
}
My Repository :
#Repository
public interface IPersonRepository extends JpaRepository<PersonEntity, String> {
}
My Controller :
#RequestMapping(value = "person")
public class PersonController {
private final PersonService personService;
public PersonController(PersonService personService) {this.personService = personService;}
#PostMapping(value = "savePerson")
#ResponseBody
public ResponseEntity<PersonEntity> savePerson(#RequestBody final PersonForm form) {
return ?
}
}
My Service :
#Transactional
#Service
public class PersonService {
#Autowired
private IPersonRepository personRepository;
public IPersonRepository(IPersonRepository personRepository) {
this.personRepository = personRepository;
}
Maybe this is enough to work.
Have others ways to do it, this is only example that complements your line of thought.
If you get a compilation error or another error, let me know :)
First you need create your object PersonEntity and sent it to your service.
#RequestMapping(value = "person")
public class PersonController {
private final PersonService personService;
public PersonController(PersonService personService) {this.personService = personService;}
#PostMapping(value = "savePerson")
#ResponseBody
public ResponseEntity<PersonEntity> savePerson(#RequestBody final PersonForm form) {
PersonEntity entity = new PersonEntity(form);
entity = personService.save(entity);
return ResponseEntity.ok(entity);
}
}
In your service, you will call the save method from repository implementation.
#Transactional
#Service
public class PersonService {
#Autowired
private IPersonRepository personRepository;
public IPersonRepository(IPersonRepository personRepository) {
this.personRepository = personRepository;
}
public PersonEntity save(PersonEntity entity) {
return personRepository.save(entity);
}
}
After it you will create ResponseEntity in the method PersonController.savePerson
I'm using Neo4j to create graphs. The below codes is an example for spring data Neo4j. I can save a node entity when no id property value is provided.
But how to save a node entiry with a specific id property value?
Model Class:
#Data
#NodeEntity
public class Person {
#Id
#GeneratedValue
private Long id;
private String name;
private String title;
#Relationship(type = "ACTED_IN")
private List<Movie> movies = new ArrayList<>();
}
Repository Class
public interface PersonRepository extends Neo4jRepository<Person, Long> {
#Query("MATCH (n:Person {name:{name}}) RETURN n")
List<Person> findByName(#Param("name") String name);
}
Controller Class
#RestController
#RequestMapping("/person")
public class PersonController {
#Autowired
private PersonRepository personRepository;
#PostMapping("/save")
public Map save(#RequestBody Person person) {
Map resultMap = new HashMap();
String code = "200";
String msg = "success";
// It can save success when no id property value is provided
Person savedPerson = personRepository.save(person);
resultMap.put("code", code);
resultMap.put("msg", msg);
resultMap.put("data", savedPerson);
return resultMap;
}
}
I have tried it successfully and can be easily done provide the "id" should be
String not Long
Domain/DAO class:
#Id
#GeneratedValue(strategy = Neo4JCustomIdStrategy.class)
String id;
Repository Class:
#Repository
public interface PersonRepository extends Neo4jRepository<Person, String>{
}
And lastly, custom implementation of Strategy:
public class Neo4JCustomIdStrategy implements IdStrategy {
#Override
public Object generateId(Object entity) {
return String.valueOf(entity.hashCode());
}
}
The library I am using is spring-data-neo4j
I want to get some data from Neo4j using Spring boot, but I always get nothing. In other words, it seems that java cannot get the data from the neo4j database.
The code is written according to the neo4j Spring tutorial.https://neo4j.com/developer/spring-data-neo4j/
domain class
#NodeEntity
public class Weather {
#Id
#GeneratedValue
private Long id;
private String name;
#Relationship(type = "HAS_INSTANCE")
private List<Instance> instances = new ArrayList<>();
#Relationship(type = "HAS_CHARACTERISTIC")
private List<Characteristic> characteristics = new ArrayList<>();
...
}
repository class
#RepositoryRestResource(collectionResourceRel = "weathers", path = "weathers")
public interface WeatherRepository extends Neo4jRepository<Weather, Long> {
}
service class
#Service
public class WeatherService {
private final WeatherRepository weatherRepository;
public WeatherService(WeatherRepository weatherRepository){
this.weatherRepository = weatherRepository;
}
#Transactional(readOnly = true)
public Iterable<Weather> findAll(){
Iterable<Weather> result = weatherRepository.findAll();
return result;
}
}
controller class
#RestController
#RequestMapping("/")
public class WeatherController {
private final WeatherService weatherService;
public WeatherController(WeatherService weatherService){
this.weatherService = weatherService;
}
#GetMapping("/findAll")
public Iterable<Weather> findAll(){
return weatherService.findAll();
}
}
And the username and password configuration are in the application.properties.
Could someone help me about it? Thanks!
I am trying to a write a spring boot controller which can return the result of a native query as json. I will be passing the query as input parameter and the return must be result of the query. Is there a way to do this? I know the http rpc help on this. The query can be anything and the system must accept it and must respond with the result as json.
For example if I pass the request as select * from employee it must respond with result of query as json.
Simply make every function returning:
Map<String, Object>
It will automatically map the object property and value. That means a json object is an instance of Map. If you are managing an array of it, enclose it with a List:
List<Map<String, Object>>
and finally the ResponseEntity becomes:
ResponseEntity<List<Map<String, Object>>>
You could actually use Spring JDBC for that,
Repo
#Repository
public class FooRepo {
#Autowire
private JdbcTemplate jdbcTemplate;
public Object returnDataForQuery(String sql) {
return jdbcTemplate.queryForObject(sql, Object.class); // You could define a proper class if you know the return Type else returning plain object is more then enough
// return jdbcTemplate.queryForList(sql, Object.class) Incase Multiple Data
}
}
Model
public class FooDto {
private String query;
// Getter, Setter & No Args Constructor (or) Lombok
}
Controller
#Autowire
private FooRepo fooRepo;
#PostMapping(value = "/postData", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity postData(#RequestBody FooDto foo) {
return ResponseEntity.ok(fooRepo.returnDataForQuery(foo.getQuery);
}
This is just a overview, you could bend it.As for your result output concern you ResponseEntity will take care of it
SpringBoot
//Controller Class
#RestController
#RequestMapping("/employee")
public class EmployeeController {
#Autowired
private EmployeeService employeeService;
#GetMapping("/all")
public List<Employee> getAllEmplpyee() {
logger.info("get All Employeee");
return employeeService.getAllEmployeeService();
}
}
//ServiceImpl
#Service
public class EmployeeService {
private static final Logger logger = LoggerFactory.getLogger(EmployeeService.class);
#Autowired
private EmployeeRepository employeeRepository;
public List<Employee> getAllEmployeeService() {
logger.info(getClass().getName()," invked getAllEmployee");
List<Employee> empBo = employeeRepository.findAll();
return copyPropertiesValues(empBo);
}
}
//DAO
#Component
public interface EmployeeRepository extends JpaRepository<Employee, String>{
}
//Model
#Entity
#Table(name = "employees")
public class Employee {
#Id
#Column(name = "employeeNumber",nullable=false)
private String employeeNumber;
#Column(nullable=false)
private String lastName;
#Column(nullable=false)
private String firstName;
#Column(nullable=false)
private String extension;
#Column(nullable=false)
private String email;
#Column( nullable=false)
private String officeCode;
#Column(nullable=false)
private String reportsTo;
#Column(nullable=false)
private String jobTitle;
//GETTER SETTER
}
//application.properties
spring.jpa.hibernate.ddl-auto=update
spring.jpa.open-in-view=true
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
logging.level.org.hibernate.SQL=debug
logging.level.org.hibernate.type.descriptor.sql=trace
spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=****