SpringBoot 做代web理服务器
因公司业务需要,把多个子系统集成到一个平台,但是又不希望把代码重做一遍,子系统用nodejs,主平台用java,所以不能直接融合到一起。
一个想法就是,现在web开发都采用的前后台分离模式,把子平台的前台代码放在主平台的一个目录中,然后在主平台做一个代理,对接子平台的后台代码,主平台做个代理,这样不同平台代码就打通了。
今天尝试了下,springmvc框架,springboot提供很好用的代码可以简单来实现,以下是自己测试的小例子,供自己备忘,也希望能分享有需要的朋友!
- 测试采用的springboot的demo模块,从start.spring.io上下载
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.7</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- SpringBoot 下载来的例子中自带的Demo,补充个RestTemplate工具
package com.example.demo;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@ServletComponentScan
@EnableAutoConfiguration
public class DemoApplication {
// 启动的时候要注意,由于我们在controller中注入了RestTemplate,所以启动的时候需要实例化该类的一个实例
@Autowired
private RestTemplateBuilder builder;
// 使用RestTemplateBuilder来实例化RestTemplate对象,spring默认已经注入了RestTemplateBuilder实例
@Bean
public RestTemplate restTemplate() {
return builder.build();
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
//main1(null);
}
}
- 因为需要拦截界面对子系统的请求,所以添加了一个过滤器,拦截到子系统代码时做一次转发,代码如下
package com.example.demo;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@WebFilter(filterName = "myFilter", urlPatterns = "/*")
public class MyWebFilter implements Filter {
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public void destroy() {
logger.debug("...MyWebFilter destroy...");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
String requestURI = req.getRequestURI();
logger.debug("...MyWebFilter doFilter...");
logger.debug("req:" + requestURI);
if (requestURI.startsWith("/sub")) {
RequestDispatcher rd = req.getRequestDispatcher("/reset");
req.setAttribute("requestURI", requestURI);
rd.forward(req, resp);
return;
}
chain.doFilter(req, resp);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
logger.info("...MyWebFilter init...");
}
}
- *接下来重要一步就是写自己如果做的代理,其实本来想用httpclient来写,感觉有点复杂,后发网上发现RestTemplate是个好东西,减少了许多代码
package com.example.demo.action;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class MyAction {
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private RestTemplate restTemplate;
@RequestMapping("/")
public String home() {
return "Hello World!";
}
@RequestMapping("/next")
public String next(HttpServletRequest request, HttpServletResponse response) {
String reqURL = request.getRequestURI();
logger.debug("reqURL:"+reqURL);
return "next!";
}
@RequestMapping("/reset")
@ResponseBody
public Object reset(HttpServletRequest request, HttpServletResponse response) {
String reqURL = request.getRequestURI();
String queryString = request.getQueryString();
String orgURI = (String)request.getAttribute("requestURI");
logger.debug("reqURL:"+reqURL);
logger.debug("queryString:"+queryString);
//logger.debug("orgURI:"+orgURI);
String targetIP = "http://172.17.7.113:1780";
String targetURL = targetIP.concat(orgURI).concat("?").concat(queryString);
logger.debug("targetURL:"+targetURL);
Enumeration<String> params = request.getParameterNames();
Map<String,String> paramMap = new HashMap<String,String>();
while(params.hasMoreElements()){
String paraName = params.nextElement();
paramMap.put(paraName, request.getParameter(paraName));
}
String json = restTemplate.postForEntity(targetURL, paramMap, String.class).getBody();
System.out.println(json);
return json;
}
}
当我请求http://localhost:8080/sub/aa?id=1,代码restTemplate会帮我转发到targetURL ,并转发返回结果。
结论
- 当前简单的例子,还需要有所完善,比如说编码问题,返回未json格式
- 该功能只能实现对前后台有明确的ajax接口转发,具体的界面文件还不行,后面想继续完善。