file upload angular - spring boot - mysql - mysql

I had a working post api sending formdata to the back end and posting it to the DB .
when I added an input file type to the form and appended it the dataform, I got errors.
I always have this error:
"error: "Internal Server Error"
message: "Unrecognized field "file" (class org.sid.model.User), not marked as ignorable (6 known properties: "fileName", "id", "email", "name", "password", "logo"])↵ at [Source: (String)"{"name":"ss","email":"sss","password":"ssssssss","file":"C:\fakepath\ooredoo_758118.png"}"; line: 1, column: 58] (through reference chain: org.sid.model.User["file"])"
path: "/users"
"
Controller
#CrossOrigin(origins = { "http://localhost:4200", "http://localhost:9000" }, maxAge = 36000)
/*#RequestMapping(value="/users" , method=RequestMethod.POST)*/
#RequestMapping(value="/users" , headers = ("content-type=multipart/*"), method = RequestMethod.POST,
consumes = MediaType.MULTIPART_FORM_DATA_VALUE ,
produces = { "application/json" }
)
public User save(#RequestPart("file") MultipartFile f ,
#RequestPart ("user") String u)
throws JsonParseException, JsonMappingException, IOException{
User user = new ObjectMapper().readValue(u, User.class) ;
user.setLogo(f.getBytes());
return userRepository.save(user);
}
User.java
#Entity
public class User {
#Id #GeneratedValue
private Long id ;
private String name ;
private String email ;
private String password ;
#Column(name="logo")
private byte[] logo;
#Column(name="file_name")
private String fileName ;
}
mainApplication.java
#SpringBootApplication
public class MyChebbaApplication {
public static void main(String[] args) {
SpringApplication.run(MyChebbaApplication.class, args);
}
#Bean
public MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory();
factory.setMaxFileSize("10240KB");
factory.setMaxRequestSize("10240KB");
return factory.createMultipartConfig();
}
}
Clien Side
component.html
<div class="container" >
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Register</div>
<div class="panel-body">
<form class="form-horizontal" #form="ngForm" (ngSubmit)="onSubmit(form)">
<div class="form-group">
<label for="name" class="control-label col-md-4">Nom Complet</label>
<div class="col-md-6">
<input id="name" type="text" name="name" #userName="ngModel" ngModel class="form-control" required>
</div>
</div>
<div class="form-group">
<label for="email" class="control-label col-md-4">E-mail Address</label>
<div class="col-md-6">
<input id="email" type="email" name="email" #userEmail="ngModel" ngModel class="form-control" required>
</div>
</div>
<!-- <div class="form-group">
<label for="phone" class="control-label col-md-4">Phone number</label>
<div class="col-md-6">
<input id="phone" type="phone" name="phone" #phone="ngModel" ngModel class="form-control" >
</div>
</div> -->
<div class="form-group">
<label for="password" class="control-label col-md-4">Password</label>
<div class="col-md-6">
<input id="password" type="text" name="password" #password="ngModel" ngModel class="form-control" required>
</div>
</div>
<div class="form-group">
<label for="file" class="control-label col-md-4">File Upload</label>
<div class="col-md-6">
<input
type="file"
name="file"
accept="image/*"
(change)="onFileSelected($event)"
ngModel class="form-control" >
</div>
</div>
<div class="form-group">
<div class="col-md-8 col-md-offset-4">
<button type="submit" class="btn btn-primary"
[disabled]="form.invalid">
Register
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
component.ts
selectedFile: File = null ;
constructor(private userService: UserService) { }
ngOnInit() {
}
onFileSelected(event) {
console.log(event) ;
this.selectedFile = event.target.files[0] ;
}
onSubmit(form: any) {
let fd = new FormData() ;
const user = form.value ;
fd.append('user' , JSON.stringify(user)) ;
fd.append('file' , this.selectedFile ) ;
console.log(fd) ;
this.userService.register(fd )
.then((resp) => {
this.userService.logUserIn(resp) ;
}) ;
}
user.service.ts
register(fd: FormData ): Promise<UserData> {
return this.http.post(`${CONFIG.API_URL}/users`, fd)
.toPromise()
.then((response) => {
let token = response.json().token ;
let user = response.json() ;
let userData = new UserData(token, user) ;
this.router.navigate(['/users']);
return userData ;
});
}

