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

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

Related

Implement properly list of Objects from rest api

I want to implement Angular example which gets list from rest API. I tried this:
SQL query:
#Override
public Iterable<Merchants> findAll() {
String hql = "select e from " + Merchants.class.getName() + " e";
TypedQuery<Merchants> query = entityManager.createQuery(hql, Merchants.class);
List<Merchants> merchants = query.getResultList();
return merchants;
}
Rest controller:
#RestController
#RequestMapping("/merchants")
public class MerchantController {
#GetMapping("/list")
public Iterable<Merchants> getMerchantsList() {
return merchantRepository
.findAll();
}
}
Service:
#Injectable({
providedIn: 'root'
})
export class MerchantService {
constructor(private http: HttpClient) {
}
getList() {
return this.http.get("...../api/merchants/list");
}
}
Component:
#Component({
selector: 'app-terminal',
templateUrl: './terminal.component.html',
styleUrls: ['./terminal.component.scss']
})
export class TerminalComponent implements OnInit {
merchants: Merchant[];
constructor(private merchantService: MerchantService,
private router: Router,
private route: ActivatedRoute) {
}
ngOnInit() {
this.merchantService.getList();
}
}
But when I lock the component via web page nothing happens. Can you give me some advice where I'm wrong?
Probably my typescript is somewhere incorrect?
You need to call subscribe on the Observable, otherwise it won't make the HTTP request
ngOnInit() {
this.merchantService.getList().subscribe(res => {
console.log("The response is", res);
});
}

Getting HTTP 404 error in Spring login

Error:
HTTP Status 404 – Not Found
Type Status Report
Message /DemoTask/
Description The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.
Apache Tomcat/7.0.90
Code:
import com.demo.bean.Login;
#Controller
public class LogController {
#RequestMapping({ "/login" })
public String showHome(#ModelAttribute("login") Login login) {
String name = login.getUname();
String password = login.getUpass();
if ((name.equals("hello")) && (password.equals("hello"))) {
return "redirect:admin.do";
}
return "login";
}
#RequestMapping({ "login" })
public String showLogin() {
return "login";
}
}
Ambigious Request Mapping for the uri "login".
Added request type to mapping as below
#Controller
public class LogController {
#RequestMapping(value = { "/login" }, method = RequestMethod.POST)
public String showHome(#ModelAttribute("login") Login login) {
String name = login.getUname();
String password = login.getUpass();
if ((name.equals("hello")) && (password.equals("hello"))) {
return "redirect:admin.do";
}
return "login";
}
#RequestMapping(value = { "login" }, method = RequestMethod.GET)
public String showLogin() {
return "login";
}
}

How to use Angular Observable

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.

Cannot read property ‘children’ of undefined ionic

I am getting an error while trying to read a json. I am using asp.net web api.
My code looks like this:
export class ProdutoListaPage {
public produto: Array<string>;
private url: string = "http://localhost:50907/api/consulta/BuscaProduto";
constructor(public navCtrl: NavController, public navParams: NavParams, public http:Http) {
this.http.get(this.url).map(res => res.json())
.subscribe(data => {
this.produto = data.data.children;
});
}
ionViewDidLoad() {
console.log('ionViewDidLoad ProdutoListaPage');
}
}
If your api response is this : the correct way to assign the produto array is this : this.produto = data;

After accepting data with #requestbody, I want to return message or realize webpage-jump

Controller:
#RequestMapping(value="receive", method=RequestMethod.POST, consumes="application/json")
#ResponseBody
public RegInfo receiveData(#RequestBody RegInfo info){
String reg_check = regInfoService.checkRegInfo(info);
......
}
RegInfo:
public class RegInfo {
private String account;
private String passwords;
private String realname;
private String phonenumber;
private String sex;
private String mailname;
.......}
register.jsp:
$("#sub").click(function(){
var m = {
"account": $("#_account").val(),
"passwords": $("#_pass").val(),
"realname": $("#real_name").val(),
"phonenumber": $("#phone_number").val(),
"sex": $("input:checked").val(),
"mailname": $("#mail_name").val()
};
$.ajax({
type:"POST",
async : false,
url:"/demo/user/receive",
dataType:"json",
contentType:"application/json; charset=utf-8",
data:JSON.stringify(m),
success:function(data){
alert("ok");
alert(data.realname);
},
erroe:function(data){
alert("保存失败 ")
}
})
});
Now I want to check RegInfo in the controller. If the result of check is legal, I want to jump to other webpage like login.jsp and if it is illegal, I want to return some message and show the message in register.jsp. How can I realize it?
complete Controller:
#Controller
#RequestMapping("/user")
public class LoginController {
#Autowired
private UserService userService;
#Autowired
private RegInfoService regInfoService;
#RequestMapping("/login")
public String homePage(){
return "user/login";
}
#RequestMapping("/loginin")
public String toLogin(#ModelAttribute("user")User user){
String u = userService.loginCheck(user);
System.out.println(u);
if(u == "success"){
return "user/success";
}
else{
return "user/login";
}
}
#RequestMapping("/register")
public String toRegister(){
return "user/register";
}
#RequestMapping("/success")
public String toSuccess(){
return "user/success";
}
#RequestMapping(value="receive", method=RequestMethod.POST, consumes="application/json")
#ResponseBody
public RegInfo receiveData(#RequestBody RegInfo info){
String reg_check = regInfoService.checkRegInfo(info);
System.out.println(reg_check);
System.out.println(info);
System.out.println(info.getRealname());
return info;
}
}
I want to jump to other webpage like login.jsp and if it is illegal, I
want to return some message and show the message in register.jsp. How
can I realize it?
Simple, in your AJAX success handler redirect with URL parameters like:
$.ajax({
type:"POST",
async : false,
url:"/demo/user/receive",
dataType:"json",
contentType:"application/json; charset=utf-8",
data:JSON.stringify(m),
success:function(data){
alert("ok");
alert(data.realname);
if (data.realname != undefined || data.realname!= null) {
window.location = '/login?realname=' + data.realname;
}
},
erroe:function(data){
alert("保存失败 ")
}
});
EDITS:
based on your comment the controller method will look like:
#Controller
#RequestMapping("/user")
public class LoginController {
#RequestMapping("/login")
public String homePage(Mode model, #RequestParam(value="realname",required=false)String realName){
if(realName!=null && (!realName.trim().isEmpty())){
model.addAttribute("regSuccessUser",realName);
}
return "user/login";
}
}
and redirect statement will look like:
window.location = '/user/login?realname=' + data.realname;
Note: URL start with contextPath to avoid 404 problems
I test as follows:
<input type="button" value="test" onClick="newpage()">
function newpage(){
window.location="/demo/user/login";}
then it jump to login.jsp successfully.In the ajax,it had run to "window.location" but didn't jump.It looks so strange.
Final solution:
error:
<input type="submit" id="sub" value="save" >
true:
<input type="button" id="sub" value="save" >
Form is submitted twice.

Resources