How to use Angular Observable - spring

I have got problem with getting user information using http request to my rest api server, I don't know what is wrong....
When user click on login button, Angular send request to server with username and password, if is correct it returns user info else it returns null. Problem is that variable user in user service is still null though the username and password are correct.
I don't know how to solve this problem, so if you help me I will be happy ! Thank for any help.
REST API:
package cz.flay.fellcms.http;
import cz.flay.fellcms.dao.UsersRepository;
import cz.flay.fellcms.entities.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
#CrossOrigin
#RestController
#RequestMapping(path = "/api/users")
public class UsersRestController {
#Autowired
private UsersRepository usersRepository;
Logger logger = LoggerFactory.getLogger(UsersRestController.class);
#CrossOrigin
#GetMapping(path = "/all")
public #ResponseBody Iterable<User> getAll(){
return usersRepository.findAll();
}
#CrossOrigin
#GetMapping(path = "/verify", params = {"username", "password"})
public #ResponseBody User verify(#RequestParam(value = "username") String username, #RequestParam(value = "password") String password){
logger.info("t");
return usersRepository.verify(username, password);
}
}
User Service
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { User } from '../entities/User';
#Injectable()
export class UserService {
private usersUrl: 'http://localhost:8080/api/users';
user: User;
verifyUrl: string;
constructor(private http: HttpClient) {}
isLoggedIn() {
return this.user != null;
}
isAdmin() {
return this.user.isAdmin;
}
unLoggin() {
this.user = null;
}
login(username: string, password: string) {
this.verifyUrl = 'http://localhost:8080/api/users/verify?username=' + username + '&password=' + password;
this.http.get<User>(this.verifyUrl).subscribe(data => this.user = data);
if (this.user != null) {
return true;
} else {
return false;
}
}
}

You're calling if (this.user !== null) too soon. That evaluation will get called before the request goes away and back. Try this:
login(username: string, password: string) {
this.verifyUrl = `http://localhost:8080/api/users/verify?username=${username}&password=${password}`;
return this.http.get<User>(this.verifyUrl)
.map(data => {
this.user = data
if (this.user != null) {
return true;
} else {
return false;
}
});
}
The thing is though, wherever you call this login method, it's now an observable you have to subscribe to, not a sync method.

Related

identifier of an instance of ...was altered from

i found many response about this title "identifier of an instance of ...was altered from ..." but none of this give me a solution.
i am using PostgreSQL
with just 2 column id_type and libelle.
here is my Model level :
package com.stev.pillecons.pilleCons.models;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
#Entity(name = "type_pille")
#JsonIgnoreProperties({"hibernateLazyInitializer","handler"})
public class LePille {
#Id
#GeneratedValue (strategy = GenerationType.IDENTITY)
private int id_type;
private String libelle;
public LePille(){}
public String getLibelle() {
return libelle;
}
public void setLibelle(String libelle) {
this.libelle = libelle;
}
public int getId_type() {
return id_type;
}
public void setId_type(int id_type) {
this.id_type = id_type;
}
}
My Service level :
#Override
public LePille updatePille(Integer id, LePille Sourcepille) {
Optional<LePille> existingSession = pilleRepo.findById(id);
if (existingSession.isPresent())
{
LePille Targetpile = existingSession.get();
BeanUtils.copyProperties(Sourcepille, Targetpile);
return pilleRepo.saveAndFlush(Targetpile);
}
else
{
throw new PilleException("pille not found");
}
}
when i debug it, with the data
{"id_type":10,"libelle":"dsf"}
with postman
the value of TargetPille is : {"id_type":10,"libelle":"dsf"}
and the value of SourcePille : {"id_type":0,"libelle":"popo"}
last but not least is Controller level:
#RequestMapping(value = "{id}", method = RequestMethod.PUT)
public ResponseEntity update(#PathVariable Integer id, #RequestBody LePille session) {
LePille updPille = pilleService.updatePille(id, session);
return new ResponseEntity<LePille>(updPille, HttpStatus.OK);
}
it is strange because juste update that not working, Create, Read and Delete works fine.
thanks in advance
i just change the code like this:
BeanUtils.copyProperties(Sourcepille, Targetpile, "id_type");
just add the id_type to ignore variable

axios can't accept response data sent by Spring Boot controller