this means that your JSON String u doesn't contain "file" field. In order to ignore missing fields please use this:
ObjectMapper mapper = new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
mapper.readValue(u, User.class);
...
Good luck.

It means that User doesn't have a property file.
To solve that, just disable that config in applicatgion.properties.
pring.jackson.deserialization.fail-on-unknown-properties=true

Related

React - HTML form validation doesn't work

I work on a React project. I wrote HTML codes for create form. There is validation in HTML scripts. I wrote validations but validations doesn't work. The code is below. For example I want the relevant field to be red when the name is not entered or I want it to give a warning message when the name does not comply with the text rules. I must do it without any library. How can I fix it ?
import React, { Component } from 'react'
import EmployeeService from '../services/EmployeeService';
class CreateEmployeeComponent extends Component {
constructor(props) {
super(props)
this.state = {
id: this.props.match.params.id,
firstName: '',
lastName: '',
emailId: ''
}
}
componentDidMount(){
if(this.state.id === '_add'){
return
}else{
EmployeeService.getEmployeeById(this.state.id).then( (res) =>{
let employee = res.data;
this.setState({firstName: employee.firstName,
lastName: employee.lastName,
emailId : employee.emailId
});
});
}
}
saveOrUpdateEmployee = (e) => {
e.preventDefault();
let employee = {firstName: this.state.firstName, lastName: this.state.lastName, emailId: this.state.emailId};
console.log('employee => ' + JSON.stringify(employee));
// step 5
if(this.state.id === '_add'){
EmployeeService.createEmployee(employee).then(res =>{
this.props.history.push('/employees');
});
}else{
EmployeeService.updateEmployee(employee, this.state.id).then( res => {
this.props.history.push('/employees');
});
}
}
changeFirstNameHandler= (event) => {
this.setState({firstName: event.target.value});
}
changeLastNameHandler= (event) => {
this.setState({lastName: event.target.value});
}
changeEmailHandler= (event) => {
this.setState({emailId: event.target.value});
}
cancel(){
this.props.history.push('/employees');
}
getTitle(){
if(this.state.id === '_add'){
return <h3 className="text-center">Add Employee</h3>
}else{
return <h3 className="text-center">Update Employee</h3>
}
}
onSubmit = e => {
e.preventDefault();
}
render() {
return (
<div>
<br></br>
<div className = "container">
<div className = "row">
<div className = "card col-md-6 offset-md-3 offset-md-3">
{
this.getTitle()
}
<div className = "card-body">
<form onSubmit={this.onSubmit} noValidate>
<div className = "form-group">
<label for="validationCustom01" class="form-label">First name</label>
<input type='text' maxLength={20} pattern='[A-Za-z]' placeholder="First Name" name="firstName" className="form-control"
value={this.state.firstName} onChange={this.changeFirstNameHandler} required/>
</div>
<div className = "form-group">
<label> Last Name: </label>
<input type='text' maxLength={20} pattern='[A-Za-z]'class="form-control" placeholder="Last Name" name="lastName" className="form-control"
value={this.state.lastName} onChange={this.changeLastNameHandler} required/>
</div>
<div className = "form-group">
<label> Email Id: </label>
<input type='email' maxLength={35} pattern='[A-Za-z]' placeholder="Email Address" name="emailId" className="form-control"
value={this.state.emailId} onChange={this.changeEmailHandler} required/>
</div>
<button type="submit" className="btn btn-success" onClick={this.saveOrUpdateEmployee}>Save</button>
<button className="btn btn-danger" onClick={this.cancel.bind(this)} style={{marginLeft: "10px"}}>Cancel</button>
</form>
</div>
</div>
</div>
</div>
</div>
)
}
}
export default CreateEmployeeComponent
Remove noValidate from your <form> element.
Additionally, I've personally found that Formik and Yup can be a helpful library.
(Sorry I missed that "no libraries" wasa constraint)
Edit:
I was a muppet and forgot to change the pattern
You can do one of 2 things:
Remove maxLength and change the pattern to pattern="[A-Za-z]{1,20}"
Where 20 will be the new max-length (so 20 or 35, depending on the field)
Only change the pattern to be pattern="[A-Za-z]+"
The + is needed to ensure 1 or more of the [A-Za-z] regex is done. https://regexr.com/
Also don't forget to remove noValidate from your <form> element.
This answer may also prove helpful in setting custom validity status messages and callbacks.

