下面聊聊我在解决这个方法上, 用的方法.
我先说一下我的思路:这是一个功能, 所以不能写的太死, 最好得写成配置, 用一套机制去让他们自动管理. 我把所有需要转化的URL全写在properties文件里, 也可以写在数据库中, 我觉得写的配置文件里, 维护起来"实在"些. 每次都会这种感觉. 哈哈~~ 然后, 项目启动是, 将这些全部加载到Map里. 转换的时候, 我们去看Map是否存在, 存在OK, 我转换成我想要的URL. 没有, 我不管.
我们看看具体的代码:
资源文件: urlmapper-server.properties
# question detail
/wenda/question/question!fetchQuestion.action=/question/detail?qid=qid&aid=aid
# party detail
/wenda/party/detail.action=/party/detail?pid=pid
# share detail
/wenda/question/question!fetchShareInfo.action=/share/detail?qid=qid
# settings
/wenda/notify/index!setting.action=/my/setting
# question index
/wenda/question/question!index.action=/question
# share index
/wenda/share/shareAction!allShare.action=/share
# party index
/wenda/party/partyIndexAction.action=/party
解释一下这个配置文件, 这里的key对应原URL的path部分(/wenda/question/question!fetchQuestion.action), value的?以前就是我们新的path, ?以后就是可选的参数. 每个param "="前表示新的key, "="后表示旧的key. 大概是说明白了.
下面, 我需要在系统启动是, 加载这里的配置.URLMapperLoader.java
// ---------------------------------- filed names ---------------------------------
private static final String serverConfig = "/urlmapper-server.properties";
private static final String clientConfig = "/urlmapper-client.properties";
// ---------------------------------- main methods --------------------------------
/**
* 服务端为客户端转义URL规则
*
* @return
*/
public static Map<String, Map<String, String>> serverLoader() {
Map<String, Map<String, String>> urlMapper = new HashMap<String, Map<String, String>>();
Properties properties = new Properties();
try {
properties.load(URLMapperLoader.class.getResourceAsStream(serverConfig));
} catch (IOException e) {
e.printStackTrace();
}
Enumeration<Object> _enum = properties.keys();
while (_enum.hasMoreElements()) {
String key = (String) _enum.nextElement();
String value = (String) properties.get(key);
Map<String, String> map = new HashMap<String, String>();
String[] values = value.split("[?]");
map.put("url", values[0]);
if (values.length > 1) { // 说明是有参数的, 需要为参数做Mapper
String query = values[1];
String[] params = query.split("[&]");
for (int i = 0; i < params.length; i++) {
String param = params[i];
String[] p = param.split("[=]");
map.put(p[0], p[1]);
}
}
urlMapper.put(key, map);
}
return urlMapper;
}
/**
* 客户端自己内部跳转规则
*
* @return
*/
public static Map<String, Map<String, String>> clientLoader() {
Map<String, Map<String, String>> urlMapper = new HashMap<String, Map<String, String>>();
Properties properties = new Properties();
try {
properties.load(URLMapperLoader.class.getResourceAsStream(clientConfig));
} catch (IOException e) {
e.printStackTrace();
}
Enumeration<Object> _enum = properties.keys();
while (_enum.hasMoreElements()) {
// TODO 解析未完成
}
return urlMapper;
}
这样子, 所有的配置会以Map的形式放在内存中. 我们需要的时候,就去get吧.
具体转换:URLMapperService.java
public String web2ClientUrlRowMapper(String url) {
if (StringUtils.isEmpty(url)) {
return "";
}
// 获取URL的path部分
String path = URIUtil.getPath(url);
if (StringUtils.isEmpty(path)) {
return "";
}
// 强制转换
Map<String, Map<String, String>> urlMap = (Map<String, Map<String, String>>) configService.get(SERVER_KEY);
Map<String, String> map = urlMap.get(path);
if (map == null) {
return url;
}
// 开始转义
String query = URIUtil.getQuery(url);
Map<String, String> params = params2Map(query);
StringBuilder URL = new StringBuilder();
URL.append(Constants.DOMAIN);
URL.append(map.get("url"));
if (map.size() > 1) { //说明包含有参数 qid=12001&aid=2323
URL.append("?");
for (String key : map.keySet()) {
if (!key.equals("url")) {
URL.append(key);
URL.append("=");
URL.append(params.get(map.get(key)));
URL.append("&");
}
}
// 去掉最后的"&"
URL.setLength(URL.length() - 1);
}
return URL.toString();
}
/**
* 将参数变成Map
*
* @param params
* @return
*/
public static Map<String, String> params2Map(String params) {
Map<String, String> map = new HashMap<String, String>();
if (StringUtils.isEmpty(params)) {
return map;
}
String[] param = params.split("[&]");
if (param == null || param.length == 0) {
return map;
}
for (int i = 0; i < param.length; i++) {
String str = param[i];
String[] pair = str.split("[=]");
try {
map.put(pair[0], pair[1]);
} catch (Exception e) {
}
}
return map;
}
测试:
public static void main(String[] args) {
URLMapperService urlMapperService = new URLMapperService();
String url = "http://www.dianziq.com/wenda/question/question!fetchQuestion.action?qid=17200&aid=2145";
System.out.println(URIUtil.getPath(url));
System.out.println(URIUtil.getQuery(url));
url = urlMapperService.web2ClientUrlRowMapper(url);
System.out.println("NEW URL: " + url);
url = "http://www.dianziq.com/wenda/party/detail.action?pid=443" ;
// System.out.println(URIUtil.getPath(url));
url = urlMapperService.web2ClientUrlRowMapper(url);
System.out.println("NEW URL: " + url);
url = "http://www.dianziq.com/wenda/question/question!fetchShareInfo.action?qid=17257" ;
// System.out.println(URIUtil.getPath(url));
url = urlMapperService.web2ClientUrlRowMapper(url);
System.out.println("NEW URL: " + url);
url = "http://www.dianziq.com/wenda/notify/index!setting.action" ;
// System.out.println(URIUtil.getPath(url));
url = urlMapperService.web2ClientUrlRowMapper(url);
System.out.println("NEW URL: " + url);
url = "http://www.dianziq.com/wenda/question/question!index.action" ;
// System.out.println(URIUtil.getPath(url));
url = urlMapperService.web2ClientUrlRowMapper(url);
System.out.println("NEW URL: " + url);
url = "http://www.dianziq.com/wenda/share/shareAction!allShare.action" ;
// System.out.println(URIUtil.getPath(url));
url = urlMapperService.web2ClientUrlRowMapper(url);
System.out.println("NEW URL: " + url);
url = "http://www.dianziq.com/wenda/party/partyIndexAction.action" ;
// System.out.println(URIUtil.getPath(url));
url = urlMapperService.web2ClientUrlRowMapper(url);
System.out.println("NEW URL: " + url);
}
结果:
/wenda/question/question!fetchQuestion.action
qid=17200&aid=2145
NEW URL: http://localhost:8080/question/detail?qid=17200&aid=2145
NEW URL: http://localhost:8080/party/detail@pid=pid
NEW URL: http://localhost:8080/share/detail?qid=17257
NEW URL: http://localhost:8080/my/setting
NEW URL: http://localhost:8080/question
NEW URL: http://localhost:8080/share
NEW URL: http://localhost:8080/party
这样子就算转换完了, 以后有新的url需要转换, 就可以在配置文件里面配置就可以了.