Handling Cross-Origin Requests with Spring Cloud Gateway and HttpClient in Java
This article explains why cross‑origin issues occur, presents common solutions such as @CrossOrigin, HttpClient and Spring Cloud Gateway, and provides detailed code examples for configuring CORS, building a gateway module, and making HTTP requests in a Java backend project.
Why Cross-Origin Issues Occur
Browsers enforce the same‑origin policy for security, so requests from different origins (different ports, protocols, or domain names) are blocked.
Common Solutions to Cross-Origin Problems
Add the @CrossOrigin annotation on controller classes.
Use an HTTP client (e.g., HttpClient) that does not rely on the browser.
Deploy a gateway such as Spring Cloud Gateway to handle CORS centrally.
Annotation: @CrossOrigin
Adding the @CrossOrigin annotation to a controller resolves front‑back port cross‑origin issues within a project.
Gateway Integration
Spring Cloud Gatewayreplaces Netflix Zuul and provides unified routing, security, monitoring, rate‑limiting, and other gateway functions based on a filter chain.
(1) Routing
Each route has an ID, a destination URL, a set of predicates, and a set of filters. When the predicates evaluate to true, the request matches the route.
(2) Predicates
Predicate functions in Spring Cloud Gateway accept a ServerWebExchange object, allowing developers to match any request information such as headers or parameters.
(3) Filters
Filters are either Gateway Filter or Global Filter and can modify requests and responses.
When a request passes through the gateway, the Gateway Handler Mapping finds the matching route and forwards it to the Gateway Web Handler, which then executes the filter chain and invokes the target service.
Project Usage
Create a new module service_gateway and add the following Maven dependencies:
<dependencies>
<!-- Public module dependency -->
<dependency>
<groupId>com.lzq</groupId>
<artifactId>service_utils</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>Configuration file (application.yml or properties):
# Service port
server.port=9090
# Service name
spring.application.name=service-gateway
# Nacos address (default 8848)
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8888
# Enable discovery‑based routing
spring.cloud.gateway.discovery.locator.enabled=true
# Route definitions
spring.cloud.gateway.routes[0].id=service-hosp
spring.cloud.gateway.routes[0].uri=lb://service-hosp
spring.cloud.gateway.routes[0].predicates=Path=/*/hosp/**
spring.cloud.gateway.routes[1].id=service-cmn
spring.cloud.gateway.routes[1].uri=lb://service-cmn
spring.cloud.gateway.routes[1].predicates=Path=/*/cmn/**
spring.cloud.gateway.routes[2].id=service-user
spring.cloud.gateway.routes[2].uri=lb://service-user
spring.cloud.gateway.routes[2].predicates=Path=/*/userlogin/**Bootstrap class:
@SpringBootApplication
public class ApiGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(ApiGatewayApplication.class, args);
}
}Update the front‑end .evn file to point to the gateway port.
HttpClient
Typical use cases include inter‑system API calls and web crawling.
Example of a native HTTP request to fetch a page:
public class HttpTest {
@Test
public void test1() throws Exception {
String url = "https://www.badu.com";
URL url1 = new URL(url);
URLConnection urlConnection = url1.openConnection();
HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection;
InputStream is = httpURLConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(is, StandardCharsets.UTF_8);
BufferedReader br = new BufferedReader(reader);
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
}
// Set request method and headers
httpURLConnection.setRequestMethod("GET");
httpURLConnection.setRequestProperty("Accept-Charset", "utf-8");Using Apache HttpClient:
Create an HttpClient instance.
Instantiate HttpGet or HttpPost with the target URL.
Set request parameters via setParams or setEntity for POST.
Execute the request with client.execute(request) to obtain an HttpResponse.
Read response headers and body using getAllHeaders, getHeaders, and getEntity.
Release the connection in a finally block.
Dependency for testing:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>Example test using CloseableHttpClient:
@Test
public void test2() {
CloseableHttpClient client = HttpClients.createDefault();
String url = "https://www.baidu.com";
HttpGet httpGet = new HttpGet(url);
CloseableHttpResponse response = null;
try {
response = client.execute(httpGet);
String result = EntityUtils.toString(response.getEntity(), "utf-8");
System.out.println(result);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (client != null) {
try { client.close(); } catch (IOException e) { e.printStackTrace(); }
}
}
}Project Integration
Controller method to save hospital data:
@RequestMapping(value="/hospital/save", method=RequestMethod.POST)
public String saveHospital(String data, HttpServletRequest request) {
try {
apiService.saveHospital(data);
} catch (YyghException e) {
return this.failurePage(e.getMessage(), request);
} catch (Exception e) {
return this.failurePage("数据异常", request);
}
return this.successPage(null, request);
}Service implementation uses HttpRequestHelper to post data to another service:
@Override
public boolean saveHospital(String data) {
JSONObject jsonObject = JSONObject.parseObject(data);
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("hoscode", "10000");
paramMap.put("hosname", jsonObject.getString("hosname"));
paramMap.put("logoData", jsonObject.getString("logoData"));
JSONObject response = HttpRequestHelper.sendRequest(paramMap, this.getApiUrl() + "/api/hosp/saveHospital");
if (response != null && response.getIntValue("code") == 200) {
return true;
} else {
throw new YyghException(response.getString("message"), 201);
}
}Utility class HttpRequestHelper builds a POST payload and sends it via HttpUtil.doPost:
public static JSONObject sendRequest(Map<String, Object> paramMap, String url) {
StringBuilder postdata = new StringBuilder();
for (Map.Entry<String, Object> param : paramMap.entrySet()) {
postdata.append(param.getKey()).append("=").append(param.getValue()).append("&");
}
byte[] reqData = postdata.toString().getBytes("utf-8");
byte[] respData = HttpUtil.doPost(url, reqData);
return JSONObject.parseObject(new String(respData));
}Low‑level HTTP utility HttpUtil performs the actual connection handling.
Finally, a REST controller exposes an endpoint /api/hosp/saveHospital that receives the parameters, converts them to a Hospital object, and persists it to MongoDB.
With these configurations, cross‑origin requests are properly handled, and different systems can invoke each other through the gateway and HTTP client utilities.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Selected Java Interview Questions
A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
