Get data in Angular 2 from Spring

Let’s say that I have a page rendered by Spring Framework. It is a page with Angular 2 code. How could I receive data on the page if Spring sends it? I do not want to render a page, then do an HTTP request, then get a response. No, in Spring controller I want to send data and somehow receive it with Angular 2 and show (without additional requests). With JSPs it is obvious how to do, but how to set Angular 2 model from JSON sent by Spring upon rendering the page?

What I have right now is Spring Security managing login. Then, in controller data gets prepared depending on the user, and then I want to send it to Angular 2 page. So, I am stuck with not knowing how to render a page AND attach data for it to be rendered by Angular 2 at the same time.

Difficulty creating a functional Angular2 post

I’m trying to send a post request to another service (a Spring application), an authentication, but I’m having trouble constructing a functional Angular2 post request at all. I’m using this video for reference, which is pretty new, so I assume the information still valid. I’m also able to execute a get request with no problems.

Here’s my post request:

export class LogIn {
    authUser: string;
    authPass: string;
    token: any;

    constructor(private _http:Http){}

    onSubmit() {
        var header = new Headers()
        var json = JSON.stringify({ user: this.authUser, password: this.authPass })
        var params2 = 'user=' + this.authUser + '&password=' + this.authPass
        var params = "json=" + json
        header.append('Content-Type', 'application/x-www-form-urlencoded')

        this._http.post("http://validate.jsontest.com", params, {
            headers: header
        }).map(res => res.json())
            .subscribe(
                data => this.token = JSON.stringify(data),
                err => console.error(err),
                () => console.log('done')
            );
        console.log(this.token);
    }
}

The info is being correctly taken from a form, I tested it a couple of times to make sure. I am also using two different ways to build the json (params and params2). When I try to send the request to http://validate.jsontest.com, the console prints undefined where this.token should be. When I try to send the request to the Spring application, I get an error on that side:

Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported

Does anyone know what I’m doing wrong?

Web Service Rest with Angular2 'POST'

this is my Service Typscript where I have the method Json post

 import {Injectable, Inject} from "angular2/core";
    import {Http, Headers} from "angular2/http";
    import 'rxjs/add/operator/map';
    import {User} from "../User/User";


    @Injectable()
    export class loginService {

        constructor(@Inject(Http) private _http:Http) {
        }
        enter code here

        postJSON(){
            var json = JSON.stringify({v:"value",a:"3"}); // var creds = "username=" + "khalil" + "&password=" + 3;   .map(res=>res.text());
            var headers = new Headers();
            headers.append('Content-Type','application/json');
            return this._http.post('http://localhost:8080/connect',json,{
                    headers:headers
                })
                .map(res=>res.json());

        }

this is my component with subscribe

import {Component, Inject} from 'angular2/core';
import {Router} from "angular2/router";
import {loginService} from "./login.service";
import {HTTP_PROVIDERS, Http} from "angular2/http";
import {User} from "../User/User";


@Component({
    selector: 'login',
    templateUrl: '../dev/login/login.html',
    providers: [HTTP_PROVIDERS, loginService]
})

export class TestComponent {

    getData:string;

    postData:string;

    constructor(private _router:Router,
                @Inject(Http) http:Http,
                private _loginService:loginService) {


    }


    postJson(){
        this._loginService.postJSON().subscribe(
            data => this.postData = JSON.stringify(data),
            error => alert(this.postData + error),
            () => console.log("finished")
        );
    }
}        
        }

server side I work with spring 4

this is my controller

@RestController
@CrossOrigin()
public class HomeController {


    @RequestMapping(value = "/connect", method = RequestMethod.POST,produces = MediaType.APPLICATION_JSON_VALUE)
    public @ResponseBody String connect(String v, String a) {
        int i = Integer.parseInt(a);
        if (v.equals("khalil") && i == 3) {
            System.out.println("----------------------***********************---------------------");
        } else {
            System.out.println("----------------------**** elseeeeee *******************---------------------");

        }
        return v+a;

    }
}

