Legendshop开讲时间

Legendshop的开发哥又来送福利了,今天要给大家科普一下Java如何实现二级域名访问卖家首页。


一.使用场景说明

在电子商务平台中,卖家在平台上可以开自己的店铺,然后买家就可以直接进入到卖家的店铺进行购物.那么问题来了,买家通过什么样的入口进入卖家的店铺?

不加任何处理的方式就是:
1. 在平台上添加卖家店铺入口的链接
2. 直接给用户一个访问卖家店铺首页的URL

对于第一种方式,是合理的,也是必须要这样做.而第二种很明显就不合理,我想大家作为一个web开发者都知道,上面所说的那个访问卖家首页的url一定是带着很多参数,很长很不优雅,很难记忆的一个url.所以,我们是要给用户一个url,但是这个url必须得是精短的,易记的,优雅的一个URL.所以我们可以为每个店铺配置一个二级域名,用户通过这个二级域名在浏览器输入,就可以直接访问卖家店铺的首页了.


然后,接下来的第二个问题就来了,我们如何给卖家配置二级域名?为每一个卖家的店铺都在DNS服务器上配置一个二级域名显然是不现实.所以我们要通过程序来实现二级域名的访问.


二.实现原理:

  1. 给DNS配置泛域名解析,也就是在DNS服务器上配置一条: “*.一级域名” 的主机记录,假如您申请的以及域名是 legengshop.com,那在DNS服务器上配置的泛域名解析的主机记录就是 *.legendshop.com 配置泛域名解析的意义就在于让所有的 *.legendshop.com 访问都映射到同一个IP

    关于配置DNS的泛域名解析请参考 DNS泛域名解析

  2. 编写一个过滤器来拦截所有的请求,然后对拦截的请求进行解析,转换成访问卖家店铺首页的url,然后在过滤器进行转发.

三. 具体实现

  1. 数据设计

一般来说,店铺信息应该在数据库有一张店铺表来保存店铺信息的,上面举例的链接 www.legendshop.com/shop?shopId=1 中的shopId=1,其实就是把店铺id通过url参数传到后台,然后后台程序通过这个店铺ID找到数据库对应的店铺数据,再填充到页面,最后将页面响应给用户,那么用户访问的就是店铺首页.数据库的店铺表如下:

shop_id shop_name sec_domain_name shop_info
1 可口可乐 coco 你想和谁分享可口可乐。

所以我们要做的就是,在数据库的店铺表增加一个用于存放二级域名的字段,每条店铺记录对应一个二级域名.然后我们通过二级域名这个字段就可以查询到对应的店铺ID,然而根据这个店铺ID就可以拼接一个能实际访问店铺首页的url,如上面提到的例子: www.legendshop.com/shop?shopId=1 然后对这个url进行转发,这样就实现了.

至于二级域名的获取,假如用户在浏览器输入的是 coco.legendshop.com ,这个”coco”就是二级域名,我们只要在过滤器获取到用户访问的主机名,然后进行字符串的切割就可以获取到了.

过滤器的编写,代码的实现.

public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain)

throws IOException, ServletException

{ HttpServletRequest request = (HttpServletRequest) req;

HttpServletResponse response = (HttpServletResponse) resp;

//获取域名

String serverName = request.getServerName();

//获取访问路径

String uri = request.getRequestURI();

//如果后面带有路径的,则不拦截

if(uri.length()>1){ filterChain.doFilter(request, response); return; }

//获取主域名

String domainName = serverName.substring(serverName.indexOf(".")+1);

if(!domainName.equalsIgnoreCase(this.domainName)){ filterChain.doFilter(request, response); return; }

//获取二级域名

String secDomainName = serverName.substring(0, serverName.indexOf("."));

if(retainDomainName.contains(secDomainName)){ request.getRequestDispatcher("/index.jsp").forward(request, response); return; } //

根据二级域名获取店铺id

Integer shopId = shopDao.getShopIdBySecDomainName(secDomainName);

if(null == shopId){ filterChain.doFilter(request, response); return; }

//根据获取到的店铺ID拼接成能够访问店铺首页的URL,然后进行转发

request.getRequestDispatcher("/shop?shopId="+shopId).forward(request, response); }


访问店铺首页的servlet

private ShopDao shopDao = new ShopDao();


@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //设置字符编码 req.setCharacterEncoding("UTF-8"); resp.setCharacterEncoding("UTF-8"); resp.setContentType("text/html;charset=utf-8");

//获取用户请求参数,也就是店铺ID

String shopId = req.getParameter("shopId");

//根据ID查询店铺信息

Shop shop = shopDao.getShopById(Integer.parseInt(shopId)); if(null == shop){ resp.setStatus(404); return; } req.setAttribute("shop", shop);

//转发到店铺首页页面

req.getRequestDispatcher("/WEB-INF/jsp/shop.jsp").forward(req, resp); }


web.xml的配置

<servlet>

<servlet-name>shopServlet