I tried to integrate vue.js with Spring Boot. This is my vue.js code:
<template>
// ...
</template>
<script>
export default {
name: "Login",
data: function() {
return {
username: '',
password: '',
msg: ''
}
},
methods: {
// post data to Spring Boot
login() {
axios.post('/login',{
username: this.username,
password: this.password
})
.then(function(response) {
if(response.data.code === 200){
this.$store.dispatch('setCurrentUser',this.username);
// vue-route
this.$router.push('/course');
} else {
this.msg = response.message;
}
})
.catch(function(err) {
this.msg = 'error';
});
}
}
};
</script>
And this is my Spring Boot controller:
#RestController
#ResponseBody
public class LoginController {
#Autowired
private ResultGenerator resultGenerator;
#PostMapping("/login")
public RestResult login(String username, String password){
if(username.equals("123") && password.equals("123")){
return resultGenerator.getSuccessResult();
} else {
return resultGenerator.getFailResult("error");
}
}
}
The controller will return JSON data which looks like:{"code":200,"message":"success","data":null}. When the login method was called, controller could accept the username and password and controller sent response data too. But that was all and vue-router didn't work. All I saw in the brower was:
Can anyone help?
------------------ Addition -----------------------
This is vue-router config:
const routes = [
{
path: '/',
component: Login
},
{
path: '/signin',
component: Signin
},
{
path: '/course',
component: Course
}
];
const router = new VueRouter({
routes,
mode: "history"
});
The problem could be that you return resultGenerator.getSuccessResult(). Have you tried redirecting to the '/course' path inside Spring Boot Controller?
#PostMapping("/login")
public RestResult login(String username, String password){
if(username.equals("123") && password.equals("123")){
this.$router.push('/course');
} else {
return resultGenerator.getFailResult("error");
}
}
If the Vue.js and Spring boot are 2 different apps (like backend and frontend), this may help:
Try using #CrossOrigin (CORS) on your #controller or on the method that expose the rest, I had similar issues on an Ionic 3 proyect and thaty solved the problem.
EXAMPLE:
#CrossOrigin(origins = "http://localhost:9000")
#GetMapping("/greeting")
public Greeting greeting(#RequestParam(required=false, defaultValue="World") String name) {
System.out.println("==== in greeting ====");
return new Greeting(counter.incrementAndGet(), String.format(template, name));
}
It should look something like this:
#RestController
#ResponseBody
public class LoginController {
#Autowired
private ResultGenerator resultGenerator;
#CrossOrigin(origins = "http://localhost:9000") // The IP:PORT of the vue app origin
#PostMapping("/login")
public RestResult login(String username, String password){
if(username.equals("123") && password.equals("123")){
return resultGenerator.getSuccessResult();
} else {
return resultGenerator.getFailResult("error");
}
}
}
Source from spring.io Here! :D

Spring WEB MVC + produces = MediaType.IMAGE_JPEG_VALUE + #ResponseStatus(HttpStatus.FORBIDDEN) = HTTP status 406

I'm writing some code for user authorization. For users with 2 factored authorization enabled I'm writing code for 2fa secret update:
#RestController
public class CurrentUserController {
#PostMapping(value = "update-2fa-secret", produces = MediaType.IMAGE_JPEG_VALUE)
public byte[] update2FaSecret() {
UserEntity user = userRepository.findOne(currentUserId);
if (user.is2FaEnabled() != Boolean.TRUE)
throw new HttpForbiddenException("2fa disabled for current user");
String secret = createNewSecret();
user.setSecret2Fa(secret);
userRepository.save(user);
return createQRCode(secret, user.getEmail());
}
}
And Exception:
#ResponseStatus(HttpStatus.FORBIDDEN)
public class HttpForbiddenException extends RuntimeException {
............
}
And when Exception happens I get response from the server with 406 Http status and without body (content).
I don't understand why this happens and how to solve it. Can somebody explain it to me please?
I've solved this issue in the next way:
#RestController
public class CurrentUserController {
#PostMapping(value = "update-2fa-secret", produces = MediaType.IMAGE_JPEG_VALUE)
public byte[] update2FaSecret(HttpServletResponse response) {
UserEntity user = userRepository.findOne(currentUserId);
if (user.is2FaEnabled() != Boolean.TRUE) { //fix is here
response.setStatus(HttpStatus.FORBIDDEN.value()); //403
return new byte[0];
}
String secret = createNewSecret();
user.setSecret2Fa(secret);
userRepository.save(user);
return createQRCode(secret, user.getEmail());
}
}