when I try to call a web service rest I get this error

 POST http://localhost:8080/connect 500 (Internal Server Error)(anonymous function)
 @ http.js:683Observable.subscribe 
@ Rx.js:11006Observable._subscribe
 @ Rx.js:11038Observable.subscribe 
@ Rx.js:11004loginComponent.postJson
 @ login.component.ts:63ChangeDetector_loginComponent_0.handleEventInternal 
@ viewFactory_loginComponent:415AbstractChangeDetector.handleEvent
 @ angular2.js:9568AppView.triggerEventHandlers
 @ angular2.js:10246(anonymous function)
 @ viewFactory_loginComponent:558(anonymous function)
 @ angular2.js:14068(anonymous function)
 @ angular2.js:13496ZoneDelegate.invoke 
@ angular2-polyfills.js:332NgZoneImpl.inner.inner.fork.onInvoke 
@ angular2.js:2111ZoneDelegate.invoke
 @ angular2-polyfills.js:331Zone.runGuarded 
@ angular2-polyfills.js:241NgZoneImpl.runInner
 @ angular2.js:2140NgZone.run
 @ angular2.js:13649outsideHandler 
@ angular2.js:13495ZoneDelegate.invokeTask
 @ angular2-polyfills.js:365Zone.runTask
 @ angular2-polyfills.js:263ZoneTask.invoke 
@ angular2-polyfills.js:431

thanks for helping me ^^

Angular2 missing Set-Cookie in response from REST service

Goal

The goal is to call a remote login-service with HTTP Basic and receive the JSESSIONID for further usage.

Tested backend

So far I achieved the service call including a 200 response. My tests with restassured work smoothly and indicates that the JSESSIONID is properly provided by the login-service. The spring backend service is annotated with @CrossOrigin.

// assure we are not logged in
RestAssured.baseURI = "https://" + ip;
RestAssured.basePath = "/user";
Response responseA = post("/create"); // /user/create is a secured service
assertEquals(401, responseA.statusCode());

// log in and save the token
RestAssured.baseURI = "https://" + username + ":pass@" + ip; // http basic auth is used
RestAssured.basePath = "/user";
Response responseB = post("/login");
assertEquals(200, responseB.statusCode());

String jsessionId = responseB.getCookie("JSESSIONID");
// C50C28EA1F3ABBB76F0E4189A772A4E9

RestAssured.baseURI = "https://" + ip;
RestAssured.basePath = "/user";

// call a service without token or credentials --> 401
Response responseC = get("/id"); // /user/id is a secured service
assertEquals(401, responseC.statusCode());

// call a service with the token
RestAssured.sessionId = jsessionId;
Response responseD = get("/id");
assertEquals(200, responseD.statusCode());

The test is green.

Frontend problems

In our Angular2 frontend app we have a login page, whose submit button runs the following code through the onSubmit() method.

_url = "theLoginServiceUrl"

createAuthorizationHeader(username: string, password: string, headers:Headers) {
    headers.append('Authorization', 'Basic ' + btoa(username + ':' + password));
    // tried all of these, but they didn't fix the problem
    // headers.append('Access-Control-Allow-Origin', '*');
    // headers.append('Access-Control-Allow-Headers', '*');
    // headers.append('Access-Control-Allow-Methods', '*');
}

login (username: string, password: string) {
    let headers = new Headers();
    this.createAuthorizationHeader(username, password, headers);
    return this._http.post(this._url, "", {
        headers: headers
    });
}

onSubmit() {
    this.login(this.currentUser.username, this.currentUser.password)
        .subscribe((res) => {
                var headers = res.headers;
                console.log(headers); 
                // Headers {_headersMap: Map}
                // <entries>[3]
                // {"Pragma" => Array[1]}
                // {"Cache-Control" => Array[1]}
                // {"Expires" => Array[1]}

                var setCookieHeader = headers.get('Set-Cookie');
                console.log(setCookieHeader)
                // null
            }
        );
}

