This is my class User
#JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "userType")
#JsonSubTypes({
#JsonSubTypes.Type(value = Broker.class, name = "BROKER"),
#JsonSubTypes.Type(value = Admin.class, name = "ADMIN")
})
public class User {
protected String password;
#Id
protected String username;
protected boolean accountNonExpired=true, accountNonBlocked=true, enabled=true, credentialNonExpired=true;
protected String[] grantedAuthorities;
protected UserType userType;
public User(){
}
public UserType getUserType() {
return userType;
}
public void setUserType(UserType userType) {
this.userType = userType;
}
#Override
public String toString() {
return "User{" +
"password='" + password + '\'' +
", username='" + username + '\'' +
", accountNonExpired=" + accountNonExpired +
", accountNonBlocked=" + accountNonBlocked +
", enabled=" + enabled +
", credentialNonExpired=" + credentialNonExpired +
", grantedAuthorities=" + Arrays.toString(grantedAuthorities) +
", userType=" + userType +
'}';
}
It uses an enum as a field of type `UserType
public enum UserType {
BROKER("BROKER"),ADMIN("ADMIN");
private static Map<String, UserType> FORMAT_MAP = Stream
.of(UserType.values())
.collect(Collectors.toMap(s -> s.value, Function.identity()));
private final String value;
UserType(String value) {
this.value = value;
}
#JsonCreator
public static UserType fromString(String string) {
return Optional
.ofNullable(FORMAT_MAP.get(string))
.orElseThrow(() -> new IllegalArgumentException(string));
}
#JsonValue
public String getValue(){
return value;
}
}
But ObjectMapper is not able to deserialize the UserType enum
My Json String :
{"password":"135","username":"cooper","accountNonExpired":true,"grantedAuthorities":["ROLE_BROKER"],"userType":"BROKER","brokerName":null,"accountNonLocked":true,"credentialsNonExpired":true,"enabled":true}
This is the code to deserialze :
User user = objectMapper.readValue(jsonString,User.class);
But after desierializing to User object, this is how the user object looks :
{password='135', username='cooper', accountNonExpired=true, accountNonBlocked=true, enabled=true, credentialNonExpired=true, grantedAuthorities=[ROLE_BROKER], userType=null}
As you can see, userType is null. What is going wrong?
It works after I changed the include = JsonTypeInfo.As.EXISTING_PROPERTY to include = JsonTypeInfo.As.PROPERTY.
Related
I just started to work with android studio. i am also new in the programming of apps or anything else. Now i try to build my first app. i get the failure massage: "E/SQLiteLog: (1) duplicate column name: Temperatur"
In the other Threads i don´t find the right solution.
My Code:
public class FangbuchDbHelper extends SQLiteOpenHelper {
public static final String DB_NAME = "fangbuch.db";
public static final int DB_Version = 1;
public static final String TABLE_KARPFEN = "Karpfen";
public static final String COLUMN_ID = "id";
public static final String COLUMN_DATUM = "Datum";
public static final String COLUMN_ZEIT = "Uhrzeit";
public static final String COLUMN_WINDRICHTUNG = "Windrichtung";
public static final String COLUMN_WINDSTAERKE = "Windstärke bft";
public static final String COLUMN_TEMPERATURA = "Temperatur außen";
public static final String COLUMN_TEMPERATURW = "Temperatur Wasser";
public static final String COLUMN_HPAGESTERN = "hPa gestern";
public static final String COLUMN_HPAHEUTE = "hPa heute";
public static final String COLUMN_HPAMORGEN = "hPa morgen";
public static final String COLUMN_MOND = "Mond";
public static final String COLUMN_GEWICHT = "Gewicht";
public static final String COLUMN_FOTO = "Foto";
public static final String TABLE_MEERFORELLE = "Meerforelle";
public static final String COLUMN_ID2 = "id2";
public static final String COLUMN_DATUM2 = "Datum2";
public static final String COLUMN_ZEIT2 = "Zeit2";
public static final String COLUMN_WASSERSTAND = "Wasserstand";
public static final String COLUMN_WINDSTAERKE2 = "Windstärke2 bft";
public static final String COLUMN_WINDRICHTUNG2 = "Windrichtung2";
public static final String COLUMN_TEMPERATURW2 = "Wassertemperatur";
public static final String COLUMN_STROEMUNG = "Strömung";
public static final String COLUMN_FOTO2 = "Foto2";
public static final String SQL_CREATE =
"create table " + TABLE_KARPFEN + "(" +
COLUMN_ID + " integer primary key , " +
COLUMN_DATUM + " text not null, " +
COLUMN_ZEIT + " text, " +
COLUMN_WINDRICHTUNG + " text, " +
COLUMN_WINDSTAERKE + " integer, " +
COLUMN_TEMPERATURA + " integer, " +
COLUMN_TEMPERATURW + " integer not null, " +
COLUMN_HPAGESTERN + " integer, " +
COLUMN_HPAHEUTE + " integer, " +
COLUMN_HPAMORGEN + " integer, " +
COLUMN_MOND + " text, " +
COLUMN_GEWICHT + " REAL, " +
COLUMN_FOTO + " text); ";
public static final String SQL_CREATE2 =
"create table " + TABLE_MEERFORELLE + "(" +
COLUMN_ID2 + " integer, " +
COLUMN_DATUM2 + " text not null, " +
COLUMN_ZEIT2 + " text, " +
COLUMN_WASSERSTAND + " text, " +
COLUMN_WINDSTAERKE2 + "integer, " +
COLUMN_WINDRICHTUNG2 + " text, " +
COLUMN_TEMPERATURW2 + " integer, " +
COLUMN_STROEMUNG + " text, " +
COLUMN_FOTO2 + " text); ";
public FangbuchDbHelper(#Nullable Context context) {
super(context, DB_NAME, null, DB_Version);
}
#Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
sqLiteDatabase.execSQL(SQL_CREATE);
sqLiteDatabase.execSQL(SQL_CREATE2);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(FangbuchDbHelper.class.getName(), "Upgrading database from version " + oldVersion + "to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS " + DB_NAME);
onCreate(db);
}
}
At the beginning i had duplicate column names. But now i have changed this.
But i still get this message.
Whats my mistake? Can someone help me? Thanks
Regards Ulf
I'm not a SQL(ite) expert, but it's noticeable that your column names Temperatur außen and Temperatur Wasser contain a space and are inserted unquoted in the create table statement, which presumably causes the error. According to SQLite Keywords, there are three or four ways of quoting an identifier in SQLite - you may want to choose one for the definitions of COLUMN_TEMPERATURA and COLUMN_TEMPERATURW.
perhaps this activities can help:
public class DbEntry {
//Karpfen Spalten Variablen
private long id;
private String Datum;
private String Zeit;
private String Windrichtung;
private int Windstaerke;
private int TemperaturA;
private int TemperaturW;
private int hPaGestern;
private int hPaHeute;
private int hPaMorgen;
private String Mond;
private float Gewicht;
//Meerforellen Spalten Variablen
private long id2;
private String Datum2;
private String Zeit2;
private String Wasserstand;
private int Windstaerke2;
private String Windrichtung2;
private int TemperaturW2;
private String Stroemung;
//get und set für Karpfentabelle
public long getId() {
return id;
}
public void setId (long id){
this.id = id;
}
public String getDatum() {
return Datum;
}
public void setDatum(String string) {
this.Datum = Datum;
}
public String getZeit() {
return Zeit;
}
public void setZeit(String string) {
this.Zeit = Zeit;
}
public String getWindrichtung() {
return Windrichtung;
}
public void setWindrichtung(String string) {
this.Windrichtung = Windrichtung;
}
public int getWindstaerke() {
return Windstaerke;
}
public void setWindstaerke(int anInt) {
this.Windstaerke = Windstaerke;
}
public int getTemperaturA() {
return TemperaturA;
}
public void setTemperaturA(int anInt) {
this.TemperaturA = TemperaturA;
}
public int getTemperaturW() {
return TemperaturW;
}
public void setTemperaturW(int anInt) {
this.TemperaturW = TemperaturW;
}
public int gethPaGestern() {
return hPaGestern;
}
public void sethPaGestern(int anInt) {
this.hPaGestern = hPaGestern;
}
public int gethPaHeute() {
return hPaHeute;
}
public void sethPaHeute(int anInt) {
this.hPaHeute = hPaHeute;
}
public int gethPaMorgen() {
return hPaMorgen;
}
public void sethPaMorgen(int anInt) {
this.hPaMorgen = hPaMorgen;
}
public String getMond() {
return Mond;
}
public void setMond(String string) {
this.Mond = Mond;
}
public float getGewicht() {
return Gewicht;
}
public void setGewicht(float aFloat) {
this.Gewicht = Gewicht;
}
//get und set für Meerforellen Tabelle
public long getId2() {
return id2;
}
public void setId2(long aLong) {
this.id2 = id2;
}
public String getDatum2() {
return Datum2;
}
public void setDatum2(String string) {
this.Datum2 = Datum2;
}
public String getZeit2() {
return Zeit2;
}
public void setZeit2(String string) {
this.Zeit2 = Zeit2;
}
public String getWasserstand() {
return Wasserstand;
}
public void setWasserstand(String string) {
this.Wasserstand = Wasserstand;
}
public int getWindstaerke2() {
return Windstaerke2;
}
public void setWindstaerke2(int anInt) {
this.Windstaerke2 = Windstaerke2;
}
public String getWindrichtung2() {
return Windrichtung2;
}
public void setWindrichtung2(String string) {
this.Windrichtung2 = Windrichtung2;
}
public int getTemperaturW2() {
return TemperaturW2;
}
public void setTemperaturW2(int anInt) {
this.TemperaturW2 = TemperaturW2;
}
public String getStroemung() {
return Stroemung;
}
public void setStroemung(String string) {
this.Stroemung = Stroemung;
}
}
or this activity:
public class DbDataSource {
private SQLiteDatabase fbDatabase;
private FangbuchDbHelper dbHelper;
private String[] allColumnsKarpfen = {"COLUMN_ID", "COLUMN_DATUM", "COLUMN_ZEIT", "COLUMN_WINDRICHTUNG", "COLUMN_WINDSTAERKE",
"COLUMN_TEMPERATURA", "COLUMN_TEMPERATURW", "COLUMN_HPAGESTERN", "COLUMN_HPAHEUTE", "COLUMN_HPAMORGEN", "COLUMN_MOND",
"COLUMN_GEWICHT"};
private String[] allColumnsMeerforelle = {"COLUMN_ID2", "COLUMN_DATUM2", "COLUMN_ZEIT2", "COLUMN_WASSERSTAND", "COLUMN_WINDSTAERKE2",
"COLUMN_WINDRICHTUNG2", "COLUMN_TEMPERATURW2", "COLUMN_STROEMUNG"};
public DbDataSource(Context context) {
dbHelper = new FangbuchDbHelper(context);
}
public void open() throws SQLException {
fbDatabase = dbHelper.getWritableDatabase();
}
public void close() {
dbHelper.close();
}
public DbEntry createEntryKarpfen(String Datum, String Zeit, String Windrichtung, int Windstaerke, int TemperaturA, int TemperaturW,
int hPaGestern, int hPaHeute, int hPaMorgen, String Mond, float Gewicht) {
ContentValues values = new ContentValues();
values.put("COLUMN_DATUM", Datum);
values.put("COLUMN_ZEIT", Zeit);
values.put("COLUMN_WINDRICHTUNG", Windrichtung);
values.put("COLUMN_WINDSTAERKE", Windstaerke);
values.put("COLUMN_TEMPERATURA", TemperaturA);
values.put("COLUMN_TEMPERATURW", TemperaturW);
values.put("COLUMN_HPAGESTERN", hPaGestern);
values.put("COLUMN_HPAHEUTE", hPaHeute);
values.put("COLUMN_HPAMORGEN", hPaMorgen);
values.put("COLUMN_MOND", Mond);
values.put("COLUMN_GEWICHT", Gewicht);
long insertId = fbDatabase.insert("TABLE_KARPFEN", null, values);
Cursor cursor = fbDatabase.query("TABLE_KARPFEN", allColumnsKarpfen, "COLUMN_ID = " + insertId, null, null, null, null);
cursor.moveToFirst();
return cursorToDbEntryKarpfen(cursor);
}
public DbEntry createEntryMeerforelle(String Datum2, String Zeit2, String Wasserstand, int Windstaerke2, String Windrichtung2, int TemperaturW2,
String Stroemung) {
ContentValues values2 = new ContentValues();
values2.put("COLUMN_DATUM2", Datum2);
values2.put("COLUMN_ZEIT2", Zeit2);
values2.put("COLUMN_WASSERSTAND", Wasserstand);
values2.put("COLUMN_WINDSTAERKE2", Windstaerke2);
values2.put("COLUMN_WINDRICHTUNG2", Windrichtung2);
values2.put("COLUMN_TEMPERATURW2", TemperaturW2);
values2.put("COLUMN_STROEMUNG", Stroemung);
long insertId2 = fbDatabase.insert("TABLE_MEERFORELLE", null, values2);
Cursor cursorMeerforelle = fbDatabase.query("TABLE_MEERFORELLE", allColumnsMeerforelle, "COLUMN_ID2 = " + insertId2, null, null, null, null);
cursorMeerforelle.moveToFirst();
return cursorToDbEntryMeerforelle(cursorMeerforelle);
}
protected List<DbEntry> getKarpfenEntries() {
List<DbEntry> EntryKarpfenList = new ArrayList<DbEntry>();
EntryKarpfenList = new ArrayList<DbEntry>();
Cursor cursor = fbDatabase.query("TABLE_KARPFEN", allColumnsKarpfen, null,null, null, null, null);
cursor.moveToFirst();
if(cursor.getCount() == 0) return EntryKarpfenList;
while (cursor.isAfterLast() == false) {
DbEntry entry = cursorToDbEntryKarpfen(cursor);
EntryKarpfenList.add(entry);
cursor.moveToNext();
}
cursor.close();
return EntryKarpfenList;
}
protected List<DbEntry> getMeerforelleEntries() {
List<DbEntry> EntryMeerforelleList = new ArrayList<DbEntry>();
EntryMeerforelleList = new ArrayList<DbEntry>();
Cursor cursor = fbDatabase.query("TABLE_MEERFORELLE", allColumnsMeerforelle, null,null, null, null, null);
cursor.moveToFirst();
if(cursor.getCount() == 0) return EntryMeerforelleList;
while (cursor.isAfterLast() == false) {
DbEntry entry = cursorToDbEntryKarpfen(cursor);
EntryMeerforelleList.add(entry);
cursor.moveToNext();
}
cursor.close();
return EntryMeerforelleList;
}
private DbEntry cursorToDbEntryKarpfen(Cursor cursor) {
DbEntry entry = new DbEntry();
entry.setId(cursor.getLong(0));
entry.setDatum(cursor.getString(1));
entry.setZeit(cursor.getString(2));
entry.setWindrichtung(cursor.getString(3));
entry.setWindstaerke(cursor.getInt(4));
entry.setTemperaturA(cursor.getInt(5));
entry.setTemperaturW(cursor.getInt(6));
entry.sethPaGestern(cursor.getInt(7));
entry.sethPaHeute(cursor.getInt(8));
entry.sethPaMorgen(cursor.getInt(9));
entry.setMond(cursor.getString(10));
entry.setGewicht(cursor.getFloat(11));
return entry;
}
private DbEntry cursorToDbEntryMeerforelle(Cursor cursor) {
DbEntry entry2 = new DbEntry();
entry2.setId2(cursor.getLong(0));
entry2.setDatum2(cursor.getString(1));
entry2.setZeit2(cursor.getString(2));
entry2.setWasserstand(cursor.getString(3));
entry2.setWindstaerke2(cursor.getInt(4));
entry2.setWindrichtung2(cursor.getString(5));
entry2.setTemperaturW2(cursor.getInt(6));
entry2.setStroemung(cursor.getString(7));
return entry2;
}
}
im getting this error idk why
There was an unexpected error (type=Bad Request, status=400).
Validation failed for object='client'. Error count: 1
org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'client' on field 'image': rejected value [org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile#42df4d2d]; codes [typeMismatch.client.image,typeMismatch.image,typeMismatch.[B,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [client.image,image]; arguments []; default message [image]]; default message [Failed to convert property value of type 'org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile' to required type 'byte[]' for property 'image'; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type 'org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile' to required type 'byte' for property 'image[0]': PropertyEditor [org.springframework.beans.propertyeditors.CustomNumberEditor] returned inappropriate value of type 'org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile']
Entity :
#Entity
#Table(name = "Client")
public class Client implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="idClient")
private Long idClient;
#Column(name="nom")
private String nomClient;
#Column(name="prenom")
private String prenomClient;
#Column(name="datedenaissance")
#DateTimeFormat(pattern = "yyyy-MM-dd")
#Temporal(TemporalType.DATE)
private Date datedenaissanceClient;
#Column(name="typepiece")
private String typepieceClient;
#Column(name="numeropiece")
private int numeropieceClient;
#Column(name="numerotel")
private Long numerotelClient;
#Column(name="email")
private String emailClient;
#Column(name="adresse")
private String adresseClient;
#Column(name="rendezvous")
#DateTimeFormat(pattern = "yyyy-MM-dd")
#Temporal(TemporalType.DATE)
private Date rendezvous;
#Column(name="temps")
#DateTimeFormat(pattern = "hh:mm")
#Temporal(TemporalType.TIME)
private Date temps;
#Column(name="tempsfin")
#DateTimeFormat(pattern = "hh:mm")
#Temporal(TemporalType.TIME)
private Date tempsfin;
#OneToMany(cascade = CascadeType.ALL, mappedBy="clients")
private List<Compte> comptes;
#Lob
#Column(name="image")
private byte[] image;
public static long getSerialversionuid() {
return serialVersionUID;
}
public Long getIdClient() {
return idClient;
}
public void setIdClient(Long idClient) {
this.idClient = idClient;
}
public String getNomClient() {
return nomClient;
}
public void setNomClient(String nomClient) {
this.nomClient = nomClient;
}
public String getPrenomClient() {
return prenomClient;
}
public void setPrenomClient(String prenomClient) {
this.prenomClient = prenomClient;
}
public Date getDatedenaissanceClient() {
return datedenaissanceClient;
}
public void setDatedenaissanceClient(Date datedenaissanceClient) {
this.datedenaissanceClient = datedenaissanceClient;
}
public String getTypepieceClient() {
return typepieceClient;
}
public void setTypepieceClient(String typepieceClient) {
this.typepieceClient = typepieceClient;
}
public Date getTempsfin() {
return tempsfin;
}
public void setTempsfin(Date tempsfin) {
this.tempsfin = tempsfin;
}
public int getNumeropieceClient() {
return numeropieceClient;
}
public void setNumeropieceClient(int numeropieceClient) {
this.numeropieceClient = numeropieceClient;
}
public Long getNumerotelClient() {
return numerotelClient;
}
public void setNumerotelClient(Long numerotelClient) {
this.numerotelClient = numerotelClient;
}
public String getEmailClient() {
return emailClient;
}
public void setEmailClient(String emailClient) {
this.emailClient = emailClient;
}
public String getAdresseClient() {
return adresseClient;
}
public void setAdresseClient(String adresseClient) {
this.adresseClient = adresseClient;
}
public Date getRendezvous() {
return rendezvous;
}
public void setRendezvous(Date rendezvous) {
this.rendezvous = rendezvous;
}
public Date getTemps() {
return temps;
}
public void setTemps(Date temps) {
this.temps = temps;
}
public List<Compte> getComptes() {
return comptes;
}
public void setComptes(List<Compte> comptes) {
this.comptes = comptes;
}
public Client(Long idClient, String nomClient, String prenomClient, Date datedenaissanceClient,
String typepieceClient, int numeropieceClient, Long numerotelClient, String emailClient,
String adresseClient, Date rendezvous, Date temps, Date tempsfin, List<Compte> comptes, byte[] image) {
super();
this.idClient = idClient;
this.nomClient = nomClient;
this.prenomClient = prenomClient;
this.datedenaissanceClient = datedenaissanceClient;
this.typepieceClient = typepieceClient;
this.numeropieceClient = numeropieceClient;
this.numerotelClient = numerotelClient;
this.emailClient = emailClient;
this.adresseClient = adresseClient;
this.rendezvous = rendezvous;
this.temps = temps;
this.tempsfin = tempsfin;
this.comptes = comptes;
this.image = image;
}
public byte[] getImage() {
return image;
}
public void setImage(byte[] image) {
this.image = image;
}
#Override
public String toString() {
return "Client [idClient=" + idClient + ", nomClient=" + nomClient + ", prenomClient=" +
prenomClient
+ ", datedenaissanceClient=" + datedenaissanceClient + ", typepieceClient=" +
typepieceClient
+ ", numeropieceClient=" + numeropieceClient + ", numerotelClient=" + numerotelClient +
", emailClient="
+ emailClient + ", adresseClient=" + adresseClient + ", rendezvous=" + rendezvous + ",
temps=" + temps
+ ", tempsfin=" + tempsfin + ", comptes=" + comptes + ", image=" + Arrays.toString(image)
+ "]";
}
public Client() {
super();
// TODO Auto-generated constructor stub
}
public Client(Long idClient, String nomClient, String prenomClient, Date datedenaissanceClient,
String typepieceClient, int numeropieceClient, Long numerotelClient, String emailClient,
String adresseClient, Date rendezvous, Date temps, List<Compte> comptes) {
super();
this.idClient = idClient;
this.nomClient = nomClient;
this.prenomClient = prenomClient;
this.datedenaissanceClient = datedenaissanceClient;
this.typepieceClient = typepieceClient;
this.numeropieceClient = numeropieceClient;
this.numerotelClient = numerotelClient;
this.emailClient = emailClient;
this.adresseClient = adresseClient;
this.rendezvous = rendezvous;
this.temps = temps;
this.comptes = comptes;
}
}
Service :
#Override
public void addClient(Client client){
// TODO Auto-generated method stub
this.clientRepository.save(client);
}
Controller :
#RequestMapping(value = { "/saveClient" }, method = RequestMethod.POST, consumes = {"multipart/form-data"})
public String saveClient(#ModelAttribute("client") Client client,Model model,#ModelAttribute("compte") Compte compte,#ModelAttribute("carte") Carte carte,
#ModelAttribute("agence") Agence agence,MultipartHttpServletRequest request,final #RequestParam("image") MultipartFile file) throws IOException {
compte.setClients(client);
String uploadDirectory = request.getServletContext().getRealPath(uploadFolder);
log.info("uploadDirectory:: " + uploadDirectory);
String fileName = file.getOriginalFilename();
String filePath = Paths.get(uploadDirectory, fileName).toString();
log.info("FileName: " + file.getOriginalFilename());
if (fileName == null || fileName.contains("..")) {
model.addAttribute("invalid", "Sorry! Filename contains invalid path sequence \" + fileName");
}
try {
File dir = new File(uploadDirectory);
if (!dir.exists()) {
log.info("Folder Created");
dir.mkdirs();
}
// Save the file locally
BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(new File(filePath)));
stream.write(file.getBytes());
stream.close();
} catch (Exception e) {
log.info("in catch");
e.printStackTrace();
}
byte[] imageData = file.getBytes();
client.setImage(imageData);
Date v = client.getTemps();
//Date dNow = new Date( ); // Instantiate a Date object
Calendar cal = Calendar.getInstance();
cal.setTime(v);
cal.add(Calendar.AM_PM, 0);
cal.add(Calendar.MINUTE, 30);
v = cal.getTime();
client.setTempsfin(v);
clientMetier.addClient(client);
compteMetier.addCompte(compte);
agence.setCompteagence(compte);
compte.setAgencecompte(agence);
agenceMetier.addAgence(agence);
model.addAttribute("compte",compte);
model.addAttribute("agence",agence);
return "compte";
}
HTML:
<form th:action="#{/saveClient}" method="POST"
th:object="${client}" enctype="multipart/form-data">
<div class="p-col-12">
<label class="p1">Image</label>
<input type="file" class="form-control" placeholder="" name="image" id="image" th:field="*{image}">
You should not directly use your entity as the form object as you need to use different types for the image.
Create a separate ClientFormData object to use in the controller that has all the fields of Client, but for image uses MultipartFile:
public class ClientFormData {
// other fields here
private MultipartFile image;
public static ClientFormData fromClient(Client client) {
// copy over fields
}
}
In the controller, get the bytes from the MultipartFile and copy those into your Client entity.
I'm trying to use JDBC authentication for my spring security when I hit the error message below. I'm trying to register all the email and password in the User class to be valid logins. I'm not sure if there is a problem with my sql statement or my User class. Any help if appreciated!
Caused by: org.h2.jdbc.JdbcSQLDataException:
Invalid value "3" for parameter "columnIndex" [90008-200]
Spring security
#Autowired
public void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.jdbcAuthentication()
// To find logins in the h2 database
.dataSource(dataSource)
.usersByUsernameQuery("select email, password " +
"from User " +
"where email = ?")
.authoritiesByUsernameQuery("select email, role " +
"from User " +
"where email =?");
}
User class
#Entity
public class User {
private String firstName;
private String lastName;
#Size(min = 6, message ="Enter at least 6 characters")
#ValidPassword
private String password;
private String matchingPassword;
private String passportNumber;
private String address;
private String phoneNumber;
#ValidEmail
private String email;
// Mark as primary key
#Id
// Will be auto generated
#GeneratedValue
private long id;
private String role;
public User(#NotNull String firstName, #NotNull String lastName,
#Size(min = 6, message = "Enter at least 6 characters") #NotNull String password,
#NotNull String passportNumber, #NotNull String address, #NotNull String phoneNumber, String email,
String role) {
super();
this.firstName = firstName;
this.lastName = lastName;
this.password = password;
this.passportNumber = passportNumber;
this.address = address;
this.phoneNumber = phoneNumber;
this.email = email;
this.role = role;
}
#Override
public String toString() {
return "User [firstName=" + firstName + ", lastName=" + lastName + ", password=" + password
+ ", matchingPassword=" + matchingPassword + ", passportNumber=" + passportNumber + ", address="
+ address + ", phoneNumber=" + phoneNumber + ", email=" + email + ", id=" + id + ", role=" + role + "]";
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getMatchingPassword() {
return matchingPassword;
}
public void setMatchingPassword(String matchingPassword) {
this.matchingPassword = matchingPassword;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getPassportNumber() {
return passportNumber;
}
public void setPassportNumber(String passportNumber) {
this.passportNumber = passportNumber;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public void setId(long id) {
this.id = id;
}
protected User() {
}
public long getId() {
return id;
}
}
EDIT: Answer to this question is marked below
Spring security expects 3 columns for the usersByUserName query. Here is the default query used if you don't specify one.
public static final String DEF_USERS_BY_USERNAME_QUERY
= "select username, password, enabled from users where username = ?";
So if you don't have such column for enabling and disabling user, use the following query
select email, password, 'true' as enabled from User where email = ?
Reference
https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/core/userdetails/jdbc/JdbcDaoImpl.html
I have a base class and two sublcasses:
public /*abstract*/ class TargetPoi {
private String poiId;
...
}
public class TargetSub1Poi extends TargetPoi {
private String oneMoreId;
...
}
public class TargetSub2Poi extends TargetPoi {
...
}
Is it possible to declare the base class abstract? ...I always get an exception when a JSON is send with the request if I use the abstract keyword...
Exception Description: This class does not define a public default constructor, or the constructor raised an exception.
Internal Exception: java.lang.InstantiationException
Descriptor: XMLDescriptor(com.foo.bar.TargetPoi --> [])
When the POST request with its JSON in the request body is coming into the Jersy Resource I want to deserialize the JSON into the proper TargetPoi subclasses.
The JSON:
{
"requestId": "84137f1ab38f4bf585d13984fc07c621",
"startTime": "2013-10-30T18:30:00+02:00",
"endTime": "2013-10-30T18:45:00+02:00",
"targetPoi":
{
"poiId": "0000000602",
"oneMoreId": "1"
},
"type": "Block",
"notification": true
}
My Resource hast a method defined this way...
#POST
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public Response doReservation(final ReservationDO reservationDO
, #QueryParam("serviceType") final String serviceType) {
...
}
The JSON shall be deserialized in this class:
#XmlRootElement
public class ReservationDO<T extends TargetPoi>
{
public String requestId;
public String startTime;
public String endTime;
public String serviceType;
public T targetPoi;
...
}
How can I tell Jackson to bind the JSON for the targetPoi properly to the correct subtype (TargetSub1Poi)? The serviceType could tell me to which subtype the targetPoi is to bind to...but I think this information can't be used from Jackson, does it? When I print out the deserialized JSON in th edoreservation method the oneMoreId part coming with the original JSON is lost.
Do I have to provide any TypeInfo or can I achieve it without?
It is possible to declare your parent class abstract and have a generic field. You just need to tell Jackson which sub-type to use to create an instance of you object. It can be done by using #JsonTypeInfo annotation as described at the Jackson polymorphic deserialization wiki page.
Here is an example:
public class JacksonPoi {
#JsonTypeInfo(use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY, property = "type")
public static abstract class TargetPoi {
public String poiId;
}
#JsonTypeName("sub1")
public static class TargetSub1Poi extends TargetPoi {
public String oneMoreId;
#Override
public String toString() {
return "TargetSub1Poi{" +
"poiId='" + poiId + '\'' +
"oneMoreId='" + oneMoreId + '\'' +
'}';
}
}
#JsonTypeName("sub2")
public static class TargetSub2Poi extends TargetPoi {
public String twoMoreId;
#Override
public String toString() {
return "TargetSub2Poi{" +
"poiId='" + poiId + '\'' +
"twoMoreId='" + twoMoreId + '\'' +
'}';
}
}
public static class Bean<T extends TargetPoi> {
public String field;
public T poi;
#Override
public String toString() {
return "Bean{" +
"field='" + field + '\'' +
", poi=" + poi +
'}';
}
}
public static final String JSON = "{\n" +
"\"poi\": \n" +
"{\n" +
" \"type\": \"sub1\",\n" +
" \"poiId\": \"0000000602\",\n" +
" \"oneMoreId\": \"1\"\n" +
"},\n" +
"\"field\": \"value1\"\n" +
"}";
public static final String JSON2 = "{\n" +
"\"poi\": \n" +
"{\n" +
" \"type\": \"sub2\",\n" +
" \"poiId\": \"0000000602\",\n" +
" \"twoMoreId\": \"13\"\n" +
"},\n" +
"\"field\": \"value2\"\n" +
"}";
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
mapper.registerSubtypes(TargetSub1Poi.class, TargetSub2Poi.class);
Bean<TargetSub1Poi> poi1 = mapper.readValue(JSON, new TypeReference<Bean<TargetSub1Poi>>() {});
System.out.println(poi1);
Bean<TargetSub2Poi> poi2 = mapper.readValue(JSON2, new TypeReference<Bean<TargetSub2Poi>>() {});
System.out.println(poi2);
}
}
Output:
Bean{field='value1', poi=TargetSub1Poi{poiId='0000000602'oneMoreId='1'}}
Bean{field='value2', poi=TargetSub2Poi{poiId='0000000602'twoMoreId='13'}}
I have a json like this
{
"name": "john",
"photo_urls":
{
"large": "http://www.server.com/john_photo.jpg"
}
}
and I would like to deserialize it in one class, like this
public class Person
{
String name;
String photoUrl;
}
instead of this
public class Person
{
String name;
public class photo_urls
{
String large;
}
}
Is it possible to do it with Jackson using Data Binding and the annotation #JsonProperty? Or is it necessary to use the streaming API instead?
Thanks for your help.
You can consider to have a setter method or a constructor parameter of the Map<String,String> type from which you can get the url field value. Here is an example:
public class JacksonDeserialize {
private static final String JSON = "{\n" +
" \"name\": \"john\",\n" +
" \"photo_urls\":\n" +
" {\n" +
" \"large\": \"http://www.server.com/john_photo.jpg\"\n" +
" }\n" +
"}";
public static class Person
{
private String name;
private String photoUrl;
#JsonCreator
public Person(#JsonProperty("name") String name, #JsonProperty("photo_urls") Map<String, String> photoUrl) {
this.name = name;
this.photoUrl = photoUrl.get("large");
}
#Override
public String toString() {
return "Person{" +
"photoUrl='" + photoUrl + '\'' +
", name='" + name + '\'' +
'}';
}
}
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.readValue(JSON, Person.class));
}
}
Output:
Person{photoUrl='http://www.server.com/john_photo.jpg', name='john'}