Spring JPA annotation based web app

I am have JSON message as request object coming into Controller.
I am trying to map the object to model class in the Controller class but unable to do so.
Can anyone help me with the procedure.
package com.firm.trayportal.contoller;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.firm.trayportal.jparepository.trayMoveRepository;
import com.firm.trayportal.jparepository.LocationRepository;
import com.firm.trayportal.jparepository.StopoffRepository;
import com.firm.trayportal.model.trayMove;
import com.firm.trayportal.model.Location;
import com.firm.trayportal.model.Stopoff;
import com.firm.trayportal.service.trayMoveService;
#RestController
public class trayPortalquoteController {
/* #Autowired
JdbcTemplate template;*/
private trayMove trayMove;
private Location location;
private Stopoff stopoff;
// Service Layer
private trayMoveService trayMoveService;
private static final Logger logger = Logger
.getLogger(trayPortalquoteController.class);
#RequestMapping(value = "/quote", method = RequestMethod.POST, consumes = {MediaType.APPLICATION_JSON_VALUE}, produces = {MediaType.APPLICATION_JSON_VALUE} )
public ThumbsUp getActivetrayOrder(HttpServletRequest request, #RequestBody trayquoteRto rto) {
logger.debug("Start processing");
if (rto != null) {
logger.debug(String.format("Driver: %s/Load Number: %s/Stop %s",
rto.getDriver(), rto.getLn(), rto.getStops() != null
&& rto.getStops().get(0) != null ? rto.getStops()
.get(0).getStop() : "?"));
/*
* Querying String insertSql =
* "insert into tray_move (move_type, carrier_id, ln) values(?,?,?)"
* ;
*
* Object[] params = new Object[] {rto.getType(), rto.getDriver(),
* rto.getLn()}; // define SQL types of the arguments int[] types =
* new int[] { Types.VARCHAR, Types.VARCHAR, Types.VARCHAR};
*/
// execute insert query to insert the data
// return number of row / rows processed by the executed query
try {
// int row = template.update(insertSql, params, types);
trayMove trayMove = new trayMove();
trayMove = savetrayInfo(rto);
// trayMoveService.populate(trayMove); // return type ?
// trayMove row = trayMoveRepo.saveAndFlush(trayMove);
// logger.debug(row + " row inserted.");
} catch (Exception _ex) {
logger.debug("Exception executing sql query:( Message: "
+ _ex.getMessage());
logger.debug("Exception executing sql query:( Message: "
+ _ex.getStackTrace());
}
} else {
logger.debug("quote RTO is NULL");
}
return new ThumbsUp();
}
private Stopoff saveStopOff(trayquoteRto rto) {
// TODO Auto-generated method stub
return null;
}
private Location saveLocationInfo(trayquoteRto rto) {
// TODO Auto-generated method stub
return null;
}
public trayMove savetrayInfo(trayquoteRto rto) {
System.out.println("In savetrayInfo method");
//trayMove.setMoveId(100005);
trayMove.setMoveType("IPU");
System.out.println("In savetrayInfo MoveType");
System.out.println("setMoveType");
trayMove.setCarrierId(rto.getDriver());
trayMove.setLn(rto.getLn());
// TODO:rto.getName(); ??
trayMove.setShippersno(rto.getShippersno());
return trayMove;
}
public Location saveLocInfo(trayquoteRto rto) {
// location.set
// location.setAddress1(address1);
return location;
}
}
/*
* create table tray_move ( move_type varchar(16), carrier_id varchar(32), ln
* varchar(32) );
*/
class trayquoteRto {
private String type;
private String driver;
private String ln;
private String shippersno;
private String oramplocation;
private String orampadd1;
private String orampadd2;
private String orampphone;
private String orampstate;
private String orampzip;
private String dramplocation;
private String drampadd1;
private String drampadd2;
private String drampphone;
private String drampstate;
private String drampzip;
private List<Stops> stops = new ArrayList<Stops>();
public String getType() {
return type;
}
public String getDriver() {
return driver;
}
public String getLn() {
return ln;
}
public String getShippersno() {
return shippersno;
}
public String getOramplocation() {
return oramplocation;
}
public String getOrampadd1() {
return orampadd1;
}
public String getOrampadd2() {
return orampadd2;
}
public String getOrampphone() {
return orampphone;
}
public String getOrampstate() {
return orampstate;
}
public String getOrampzip() {
return orampzip;
}
public String getDramplocation() {
return dramplocation;
}
public String getDrampadd1() {
return drampadd1;
}
public String getDrampadd2() {
return drampadd2;
}
public String getDrampphone() {
return drampphone;
}
public String getDrampstate() {
return drampstate;
}
public String getDrampzip() {
return drampzip;
}
public List<Stops> getStops() {
return stops;
}
}
class Stops {
String name;
String add1;
String add2;
String city;
String ext;
String phone;
String st;
String zip;
Integer stop;
Date apptment1;
Date apptment2;
public String getName() {
return name;
}
public String getAdd1() {
return add1;
}
public String getAdd2() {
return add2;
}
public String getCity() {
return city;
}
public String getExt() {
return ext;
}
public String getPhone() {
return phone;
}
public String getSt() {
return st;
}
public String getZip() {
return zip;
}
public Date getApptment1() {
return apptment1;
}
public Date getApptment2() {
return apptment2;
}
public Integer getStop() {
return stop;
}
}
class ThumbsUp {
private String message = "success";
public String getMessage() {
return message;
}
}
#Service
#Repository
public class trayMoveService {
#Autowired
private trayMoveRepository trayMoveRepo;
#Qualifier("trayMove")
public void populate(trayMove dm) {
trayMoveRepo.saveAndFlush(dm);
}
}
#Transactional
public interface trayMoveRepository extends JpaRepository<trayMove, Integer>{
}
The setter method doesnt work. I think m missing some annotations. Can someone direct me to the tutorial please ?
The application is Spring JPA(EclipseLink) annotation based.