As you see from the comments I am not able to access Set-Cookie header. In the browser however I see the successful calls including the Set-Cookie header:

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
X-Frame-Options: DENY
Set-Cookie: JSESSIONID=58A072F2BB40A711CB42233CA4EB7BF6; Path=/; Secure; HttpOnly
Access-Control-Allow-Origin: http://localhost:3000
Vary: Origin
Access-Control-Allow-Credentials: true
Content-Length: 0
Date: Fri, 06 May 2016 10:43:21 GMT

Note that this all runs through HTTPS.

Frontend details:

  • "typescript": "^1.7.5"
  • "angular2": "2.0.0-beta.7"

Question:

Why can’t I access the Set-Cookie within my Angular2 code? What do I have to change?

Spring + angularjs2 + war

I want to create web application with spring using maven and angularjs2 and want to create war file at the end to deploy.
When we install angularjs2 and angular-material2, node_modules itself takes 175mb. Due to which war file will get heavy. Is there a way to minimize its size or to skip files which are not required. I thought of keeping only js files and removing all ts files from node_modules but in each folder of angularjs, there are more than one js file. One file is common in all folder which is index.js and this file also depends on many other files. Now I’m not getting which all js files to keep and which all are need to remove. Is there any tool or script available which can do this for me?
Is there any other way of achieving this?

Angular2 does not pass parameters in POST request

I am trying to pass a parameter using Angular POST request to Tomcat server, Spring Framework. Somehow I see that the parameter is there when it is sent, but it somehow does not arrive/properly retrieved on the backend. Here is the Angular2 code:

addCompany() {
  console.log("addCompany button clicked!");
  console.log("company name: " + this.input);
  let nameId = this.input;
  let body = JSON.stringify({ input: nameId });
  let headers = new Headers({ 'Content-Type': 'application/json', 'X-CSRF-TOKEN':this.getToken() });
  console.log("csrf token: " + this.getToken());
  let options = new RequestOptions({ headers: headers });
this.http.post('http://localhost:8080/views/addcompany', body, options).toPromise()
    .then(() => {
      console.log("company added!");
      this.reloadList();
    });;
}

When I am trying to get it in Spring I am getting null for the parameter:

@RequestMapping(value = "/addcompany", method = RequestMethod.POST)
@ResponseBody
public void addCompany(HttpServletRequest request,
        HttpServletResponse response) {
    String nameId = request.getParameter("input");
    eventService.addCompany(nameId);
}

I tried also this way:

@RequestMapping(value = "/addcompany", method = RequestMethod.POST)
@ResponseBody
public void addCompany(Model model, @RequestParam("input") String nameId) {
    eventService.addCompany(nameId);
}

And in Angular code I have been trying to change commas everywhere, like:

  let nameId = this.input;
  let body = JSON.stringify({ 'input': nameId });

etc.

I tried this one: Angular2 – Http POST request parameters

Following the suggestion JB Nizet I tried to create POJO:

public class Company {
public String input;

public Company() {
    this.input = "";
}

public String getInput() {
    return this.input;
}

public void setInput(String input) {
    this.input = input;
}
}

Register it in my @Configuration file:

@Bean
public Company getCompany(){
    return new Company();
}

And changed the request method to the following:

@RequestMapping(value = "/addcompany", method = RequestMethod.POST)
@ResponseBody
public void addCompany(Company company) {
    eventService.addCompany(company.input);
}

After that I am getting Company object in the method with input=null.

Then I tried to deregister the Company @Bean from @Configuration and change the request method to the following:

@RequestMapping(value = "/addcompany", method = RequestMethod.POST)
@ResponseBody
public void addCompany(@RequestBody Company company) {
    eventService.addCompany(company.input);
}

But after that I am getting 415 (Unsupported Media Type) error.

In pom.xml I have the following jackson import:

    <dependency>  
         <groupId>org.codehaus.jackson</groupId>  
         <artifactId>jackson-mapper-asl</artifactId>  
         <version>1.9.10</version>  
    </dependency> 

Substituting it for second jackson version solved the issue:

    <properties>
        ...
        <jackson.version>2.7.5</jackson.version>
    </properties>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>${jackson.version}</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>${jackson.version}</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>${jackson.version}</version>
    </dependency>