Form data to accept nested schema in Javascript

I have a JSON schema which i am trying to make my form tailor, but the schema has nested objects and arrays like so:
{
"person": {
"firstName":"Kay",
"lastName":"Young"
}
"addressDetails":[
{
"line1": "line1",
"line2": "line2"
}]
}
HTML
<div class="form-group">
<label for="caseIdentifier">First Name</label>
<input type="text" class="form-control" id="firstname" name="?">
</div>
<div class="form-group">
<label for="lastName">Last Name</label>
<input type="text" class="form-control" id="lastName" name="?">
</div>
<div class="form-group">
<label for="line1">Line 1</label>
<input type="text" class="form-control" id="line1" name="?">
</div>
<div class="form-group">
<label for="line2">Line 2</label>
<input type="text" class="form-control" id="line2" name="?">
</div>
JS
const myForm = document.getElementById('myForm');
myForm.addEventListener('submit', function (e) {
e.preventDefault();
const url = url;
const formData = new FormData(this);
let object = {};
formData.forEach(function (value, key) {
object[key] = value;
});
let json = JSON.stringify(object);
let fetchData = {
method: 'POST',
body: json,
headers: <myHeaders>
}
fetch(url, fetchData)
.then(function (response) {
console.log(fetchData)
return response.text();
}).then(function (text) {
console.log(text);
}).catch(function (error) {
console.error(error);
});
});
How do I tailor my HTML form to match these parameters in JS? please.
....................................................................................................................................................................................................................................................................................................................................................................................................................................................................

TypeError: Cannot read property 'set' of null at isFirebaseRef in Angular