Facing difficulty with Hibernate HQL when applying it to H2

I am new to hibernate and spring maven environment.
I have tried implementing an embedded db using H2, which earlier used MySQL. there are two DAO's
OffersDao.java
package com.skam940.main.dao;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
#Repository
#Component("offersDao")
#Transactional
public class OffersDao {
#Autowired
private SessionFactory sessionFactory;
public Session session() {
return sessionFactory.getCurrentSession();
}
#SuppressWarnings("unchecked")
public List<Offer> getOffers() {
Criteria crit = session().createCriteria(Offer.class);
crit.createAlias("user", "u").add(Restrictions.eq("u.enabled", true));
return crit.list();
}
#SuppressWarnings("unchecked")
public List<Offer> getOffers(String username) {
Criteria crit = session().createCriteria(Offer.class);
crit.createAlias("user", "u");
crit.add(Restrictions.eq("u.enabled", true));
crit.add(Restrictions.eq("u.username", username));
return crit.list();
}
public void saveOrUpdate(Offer offer) {
session().saveOrUpdate(offer);
}
public boolean delete(int id) {
Query query = session().createQuery("delete from Offer where id=:id");
query.setLong("id", id);
return query.executeUpdate() == 1;
}
public Offer getOffer(int id) {
Criteria crit = session().createCriteria(Offer.class);
crit.createAlias("user", "u");
crit.add(Restrictions.eq("u.enabled", true));
crit.add(Restrictions.idEq(id));
return (Offer) crit.uniqueResult();
}
}
and UsersDao.java
package com.skam940.main.dao;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
#Repository
#Transactional
#Component("usersDao")
public class UsersDao {
#Autowired
private PasswordEncoder passwordEncoder;
#Autowired
private SessionFactory sessionFactory;
public Session session() {
return sessionFactory.getCurrentSession();
}
#Transactional
public void create(User user) {
user.setPassword(passwordEncoder.encode(user.getPassword()));
session().save(user);
}
public boolean exists(String username) {
Criteria crit = session().createCriteria(User.class);
crit.add(Restrictions.idEq(username));
User user = (User) crit.uniqueResult();
return user != null;
}
#SuppressWarnings("unchecked")
public List<User> getAllUsers() {
return session().createQuery("from User").list();
}
}
no the thing is I get an exception of
HTTP Status 500 - PreparedStatementCallback; bad SQL grammar [select username, password, enabled from users where binary username = ?]; nested exception is org.h2.jdbc.JdbcSQLException: Column "BINARY" not found; SQL statement:
And the thing I want to do here to make the username case sensitive, and apparently H2 recognises BINARY as a table name but not as a type or what ever you call that, can any one tell which which method is implementing this SQL grammar?
User.java
package com.skam940.main.dao;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import org.hibernate.validator.constraints.NotBlank;
import com.skam940.main.validation.ValidEmail;
#Entity
#Table(name="users")
public class User {
#NotBlank(groups={PersistenceValidationGroup.class, FormValidationGroup.class})
#Size(min=6, max=15, groups={PersistenceValidationGroup.class, FormValidationGroup.class})
#Pattern(regexp="^\\w{8,}$", groups={PersistenceValidationGroup.class, FormValidationGroup.class})
#Id
#Column(name="username")
private String username;
#NotBlank(groups={PersistenceValidationGroup.class, FormValidationGroup.class})
#Pattern(regexp="^\\S+$", groups={PersistenceValidationGroup.class, FormValidationGroup.class})
#Size(min=8, max=15, groups={PersistenceValidationGroup.class, FormValidationGroup.class})
private String password;
#ValidEmail(groups={PersistenceValidationGroup.class, FormValidationGroup.class})
private String email;
#NotBlank(groups={PersistenceValidationGroup.class, FormValidationGroup.class})
#Size(min=3, max=30, groups={FormValidationGroup.class})
private String name;
private boolean enabled = false;
private String authority;
public User() {
}
public User(String username, String name, String password, String email, boolean enabled,
String authority) {
this.username = username;
this.name = name;
this.password = password;
this.email = email;
this.enabled = enabled;
this.authority = authority;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public String getAuthority() {
return authority;
}
public void setAuthority(String authority) {
this.authority = authority;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((authority == null) ? 0 : authority.hashCode());
result = prime * result + ((email == null) ? 0 : email.hashCode());
result = prime * result + (enabled ? 1231 : 1237);
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result
+ ((username == null) ? 0 : username.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
User other = (User) obj;
if (authority == null) {
if (other.authority != null)
return false;
} else if (!authority.equals(other.authority))
return false;
if (email == null) {
if (other.email != null)
return false;
} else if (!email.equals(other.email))
return false;
if (enabled != other.enabled)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (username == null) {
if (other.username != null)
return false;
} else if (!username.equals(other.username))
return false;
return true;
}
#Override
public String toString() {
return "User [username=" + username + ", email=" + email + ", name="
+ name + ", enabled=" + enabled + ", authority=" + authority
+ "]";
}
}
Offer.java
package com.skam940.main.dao;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.validation.constraints.Size;
#Entity
#Table(name="offers")
public class Offer {
#Id
#GeneratedValue
// because this is an auto increment value
private int id;
#Size(min=5, max=255, groups={PersistenceValidationGroup.class, FormValidationGroup.class})
#Column(name="text")
private String text;
// every user can have only one offer
#ManyToOne
#JoinColumn(name="username")
private User user;
public Offer() {
this.user = new User();
}
public Offer(User user, String text) {
this.user = user;
this.text = text;
}
public Offer(int id, User user, String text) {
this.id = id;
this.user = user;
this.text = text;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String getUsername() {
return user.getUsername();
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((text == null) ? 0 : text.hashCode());
result = prime * result + ((user == null) ? 0 : user.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Offer other = (Offer) obj;
if (text == null) {
if (other.text != null)
return false;
} else if (!text.equals(other.text))
return false;
if (user == null) {
if (other.user != null)
return false;
} else if (!user.equals(other.user))
return false;
return true;
}
#Override
public String toString() {
return "Offer [id=" + id + ", text=" + text + ", user=" + user + "]";
}
}
the full file content is available here -> https://app.box.com/s/c3uq71khbwf05p8asu27
This query is coming from your Spring security configuration, please check security-context.xml, you can find Spring security authentication provider that uses authorities-by-username-query as
select username, authority from users where binary username = ?
This query uses MySQL-specific function BINARY for case-sensitive comparison (http://gilfster.blogspot.com/2005/08/case-sensitivity-in-mysql.html). H2, on the other hand, is case sensitive by default.
Try to change it with
select username, authority from users where username = ?
The same applies to users-by-username-query property.

Resources