Exclude Angluar2 route from Spring Web MVC application

I have a spring-boot application that has a few views set up. I also have bundled an Angular2 app. When I load the Angular2 app, all works fine, however, when I try to deep link to a route within the application, Spring MVC is intercepting the call, failing to find an associated view and returning the error page.

http://localhost:8080/index.html will load the Angular2 application which then re-writes the URL to be just http://localhost:8080/. If I then navigate to the route I want e.g. http://localhost:8080/invite/12345, then the route loads and works as expected. Hitting http://localhost:8080/invite/12345 directly returns the standard Spring MVC error page.

However, if I run the Angular2 app as a standalone application (not served up by spring-boot), then hitting that link directly works as expected. it loads the index.html, fires the route and shows me the data I want.

How can I, via Java configuration, tell Spring to ignore the /invite/** path (and other paths too as my Angular2 app grows) so I can deep-link to routes within my Angular2 application. Here’s the current Java configuration:

@SpringBootApplication
@EnableResourceServer
public class AuthserverApplication extends WebMvcAutoConfigurationAdapter {

    public static void main(String[] args) {
        SpringApplication.run(AuthserverApplication.class, args);
    }

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/login").setViewName("login");
        registry.addViewController("/oauth/confirm_access").setViewName("authorize");
        registry.addViewController("/success").setViewName("success");
    }

    @Bean
    public ViewResolver getViewResolver() {
        final InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setSuffix(".html");
        return resolver;
    }
}

This project is inheriting from spring-boot 1.3.3.RELEASE:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.3.3.RELEASE</version>
</parent>

Angular2 Spring Authentication

I have separate Angular2 Client and Spring hosted servers.
My Angular2 application is able to call rest call of the spring.
But, I am facing few difficulties to do CSRF authentication with Spring.

main.ts:

    import { CsrfBaseRequestOptions } from './app/shared';

    bootstrap(AppComponent, [
      ROUTER_PROVIDERS,
      HTTP_PROVIDERS,
      ...
      provide(RequestOptions, { useClass: CsrfBaseRequestOptions })
    ]);
    XhrBaseRequestOptions:

    @Injectable()
    export class XhrBaseRequestOptions extends BaseRequestOptions {

      constructor() {
        super();

        this.headers.append('X-Requested-With', 'XMLHttpRequest');
      }

    }
    CsrfBaseRequestOptions:

    import { Injectable } from '@angular/core';
    import { XhrBaseRequestOptions } from './xhr-base-request-options';

    @Injectable()
    export class CsrfBaseRequestOptions extends XhrBaseRequestOptions {

      constructor() {
        super();

        let csrfToken = this.getCsrfToken('X-CSRF-TOKEN');
        if (csrfToken) {
          this.headers.append('X-CSRF-TOKEN', csrfToken);
        }
      }

      getCsrfToken(tokenName:string):string {
        let tokenNameEQ = tokenName + '=';
        let ck = document.cookie;
        let ca = ck.split(';');

        for (let i = 0; i < ca.length; i++) {
          let c = ca[i];
          while (c.charAt(0) === ' ') c = c.substring(1, c.length);
          if (c.indexOf(tokenNameEQ) === 0) return c.substring(tokenNameEQ.length, c.length);
        }
        return null;
      }

    }

    index.ts

    onSubmit(event, username, password) {
            this.headers = new Headers();
            this.headers.append("Content-Type", 'application/json');
            let body = JSON.stringify({username, password});
            this.http.post('http://localhost:8080/EEP/test', body, { headers: this.headers })
                .subscribe((res) => this.token = res.json())


        }

hear Nothing is happening.

THanks in advance if you help me to call the Spring ..

Trigger Batch Job using rest webservice

My application is built on spring boot and angular 2. I am uploading a excel file from the angular 2 UI, which will be saved in server. I am planning to read this file and save it in DB using batch Job. I want to trigger the job using the rest webservice, Is this possible? My Aim is to trigger the job which reads the file and my services should not wait for the response. Any suggestions?