2013-02-06 8 views
34

spring mvcフレームワークを使用してRESTサービスを公開するWebアプリケーションをビルドしました。 例えば:spring mvc rest serviceリダイレクト/フォワード/プロキシ

@Controller 
@RequestMapping("/movie") 
public class MovieController { 

@RequestMapping(value = "/{id}", method = RequestMethod.GET) 
public @ResponseBody Movie getMovie(@PathVariable String id, @RequestBody user) { 

    return dataProvider.getMovieById(user,id); 

} 
. 
. 
. 

は今、私は自分のアプリケーションを展開する必要があるが、私は次のような問題があります(ファイアウォールがあります) クライアントがアプリケーションが常駐上のコンピュータに直接アクセスすることはできませんが。したがって、実際の休憩サービスを呼び出すプロキシマシン(クライアントからアクセス可能)にリダイレクト層が必要です。例えば :

私はRestTemplateを使用して新しいコールを作ってみました

@Controller 
@RequestMapping("/movieProxy") 
public class MovieProxyController { 

    private String address= "http://xxx.xxx.xxx.xxx:xx/MyApp"; 

    @RequestMapping(value = "/{id}", method = RequestMethod.GET) 
    public @ResponseBody Movie getMovie(@PathVariable String id,@RequestBody user,final HttpServletResponse response,final HttpServletRequest request) { 

     HttpHeaders headers = new HttpHeaders(); 
     headers.setContentType(MediaType.APPLICATION_JSON); 
     RestTemplate restTemplate = new RestTemplate(); 
     return restTemplate.exchange(address+ request.getPathInfo(), request.getMethod(), new HttpEntity<T>(user, headers), Movie.class); 

} 
. 
. 
. 

これはokですが、私はresttemplateを使用するには、コントローラの各メソッドを書き換える必要があります。また、これにより、プロキシマシンでの冗長シリアル化/逆シリアル化が行われます。

私はrestemplateを使用して、一般的な機能を書いてみましたが、それがうまくいかなかった:

@Controller 
@RequestMapping("/movieProxy") 
public class MovieProxyController { 

    private String address= "http://xxx.xxx.xxx.xxx:xx/MyApp"; 

    @RequestMapping(value = "/**") 
    public ? redirect(final HttpServletResponse response,final HttpServletRequest request) {   
     HttpHeaders headers = new HttpHeaders(); 
     headers.setContentType(MediaType.APPLICATION_JSON); 
     RestTemplate restTemplate = new RestTemplate(); 
     return restTemplate.exchange(address+ request.getPathInfo(), request.getMethod(), ? , ?); 

} 
. 
. 
. 

私はリクエストとレスポンスのオブジェクトと連携resttemplateの方法を見つけることができませんでした。

また、スプリングリダイレクトとフォワードを試みました。しかし、リダイレクトはリクエストのクライアントIPアドレスを変更しないので、この場合は役に立たないと思います。私は別のURLにも転送できませんでした。

これを達成するより適切な方法はありますか? ありがとうございます。

+2

あなたがこれを行うために/ mod_rewriteのか、mod_proxyをwがApacheのようなものを使用することができませんでしたのはなぜ?基本的にはファイアウォールの外側にウェブサーバー(通常はDMZと呼ぶ)を設置し、ファイアウォールの背後にあるサーバーと通信できるようにFWにルールを設定します。これはほとんどの企業がこの問題を解決する方法です。 – CodeChimp

+0

ありがとうございました。あなたのソリューションが私たちのために働くならば、私はsysの管理者と話そうとします。一方、resttemplateを使用して、jsonデータをシリアル化/シリアル化して文字列に変換します。 – nilgun

答えて

1

もっと単純な方法であるmod_proxyのような下位レベルのソリューションを使用しても遠ざけることができますが、より多くの制御(セキュリティ、翻訳、ビジネスロジックなど)が必要な場合は、 Apacheのキャメル:これは、任意のヘッダを反映していないだろう

private String server = "localhost"; 
private int port = 8080; 

@RequestMapping("/**") 
@ResponseBody 
public String mirrorRest(@RequestBody String body, HttpMethod method, HttpServletRequest request, 
    HttpServletResponse response) throws URISyntaxException 
{ 
    URI uri = new URI("http", null, server, port, request.getRequestURI(), request.getQueryString(), null); 

    ResponseEntity<String> responseEntity = 
     restTemplate.exchange(uri, method, new HttpEntity<String>(body), String.class); 

    return responseEntity.getBody(); 
} 

http://camel.apache.org/how-to-use-camel-as-a-http-proxy-between-a-client-and-server.html

39

あなたは/プロキシにこれですべての要求を反映することができます。

+0

私はあなたのような答えを期待していましたが、それは長い時間がかかりました。残念ながら、包括的なテストを行い、今すぐあなたのコードを確認することはできません。 – nilgun

+0

このコントローラーのURLとパラメーターはどのように見えますか?私は正しいURLを呼び出しましたが、クライアントから送信された要求は構文的に正しくありません。 – WowBow

+0

私のオリジナルのメソッドのシグネチャは次のようになります(私はすべてのRequestBodyまたはHTTPMETHODを持っていなかった) @RequestMapping( "/ getProduct") 公共CUSTOMMESSAGEのgetCompanyResults(@RequestParam( "検索")文字列検索、 @RequestParam(値= "id"、required = false)String rfgId、 @RequestParam(value = "rowBegin"、required = false)文字列) – WowBow

4

Netflix Zuulを使用して、バネアプリケーションからの要求を別のバネアプリケーションにルーティングできます。

のは、あなたが2つのアプリケーションがあるとしましょう:最初のzuul dependecyを追加し、その後、あなたは、単にアプリケーションであなたのルーティングルールを定義することができ、API-ゲートウェイ・アプリケーションで1.songsアプリ、2.apiゲートウェイ

を。 YMLは、次のように:

のpom.xml

<dependency> 
    <groupId>org.springframework.cloud</groupId> 
    <artifactId>spring-cloud-starter-zuul</artifactId> 
    <version>LATEST</version> 
</dependency> 

application.yml

server: 
    port: 8080 
zuul: 
    routes: 
    foos: 
     path: /api/songs/** 
     url: http://localhost:8081/songs/ 

と最後のようなAPIゲートウェイアプリケーションを実行します。今

@EnableZuulProxy 
@SpringBootApplication 
public class Application { 
    public static void main(String[] args) { 
     SpringApplication.run(Application.class, args); 
    } 
} 

を、ゲートウェイルートhttp://localhost:8081/songs/へのすべての要求/api/songs/ます。

実施例はここにある:https://github.com/muatik/spring-playground/tree/master/spring-api-gateway

別のリソース:http://www.baeldung.com/spring-rest-with-zuul-proxy

関連する問題