Dubbo、Zookeeper集群搭建及Rose使用心得(二)
上篇讲了一下配置,这次主要写一下这个框架开发的大概流程。这里以实现 登陆 功能为例。
一、准备工作
1.访问拦截器
用户在进行网站访问的时候,有可能访问到不存在的网页,所以,我们需要把这些链接重新定向到一些存在的网页。比如,我们的页面只有登录页面,但是用户访问了注册页面,这个时候就是不存在的,我们可以把 用户的访问 定向到 自己配置的404页面。具体配置如下(web.xml):
<error-page>
<error-code>404</error-code>
<location>/views/404.jsp</location>
</error-page>
还有一种情况就是 用户访问一些 需要满足某种条件才能访问的页面时,也要对其进行拦截,比如,后台管理中心,要求用户登录才能访问。这个时候就要在java代码中对其进行判断。有两种方式。
a)通过继承Filter类。这个要现在web.xml中配置,配置代码如下:
<filter>
<filter-name>exceptionFilter</filter-name>
<filter-class>com.lhh.myweb.web.controllers.ExceptionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>exceptionFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
java代码如下:
package com.lhh.myweb.web.controllers; import java.io.IOException; import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class ExceptionFilter implements Filter { @Override
public void init(FilterConfig filterConfig) throws ServletException { } @Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest hsr = (HttpServletRequest) request;
HttpServletResponse hsrp = (HttpServletResponse) response;
String uri = hsr.getRequestURI();
if (!uri.contains("login") && !uri.contains("js") && !uri.contains("css") && !uri.contains("images")
&& !uri.contains("views")) {
String xrequest = hsr.getHeader("x-requested-with");
if (xrequest == null) {
hsrp.sendRedirect(hsr.getContextPath() + "/login");
} else {
hsrp.setHeader("r_error_type", "noprivilege");
hsrp.setHeader("r_exception_msg", "用户没有登录");
hsrp.setHeader("r_exception_id", "1");
}
} else {
chain.doFilter(request, response);
} } @Override
public void destroy() {
// TODO Auto-generated method stub
} }
从代码中可以看到,这个是对所有的访问进行拦截。和下面要写的方法不同。
b)继承ControllerInterceptorAdapter类。这个有一个需要注意的地方就是,这段代码要放在controllers文件夹下(Rose框架约定)。代码如下:
package com.lhh.myweb.web.controllers; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import com.lhh.myweb.common.admin.UserBean; import net.paoding.rose.web.ControllerInterceptorAdapter;
import net.paoding.rose.web.Invocation; public class AccessTrackInterceptor extends ControllerInterceptorAdapter { @Override
protected Object before(Invocation inv) throws Exception {
HttpServletRequest request = inv.getRequest();
HttpServletResponse response = inv.getResponse();
HttpSession session = request.getSession();
UserBean ub = (UserBean) session.getAttribute("user");
String uri = request.getRequestURI();
if (ub == null && !uri.contains("login")) {
String xrequest = request.getHeader("x-requested-with");
if (xrequest == null) {
response.sendRedirect(request.getContextPath() + "/login");
} else {
response.setHeader("r_error_type", "noprivilege");
response.setHeader("r_exception_msg", "用户没有登录");
response.setHeader("r_exception_id", "1");
}
return false;
} else {
return true;
}
}
}
PS:b和a的区别在于,b在a执行之后才执行,a是对所有的访问链接拦截,b是对注册过的链接拦截。对一个没有注册过的链接访问,比如,http://域名/abc ,这个时候就只有a方法起作用,b方法不起作用。那么何为注册的链接,就是在controllers定义过的。比如如下代码:
package com.lhh.myweb.web.controllers; import net.paoding.rose.web.annotation.Path;
import net.paoding.rose.web.annotation.rest.Get; @Path("")
public class LoginController { @Get("login")
public String login(){
return "login";
}
}
这里的login就是注册过的链接,如果把login换成abc,那么上面的访问,会先进入a方法再进入b方法。controller的具体用法以后会写到。这里暂且不细说。
2.上述java代码中可以看到,每个文件夹都有明确的分工。下面就写一下Rose对于文件以及文件夹名称的约定。
a)控制层。在WEB层中,会对请求进行映射。比如,当用户访问login时,我们返回login的页面。这个是怎么做的呢?首先要创建一个文件夹,名称必须为controllers,如果我们对登陆进行控制,就要在这个文件夹下,新建一个java文件,必须以Controller结尾(注意大小写)。比如,LoginController.java。结构如下(代码在方法b中):
aaarticlea/png;base64,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" alt="" />
解释几个关键字:
[Get注解是rose框架提供的标识一个http访问是get还是post或者是其他,并且会将path与get中的字符串连接成一个url]
下述代码可以从浏览器访问:http://localhost/hello/world [注意path与get中的参数]。
package com.chen.controllers;
import net.paoding.rose.web.annotation.Path;
import net.paoding.rose.web.annotation.rest.Get;
@Path("/hello/")
public class HelloController {
@Get("world")
public String index() {
return "@hello world";
}
}
返回值也有约定:
返回普通字符串,如上所述,最常用的做法,返回一个页面。
以“@”开头的字符串,比如“return "@HelloWorld";”,会将“@”后面的字符串“HelloWorld”作为结果返回;
b)DAO层。在center层中,对数据库进行访问。这个也对文件命名有约定有,要以DAO结尾。示例代码如下:
package com.yeepay.tctj.center.dao.areautil; import java.util.Map; import net.paoding.rose.jade.annotation.DAO;
import net.paoding.rose.jade.annotation.SQL; @DAO
public interface AreaUtilDAO { @SQL("select area_id ,area_name from area where area_level = 2")
public Map<String,String> getAreaCityUtil(); @SQL("select area_id,area_name from area where area_level = 1")
public Map<String,String> getAreaProvince(); }
具体使用方法以后会提到。这里不多说。
二、开发流程
我们要实现的功能是登陆,也就是说用户会输入 用户名 和 密码。
1.web层代码(LoginController)
package com.lhh.myweb.web.controllers; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import net.paoding.rose.web.annotation.Path;
import net.paoding.rose.web.annotation.rest.Get;
import net.paoding.rose.web.annotation.rest.Post; @Path("")
public class LoginController { @Get("login")
public String login(){
return "login";
} @Post("login_check")
public void login_check(HttpServletRequest request,HttpServletResponse response){
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.println("username:"+username);
System.out.println("password:"+password);
}
}
这段代码的意思是,当用户访问 "login"时,会把login的页面返回过去。当访问,login_check时,会把用户名和密码打印出来。这里需要注意的是,要把"login_check"添加到拦截器中。
效果如下:
aaarticlea/png;base64,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" alt="" />
aaarticlea/png;base64,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" alt="" />
2.我们获取到网页传来的值之后开始检查数据库。首先我们在common层定义一个接口。代码如下:
package com.lhh.myweb.common.login; public interface LoginInterf { public String login_check(String username,String password);
}
3.它的实现类在center中。代码如下(LoginImpl):
package com.lhh.myweb.center.login; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import com.lhh.myweb.center.dao.LoginDAO;
import com.lhh.myweb.common.admin.UserBean;
import com.lhh.myweb.common.login.LoginInterf; @Service(value="login")
public class LoginImpl implements LoginInterf{ @Autowired
private LoginDAO dao;
@Override
public UserBean login_check(String username, String password) {
// TODO Auto-generated method stub
UserBean userBean = dao.login_check(username, password);
return userBean;
}
}
注意@Service(value="login")
LoginDAO代码如下:
package com.lhh.myweb.center.dao; import com.lhh.myweb.common.admin.UserBean; import net.paoding.rose.jade.annotation.DAO;
import net.paoding.rose.jade.annotation.SQL;
import net.paoding.rose.jade.annotation.SQLParam; @DAO
public interface LoginDAO { @SQL("select name as username,pass as password from user where name = :username and pass = :password")
public UserBean login_check(@SQLParam("username") String username,@SQLParam("password") String password);
}
需要注意的是,LoginInterf是一个服务,要在dubbo-provider.xml注册,代码如下
<dubbo:service interface="com.lhh.myweb.common.login.LoginInterf" ref="login"/>
4.在web层再写一个类用于调用这个服务,代码如下(LoginSvc):
package com.lhh.myweb.web.service; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import com.lhh.myweb.common.admin.UserBean;
import com.lhh.myweb.common.login.LoginInterf; @Service
public class LoginSvc { @Autowired
private LoginInterf li;
public UserBean login_check(String username,String password){
UserBean ub = li.login_check(username, password);
return ub;
};
}
注意@Service,引入的包是org.springframework.stereotype.Service;
要在消费者调用 LoginInterf,代码如下:
<dubbo:reference id="login" interface="com.lhh.myweb.common.login.LoginInterf" />
5.在LoginController中调用LoginSvc.代码如下:
package com.lhh.myweb.web.controllers; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired; import com.lhh.myweb.common.admin.UserBean;
import com.lhh.myweb.web.service.LoginSvc; import net.paoding.rose.web.annotation.Path;
import net.paoding.rose.web.annotation.rest.Get;
import net.paoding.rose.web.annotation.rest.Post; @Path("")
public class LoginController { @Autowired
private LoginSvc svc;
@Get("login")
public String login(){
return "login";
} @Post("login_check")
public void login_check(HttpServletRequest request,HttpServletResponse response){
String username = request.getParameter("username");
String password = request.getParameter("password"); System.out.println("username:"+username);
System.out.println("password:"+password); UserBean ub = svc.login_check(username, password); System.out.println("ubname:"+ub.getUsername());
System.out.println("ubpass:"+ub.getPassword());
}
}
结果如下
aaarticlea/png;base64,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" alt="" />
大致流程就是这样。
Dubbo、Zookeeper集群搭建及Rose使用心得(二)的更多相关文章
- Dubbo、Zookeeper集群搭建及Rose使用心得(一)
接触这个两三月了,是时候总结一下使用的方法以及心得体会了.我是一个菜鸟,下面写的如有错误,还请各位前辈指出.废话不多说,正式开始. 一.简介 Dubbo是Alibaba开源的分布式服务框架,它最大的特 ...
- java 学习笔记(三)ZooKeeper集群搭建实例,以及集成dubbo时的配置 (转)
ZooKeeper集群搭建实例,以及集成dubbo时的配置 zookeeper是什么: Zookeeper,一种分布式应用的协作服务,是Google的Chubby一个开源的实现,是Hadoop的分布式 ...
- Zookeeper集群搭建及原理
1 概述 1.1 简介 ZooKeeper 是 Apache 的一个顶级项目,为分布式应用提供高效.高可用的分布式协调服务,提供了诸如数据发布/订阅.负载均衡.命名服务.分布式协调/通知和分布式锁等分 ...
- 分布式架构中一致性解决方案——Zookeeper集群搭建
当我们的项目在不知不觉中做大了之后,各种问题就出来了,真jb头疼,比如性能,业务系统的并行计算的一致性协调问题,比如分布式架构的事务问题, 我们需要多台机器共同commit事务,经典的案例当然是银行转 ...
- kafka学习(二)-zookeeper集群搭建
zookeeper概念 ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,它包含一个简单的原语集,分布式应用程序可以基于它实现同步服务,配置维护和命名 服务等.Zookeeper是h ...
- 分布式协调服务Zookeeper集群搭建
分布式协调服务Zookeeper集群搭建 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.安装jdk环境 1>.操作环境 [root@node101.yinzhengjie ...
- Zookeeper 集群搭建--单机伪分布式集群
一. zk集群,主从节点,心跳机制(选举模式) 二.Zookeeper集群搭建注意点 1.配置数据文件 myid 1/2/3 对应 server.1/2/3 2.通过./zkCli.sh -serve ...
- Zookeeper集群搭建以及python操作zk
一.Zookeeper原理简介 ZooKeeper是一个开放源码的分布式应用程序协调服务,它包含一个简单的原语集,分布式应用程序可以基于它实现同步服务,配置维护和命名服务等. Zookeeper设计目 ...
- Kafka学习之(五)搭建kafka集群之Zookeeper集群搭建
Zookeeper是一种在分布式系统中被广泛用来作为:分布式状态管理.分布式协调管理.分布式配置管理.和分布式锁服务的集群.kafka增加和减少服务器都会在Zookeeper节点上触发相应的事件kaf ...
随机推荐
- spring-boot+swagger实现WebApi文档
1.引用依赖包 <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-s ...
- 苹果针对on sale 的APP发的问题邮件
2017年3月8日 上午8:07 发件人 Apple Dear Developer, Your app, extension, and/or linked framework appears to c ...
- Beta阶段中间产物【欢迎来怼】
一.版本控制 ①Git地址:https://git.coding.net/tianjiping/Android-tianjiping.git ②check in次数:7次. ③成员代码贡献 因为阚博文 ...
- C#和.net框架
第一章C#和.net框架 c#只是.net的一部分,.net不只包含C#.C#是一种程序语言,.net是一个框架/平台 C#和.NET框架 在.NET之前 20世纪90年代,微软平台多数程序员使用VB ...
- ARP 询问之 校级路由器的猫腻
前情 我为什么选定 172.17.174.73 这个 ip 来进行测试.戳前情 Scapy之ARP询问 前言 在一般家用路由器局域网下,进行 arp 广播,说:我是192.168.1.100,你们谁的 ...
- c++课的圆周面积
又回顾了一下一两个月没动过的类,似乎又有点手生了,不过还好还可以做. 在栋哥的推荐下下载了一个vs2015,表示从dev的白鼠形式的简单操作缓过来还有些不习惯呢,不过有些功能,例如诊断还是挺好用的 这 ...
- Leetcode题库——9.回文数
@author: ZZQ @software: PyCharm @file: HuiWenShu.py @time: 2018/9/16 16:51 要求:判断一个整数是否是回文数.回文数是指正序(从 ...
- 剑指offer:二位数组中的查找
准备找实习期间,复习一下数据相关内容,刷刷题. 题目描述: 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样 ...
- iOS App之间常用的五种通信方式及适用场景总结
iOS系统是相对封闭的系统,App各自在各自的沙盒(sandbox)中运行,每个App都只能读取iPhone上iOS系统为该应用程序程序创建的文件夹AppData下的内容,不能随意跨越自己的沙盒去访问 ...
- lr关联-保存数组并调用(转)
LOADRUNNER中的一个关联技巧 众所周知,在LoadRunner中,关联是一个很重要的动作,大多数的脚本在录制完成后并不能直接回放,需要通过一定的关联才能成功回放.关联的技巧有很多,这里 ...