LoginSignup
0
0

More than 1 year has passed since last update.

Angular×SpringBoot HttpClientでハマったのでメモ

Last updated at Posted at 2022-12-05

SPAを作ろうとAngularに安易に手を出し、ハマったのでメモ

1.subscribeは必ず書く

まず接続テストだけのつもりでsubscribeメソッドを書かずにいたら全然つながらなかった

下記のgetItemとgetItem2のメソッドの違いはHttpResponse型で受け取るかどうかだけです

sample.service.ts

export interface Item{
  title:string;
}

export class MaterialService {
  //Angularでリバースプロキシ設定する場合
  //private host: string = '/api';

  //Angularでリバースプロキシ設定しない場合
  private host: string = 'http://localhost:8080/api/v1';

  constructor(private http: HttpClient) {}

  getItem(){
    const rtn:Observable<HttpResponse<Item>> = this.http.get<Item>(this.host+'/sample',{observe:'response'}).pipe(
      timeout(5000),
      catchError(this.handleError)
    );
    //この時点ではまだHTTP通信はされてない
    //下記のsubscribeメソッドを実装してはじめて通信はしるよう
    rtn.subscribe({
      next:(response:HttpResponse<Item>) => {
        console.log('subscribe next')
        console.log(response)   
        //「title」が存在しなくてもエラーにはならず[undifined]
        console.log(response.body?.title)
      },
      error:(e)=>{
        //404の時など、handleErrorの後に実行される
        console.log('subscribe error')
        console.log(e);
      }
    });
  }

  getItem2(){
    const rtn:Observable<Item> = this.http.get<Item>(this.host+'/sample').pipe(
      timeout(5000),
      catchError(this.handleError)
    );

    rtn.subscribe({
      next:(response:Item) => {
        console.log('subscribe next')
        console.log(response)
        //「title」が存在しなくてもエラーにはならず[undifined]
        console.log(response.title)
      },
      error:(e)=>{
        //404の時など、handleErrorの後に実行される
        console.log('subscribe error')
        console.log(e);
      }
    });
  }


  private handleError(error: HttpErrorResponse) {
    console.log('handleError');
    if (error.status === 0) {
      // A client-side or network error occurred. Handle it accordingly.
      console.error('An error occurred:', error.error);
    } else {
      // The backend returned an unsuccessful response code.
      // The response body may contain clues as to what went wrong.
      console.error(
        `Backend returned code ${error.status}, body was: `, error.error);
    }
    // Return an observable with a user-facing error message.
    return throwError(() => new Error('Something bad happened; please try again later.'));
  }
}

2.CORSエラー対策

CORSエラーが発生するので以下3つのいずれかが必要
CORSについて参考サイト:
https://b1san-blog.com/post/spring/spring-cors/

①Angularでリバースプロキシ設定

下記をAngularのプロジェクトルートへ配置後、
「ng serve --proxy-config proxy.conf.json」で起動させる

proxy.conf.json
{
    "/api": {
        "target": "http://localhost:8080/api/v1",
        "pathRewrite": {
            "^/api": ""
        }
    }
}

②SpringBootでWebConfig作成

WebConfig
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
class WebConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
        .allowedOrigins("*")
        .allowedMethods("*");
    }
}

③SpringBootのControllerに@CrossOriginを付ける

AngularRestController
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@CrossOrigin//これ
@RequestMapping("/api/v1")
public class AngularRestController {;

  @GetMapping("/sample")
  public String getAll() {
      return "{\"title\":\"app\"}";
  }
}

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0