Im start my first time with firebase and angular.
I following step to step from Angular 6 CRUD Operations With Firebase in YouTube, when I press submit then error popup in Google chrome console and cant set value into firebase realtime database.
YouTube link: https://www.youtube.com/watch?v=9wxEwE8UFr0
OrganizationComponent.html
<div class="row">
<div class="col-md-5">
<form [formGroup]="this.organizationService.form" (ngSubmit)="onSubmit()">
<input type="hidden" formControlName="$key">
<div class="form-group">
<label>Full Name</label>
<input formControlName="fullname" class="form-control" [ngClass]="{'is-invalid':submitted && formControls.fullname.errors}">
<div class="invalid-feedback" *ngIf="submitted && formControls.fullname.errors">
This field is required.</div>
</div>
<div class="form-group">
<label>Email</label>
<input formControlName="email" class="form-control" [ngClass]="{'is-invalid':submitted && formControls.email.errors}">
<div class="invalid-feedback" *ngIf="submitted && formControls.email.errors">
Invalid email address.</div>
</div>
<div class="form-group">
<label>Mobile</label>
<input formControlName="mobile" class="form-control" [ngClass]="{'is-invalid':submitted && formControls.mobile.errors}">
<div class="invalid-feedback" *ngIf="submitted && formControls.mobile.errors">
<label *ngIf="formControls.mobile.errors.required">This field is required.</label>
<label *ngIf="formControls.mobile.errors.minlength">Atleast 8 numbers.</label>
</div>
</div>
<div class="form-group">
<label>Location</label>
<input formControlName="location" class="form-control">
</div>
<div class="form-group">
<input type="submit" class="btn btn-primary" value="Submit">
</div>
</form>
<div class="alert alert-info" *ngIf="showSuccessMessage">
Submitted successfully.
</div>
</div>
<div class="col-md-7">
<app-organization-list></app-organization-list>
</div>
</div>
Organization.component.ts
import { Component, OnInit } from '#angular/core';
import { OrganzationService } from '../shared/organization.service';
#Component({
selector: 'app-organization',
templateUrl: './organization.component.html',
styleUrls: ['./organization.component.css']
})
export class OrganizationComponent implements OnInit {
constructor(private organizationService: OrganzationService) { }
submitted: boolean;
showSuccessMessage: boolean;
formControls = this.organizationService.form.controls;
ngOnInit() {
}
onSubmit(){
this.submitted = true;
if(this.organizationService.form.valid){
if(this.organizationService.form.get('$key').valid == null)
this.organizationService.insertOrganization(this.organizationService.form.value);
else
this.organizationService.updateOrganization(this.organizationService.form.value);
this.showSuccessMessage = true;
setTimeout(() => this.showSuccessMessage = false,3000);
this.submitted = false;
this.organizationService.form.reset();
this.organizationService.form.setValue({
$key: null,
fullname: '',
email: '',
mobile: '',
location: ''
})
}
}
}
OrganizationService.ts
import { Injectable } from '#angular/core';
import {FormControl,FormGroup,Validators} from "#angular/forms";
import {AngularFireDatabase,AngularFireList} from 'angularfire2/database';
#Injectable({
providedIn: 'root'
})
export class OrganzationService {
constructor(private firebase: AngularFireDatabase) { }
organizationList: AngularFireList<any>;
form = new FormGroup({
$key: new FormControl(null),
fullname: new FormControl('',Validators.required),
email: new FormControl('',Validators.email),
mobile: new FormControl('',[Validators.required,Validators.minLength(8)]),
location: new FormControl('')
});
getOrganizations() {
this.organizationList = this.firebase.list('organizations');
return this.organizationList.snapshotChanges();
}
insertOrganization(organization) {
this.organizationList.push({
fullname: organization.fullname,
email: organization.email,
mobile: organization.mobile,
location: organization.location
});
}
populateForm(organization) {
this.form.setValue(organization);
}
updateOrganization(organization) {
this.organizationList.update(organization.$key,
{
fullname: organization.fullname,
email: organization.email,
mobile: organization.mobile,
location: organization.location
});
deleteOrganization($key: string) {
this.organizationList.remove($key);
}
}

How to send nested json objects to the controller by using ajax

What I am trying to do is passing nested json objects to the controller
from where I have to set the field of those entity respectively. I have two entity named UserData and Address and I want to get nested objects for both the entity as the project requires.
As you can see at this phase I don't understand how to tackle this problem. help me out of this problem.
/front end/
<body>
<div class="container">
<div class="jumbotron">
<h1>File upload Demo</h1>
<p>File upload Demo along with the JSON data</p>
</div>
</div>
<div class="container">
<div class="alert alert-success">File uploaded successfully</div>
<div class="alert alert-danger">File is not uploaded. Error occurred</div>
<div class="form-group">
<label for="firstname">First Name:</label> <input type="text"
class="form-control" id="firstname" name="firstname">
</div>
<div class="form-group">
<label for="lastname">Last Name:</label> <input type="text"
class="form-control" id="lastname" name="lastname">
</div>
<div class="form-group">
<label for="state">State:</label> <input type="text"
class="form-control" id="state" name="state">
</div>
<div class="form-group">
<label for="city">City:</label> <input type="text"
class="form-control" id="city" name="city">
</div>
<form id="fileUploadForm">
<div class="form-group">
<input type="file" class="form-control-file border" name="file">
</div>
</form>
<button type="button" id="btnSubmit" class="btn btn-primary">Submit</button>
</div>
<script>
$(document).ready(function () {
$(".alert-success").hide();
$(".alert-danger").hide();
$("#btnSubmit").click(function () {
alert("hello");
var form = $('#fileUploadForm')[0];
var data = new FormData(form);
var jsonDataObj = {
"firstname": $("#firstname").val(),
"lastname" : $("#lastname").val(),
"address" :{
"state": $("#state").val(),
"city" : $("#city").val()
}
};
data.append("jsondata", JSON.stringify(jsonDataObj));
$("#btnSubmit").prop("disabled", true);
$.ajax({
type: "POST",
enctype: 'multipart/form-data',
url: "/upload",
data: data,
processData: false,
contentType: false,
cache: false,
timeout: 600000,
success: function (data) {
console.log("SUCCESS : ", data);
$("#btnSubmit").prop("disabled", false);
$(".alert-success").show();
$(".alert-danger").hide();
},
error: function (e) {
$(".alert-success").hide();
$(".alert-danger").show();
console.log("ERROR : ", e);
$("#btnSubmit").prop("disabled", false);
}
});
});
});
</script>
</body>
/**controller**/
#Controller
public class FileUploadRestController {
#Autowired UserRepo userRepo;
#Autowired uploadrep upld;
ObjectMapper objectMapper = new ObjectMapper();
ObjectMapper addressmap = new ObjectMapper();
#RequestMapping(value="/upload", method=RequestMethod.POST)
public ResponseEntity<Object> uploadFile(#RequestParam(required=true, value="file") MultipartFile file, #RequestParam(required=true, value="jsondata")String jsondata) throws IOException, ParseException {
System.out.println("file name is "+file.getOriginalFilename());
JSONParser parser = new JSONParser();
JSONObject json = (JSONObject) parser.parse(jsondata);
//System.out.println(json.getString("firstname"));
/*File convertFile = new File("c://mydownloads//"+file.getOriginalFilename());
convertFile.createNewFile();
FileOutputStream fout = new FileOutputStream(convertFile);
fout.write(file.getBytes());
fout.close();*/
System.out.println("data ies "+json);
//UserData personData = objectMapper.readValue(jsondata, UserData.class);
//Address addressData = addressmap.readValue(jsondata, Address.class);
//Address address =new Address(addressData.getState(),addressData.getCity());
/*UserData userData=new UserData(StringUtils.cleanPath(file.getOriginalFilename()),file.getContentType(),file.getBytes(),personData.getFirstname(),personData.getLastname());
System.out.println("uploaded datafiles ");
//String str=Base64.getEncoder().encodeToString(file.getBytes());
userData.setAddress(address);
userRepo.save(userData);*/
return new ResponseEntity<>("File is uploaded successfully", HttpStatus.OK);
}

Store null values in database while trying to save data using spring mvc angular js

angular js code
<body data-ng-app="myApp" data-ng-controller="UserController as userBean">
<form method="post" action="register" name="myForm">
<div class="form-group col-lg-7" >
<label for="username" class="control-label">First Name:</label>
<input type="text" data-ng-model="userBean.username" class="form-control" placeholder="Enter Firstname"/><br>
<label for="phone" class="control-label">Phone:</label>
<input type="text" data-ng-model="userBean.phone" class="form-control" placeholder="Enter phone no."/><br>
<label for="email" class="control-label">Email:</label>
<input type="text" data-ng-model="userBean.email" class="form-control" placeholder="Enter email"/><br>
<label for="address" class="control-label">Address:</label>
<input type="text" data-ng-model="userBean.address" class="form-control" placeholder="Enter address"/><br>
<label for="password" class="control-label">Password:</label>
<input type="password" data-ng-model="userBean.password" class="form-control" placeholder="Enter password"/><br>
</div>
<div class="form-group col-lg-7">
<button type="submit" data-ng-click="insertData()" class="btn btn-primary">Submit</button>
</div>
</form>
<script type="text/javascript">
var app = angular.module('myApp', []);
app.controller("UserController", ['$scope', '$http', function($scope, $http, httpPostService) {
var self=this;
$scope.insertData = function()
{
alert($scope.userBean.username, $scope.userBean.phone, $scope.userBean.email);
$http({
method: "POST",
url: "register",
data:{
username: $scope.userBean.username,
phone: $scope.userBean.phone,
email: $scope.userBean.email,
address: $scope.userBean.address,
password: $scope.userBean.password}
}).then(function(response){
console.log(response.status);
console.log("in success");
}, function(response){
console.log(response.status);
console.log("in fail");
});
};
}]);
</script>
controller code
#RequestMapping(value="/register", method = RequestMethod.POST, consumes="application/json")
public #ResponseBody ModelAndView doRegister(#ModelAttribute #RequestBody UserBean userBean, BindingResult result)
{
if(!result.hasFieldErrors())
{
if(retrieveService.insert(userBean) != null)
{
System.out.println("done");
}
}
return new ModelAndView("redirect:/welcome");
}
}
I think a controller problem. userBean has null values to pass it to a controller. so kindly anyone helps me
It error also came
HTTP Status 415 – Unsupported Media Type The origin server is refusing to service the request because the payload is in a format not
supported by this method on the target resource.
Set content type JSON in your request headers like below.
$http({
method: "POST",
url: "register",
data:{
username: $scope.userBean.username,
phone: $scope.userBean.phone,
email: $scope.userBean.email,
address: $scope.userBean.address,
password: $scope.userBean.password},
headers: {'Content-Type': 'application/json'}
})
Use #JsonIgnore on the field which can have null values.