零基础学习java------day27-28---------电影评分数据案例,. RPC案例

一.  电影评分数据案例

movie:电影id

rate:用户评分

timeStamp:评分时间

uid:用户id

简化数据:

 

 需求:

(1)每个用户评分最高的3部电影

(2)每个用户评分的平均值

(3)最大方(评分平均值高)的N个用户

(4)最热门的N部电影(评论次数)

(5)评价最高的N部电影

 代码(此处只写了1-3题,剩下的类似的写)

工具类

public class LoadDataUtils {
    
    /**
     * 以用户id分组
     */
    public static Map<String, List<Movie>> getUidMap(){
        Map<String, List<Movie>> uidMap = new HashMap<>();
        // 获取缓冲字符流
        try (
                BufferedReader br = new BufferedReader(new FileReader("E:/javafile/movie.txt"));
                ){
            String line = null;
            while((line = br.readLine()) != null) {
                // 获取movie对象
                Movie m = JSON.parseObject(line, Movie.class);
                String uid = m.getUid();
                List<Movie> list = uidMap.getOrDefault(uid, new ArrayList<Movie>());
                list.add(m);
                //将数据封装进uidMap
                uidMap.put(uid,list);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return uidMap;
    }
    /**
     * 以movie分组
     * @return
     */
    public static Map<String, List<Movie>> getMovieMap(){
        Map<String, List<Movie>> movieMap = new HashMap<>();
        // 获取缓冲字符流
        try (
                BufferedReader br = new BufferedReader(new FileReader("E:/javafile/movie.txt"));
                ){
            String line = null;
            while((line = br.readLine()) != null) {
                Movie m = JSON.parseObject(line, Movie.class);
                String mid = m.getMovie();
                List<Movie> list = movieMap.getOrDefault(mid, new ArrayList<Movie>());
                list.add(m);
                movieMap.put(mid,list);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return movieMap;
    }
}
View Code

实现类

public class MovieTest1 {
    public static void main(String[] args) {
//        movieTop3OfEveryone();
//        avrgOfEveryone();
        userRateTop3();
    }
    
    // 每个用户评分最高的3部电影
    public static void movieTop3OfEveryone() {
        Map<String, List<Movie>> uidMap = LoadDataUtils.getUidMap();
        System.out.println(uidMap);
        Set<Entry<String, List<Movie>>> entrySet = uidMap.entrySet();
        for (Entry<String, List<Movie>> entry : entrySet) {
            List<Movie> list = entry.getValue();
            if(list !=null && list.size() >= 3) {
                Collections.sort(list, new Comparator<Movie>() {
                    @Override
                    public int compare(Movie o1, Movie o2) {
                        return (o1.getRate()>o2.getRate())?-1:1;
                    }
                });
                for (int i=0;i<3; i++) {
                    Movie m = list.get(i);
                    System.out.println(entry.getKey()+":"+m);        
                }
            }
        }
    }
    
    // 每个用户评分的平均值
    public static void avrgOfEveryone() {
        Map<String, List<Movie>> uidMap = LoadDataUtils.getUidMap();
        Set<Entry<String, List<Movie>>> entrySet = uidMap.entrySet();
        for (Entry<String, List<Movie>> entry : entrySet) {
            List<Movie> list = entry.getValue();
            double total = 0;
            for(Movie movie : list) {
                total += movie.getRate();
            }
            double avrg = total/list.size();
            System.out.println(entry.getKey()+"电影评分的平均分为:"+avrg);
        }
    }
    
    // 最大方(评分平均值高)的N个用户
    public static void userRateTop3() {
        Map<String, List<Movie>> uidMap = LoadDataUtils.getUidMap();
        HashMap<String, Double> map = new HashMap<>();
        Set<Entry<String, List<Movie>>> entrySet = uidMap.entrySet();
        for (Entry<String, List<Movie>> entry : entrySet) {
            List<Movie> list = entry.getValue();
            double total = 0;
            for(Movie movie : list) {
                total += movie.getRate();
            }
            double avrg = total/list.size();
            map.put(entry.getKey(), avrg);
        }
        Set<Entry<String, Double>> entrySet1 = map.entrySet();
        ArrayList<Entry<String, Double>> list = new ArrayList<>(entrySet1);
        Collections.sort(list, new Comparator<Entry<String, Double>>() {
            @Override
            public int compare(Entry<String, Double> o1, Entry<String, Double> o2) {
                return o1.getValue()>o2.getValue()?-1:1;
            }
        });
        for(int i = 0;i<3;i++) {
            System.out.println(list.get(i));
        }
    }
}
View Code

 

二. RPC案例

  RPC(Remote Procedure Call)-远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。RPC采用客户机/服务器模式。请求程序就是一个客户机,而服务提供程序就是一个服务器。首先,,客户机调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息。在服务器端,进程保持睡眠状态直到调用信息到达为止。当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息,最后,客户端调用进程接收答复信息,获得进程结果

 

案例:

客户端远程请求注册,登录服务端,服务端响应客户端登录和注册是否成功(获取信息分为从数据库中获取和从本地磁盘中获取)

大致思路图:

 

 流程:客户端请求(即发送request请求对象)服务端(登录或者注册),请求中包含的信息为请求所要调用的方法,方法参数列表(形参),方法的全类名以及实参。客户端为了接受这个请求(request对象),其要在服务端创建一个一样的request去接收客户端请求中的参数(注意;全类名也要一样)。接着使用反射的方法调用该请求中的方法(此处不用new的形式来创建对象并调用方法,若业务区有多个方法,就需要new很多对象,消耗性能)。方法中包含了与数据库或是磁盘文件的交互,一般与数据库的交互是通过dao,所以业务区通过dao层与数据库或是磁盘文件交互。最终响应由dao层返回业务区,再返回给server端,最终客户端读取服务端的响应,即可拿到响应数据(登录或是注册是否成功)。

代码:

客户端:

项目构造:

 

 

MyClient代码:

public class MyServer {
    @SuppressWarnings("resource")
    public static void main(String[] args) throws Exception {
        System.out.println("开始服务");
        ServerSocket serverSocket = new ServerSocket(7788);
        while(true) {
            Socket socket = serverSocket.accept();
            InputStream inputStream = socket.getInputStream();
            ObjectInputStream ois = new ObjectInputStream(inputStream);
            System.out.println("开始读取数据");
            // 获取调用方法必须的参数
            Request request = (Request)ois.readObject();
            System.out.println("数据读取完毕");
            String className = request.getClassName();
            String methodName = request.getMethodName();
            Class<?>[] parameterTypes = request.getParameterTypes();
            Object[] paraterValues = request.getParaterValues();
            // 反射调用方法,并接收返回数据
            Class<?> clazz = Class.forName(className);
            Method method = clazz.getMethod(methodName, parameterTypes);
            Response response = (Response)method.invoke(clazz.newInstance(), (User)paraterValues[0]);
            System.out.println("接收数据完毕");
            
            // 向客户端发送响应
            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
            oos.writeObject(response);
            System.out.println(response);
            oos.close();
            ois.close();
            socket.close();
        }
    }
}
View Code

POJO(简单java对象,一般是由私有属性以及相应的设置或者获取这些属性的方法构成)部分代码:

request

public class Request implements Serializable{
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private String className;
    private String methodName;
    private Class<?>[] parameterTypes;
    private Object[] paraterValues;
    public String getClassName() {
        return className;
    }
    public void setClassName(String className) {
        this.className = className;
    }
    public String getMethodName() {
        return methodName;
    }
    public void setMethodName(String methodName) {
        this.methodName = methodName;
    }
    public Class[] getParameterTypes() {
        return parameterTypes;
    }
    public void setParameterTypes(Class[] parameterTypes) {
        this.parameterTypes = parameterTypes;
    }
    public Object[] getParaterValues() {
        return paraterValues;
    }
    public void setParaterValues(Object[] paraterValues) {
        this.paraterValues = paraterValues;
    }
    @Override
    public String toString() {
        return "Request [className=" + className + ", methodName=" + methodName + ", parameterTypes="
                + Arrays.toString(parameterTypes) + ", paraterValues=" + Arrays.toString(paraterValues) + "]";
    }
}
View Code

response:

public class Response implements Serializable{
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private String msg;
    private String statusCode;
    private User user;
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
    public String getStatusCode() {
        return statusCode;
    }
    public void setStatusCode(String statusCode) {
        this.statusCode = statusCode;
    }
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
    @Override
    public String toString() {
        return "Response [msg=" + msg + ", statusCode=" + statusCode + ", user=" + user + "]";
    }
}
View Code

User:

public class User implements Serializable{
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    String name;
    int age;
    String password;
    
    public User() {
        
    }
    
    public User(String name, int age, String password) {
        super();
        this.name = name;
        this.age = age;
        this.password = password;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User [name=" + name + ", age=" + age + ", password=" + password + "]";
    }
View Code

服务端(server):

 

 

Myserver

public class MyServer {
    @SuppressWarnings("resource")
    public static void main(String[] args) throws Exception {
        System.out.println("开始服务");
        ServerSocket serverSocket = new ServerSocket(7788);
        while(true) {
            Socket socket = serverSocket.accept();
            InputStream inputStream = socket.getInputStream();
            ObjectInputStream ois = new ObjectInputStream(inputStream);
            System.out.println("开始读取数据");
            // 获取调用方法必须的参数
            Request request = (Request)ois.readObject();
            System.out.println("数据读取完毕");
            String className = request.getClassName();
            String methodName = request.getMethodName();
            Class<?>[] parameterTypes = request.getParameterTypes();
            Object[] paraterValues = request.getParaterValues();
            // 反射调用方法,并接收返回数据
            Class<?> clazz = Class.forName(className);
            Method method = clazz.getMethod(methodName, parameterTypes);
            Response response = (Response)method.invoke(clazz.newInstance(), (User)paraterValues[0]);
            System.out.println("接收数据完毕");
            
            // 向客户端发送响应
            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
            oos.writeObject(response);
            System.out.println(response);
            oos.close();
            ois.close();
            socket.close();
        }
    }
}
View Code

业务区(service)

UserServer(接口)

public interface UserServer {
    
    /**
     *  用于用户登录
     * @param user
     * @return
     * @throws Exception
     */
     
    public Response login(User user) throws Exception;
        
    /**
      *  用于用户的注册
     * @param user
     * @return
     * @throws Exception
     */
    public Response register(User user) throws Exception;
}
View Code

UserServerImpl(实现注册和登录)

public class UserServerImpl implements UserServer{
    // 使用静态代码块加载配置文件
    static String className;
    static UserDao userDao;
    static {
        try {
            Properties p = new Properties();
            p.load(UserServerImpl.class.getClassLoader().getResourceAsStream("class.properties"));
            className = p.getProperty("className");
            userDao = (UserDao)Class.forName(className).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    // 为了提高代码的扩展性,使用配置文件并使用反射获取实例对象
    // 实现登录
    @Override
    public Response login(User user) throws Exception {
        System.out.println(user);
        User user1 = userDao.getUserFromDbByNameAndPwd(user);
        Response response = new Response();
        System.out.println(user1);
        // 登录失败
        if(user1==null) {
            response.setMsg("登录失败");
            response.setStatusCode("500");
            response.setUser(null);
        }else {
            response.setMsg("登录成功");
            response.setStatusCode("200");
            response.setUser(user1);
        }
        return response;
    }

    // 实现注册
    @Override
    public Response register(User user) throws Exception {
        Response response = new Response();
        boolean b = userDao.insertMessageOfUser(user);
        if(b){
            response.setMsg("注册成功");
            response.setStatusCode("200");
        }else{
            response.setMsg("注册失败");
            response.setStatusCode("500");
        }
        return response;
    }
    
}
View Code

dao

 UserDao(接口)

public interface UserDao {
    
    /**
      * 根据用户名和密码从数据库中查询用户
     * @param name
     * @param password
     * @return
     */
    public User getUserFromDbByNameAndPwd(User user) throws Exception;
    
    /**
     *  往数据库插入数据
     * @param user
     * @return
     */
    public boolean insertMessageOfUser(User user) throws Exception;
}
View Code

UserDaoImpl1(与磁盘文件交互)

/**
 * 操作文件
 * @author ASUS
 *
 */
public class UserDaoImpl1 implements UserDao{
    @Override
    public User getUserFromDbByNameAndPwd(User u) throws Exception {
        Map<String, User> map = TestMyUtil.getUserFromFile();
        User user = null;
        if(map != null) {
            user = map.get(u.getName());
            if(user !=null) {
                String pwd = user.getPassword();
                if(u.getPassword().equals(pwd)) {
                    return user;
                }
            }
        }
        return user;
    }

    @SuppressWarnings("unchecked")
    @Override
    public boolean insertMessageOfUser(User user) throws Exception {
        Map<String, User> map =null ;
        File f = new File(Const.PATH);
        boolean result = false; 
        if(!f.exists()) { //文件不存在,直接存map
            map = new HashMap<>();
            map.put(user.getName(), user);
            FileUtil.addObjectToFile(map, Const.PATH);
            result = true;

            // 文件已经存在,则先取出文件中的map对象,再存入相应的数据
        }else { 
            // 取出map
            map = (Map<String, User>) FileUtil.getObjectFromFile(Const.PATH);
            boolean b = map.containsKey(user.getName());
            if(!b) {
                // 将数据存入已存在的map中,并将之写入文件
                map.put(user.getName(), user);
                FileUtil.addObjectToFile(map, Const.PATH);
                result = true;
            }
        }
        return result;
    }
}
View Code

UserDaoImpl2

/**
  *  操作数据库
 * @author ASUS
 *
 */
public class UserDaoImpl2 implements UserDao{
    static ComboPooledDataSource dataSource;
    static QueryRunner runner;
    static {
        // 获取连接池对象,其中包含连接数据库所需要的参数
        dataSource = new ComboPooledDataSource();
        // 连接数据库
        runner = new QueryRunner(dataSource);
    }
    // 查询数据
    @Override
    public User getUserFromDbByNameAndPwd(User u) throws Exception {
        
        String sql = "select * from user where name=?and password=?";
        User user = runner.query(sql, new BeanHandler<>(User.class),u.getName(),u.getPassword());
        return user;
    }
    
    // 插入数据
    @Override
    public boolean insertMessageOfUser(User u) throws Exception {
        String sql = "insert into user values(?,?,?)";
        int i = runner.update(sql,u.getName(),u.getAge(),u.getPassword());
        if(i>0) {
            return true;
        }
        return false;
    }
    
}
View Code

工具类(utils)

Const(保证操作的路径一致)

/**
 * 指定路径
 * @author ASUS
 *
 */
public class Const {
    public static final String PATH = "E:/javafile/object.txt";
    
}
View Code

FileUtil

/**
 * 1 读取指定文件   获取对象
 * 2 向指定文件中存储对象
 * @author ASUS
 *
 */
public class FileUtil {
    
    /**
     * 读取指定文件   获取对象
     * @param path
     * @return
     * @throws Exception
     */
    public static Object getObjectFromFile(String path) throws Exception {
        File f = new File(path);
        Object obj = null ;
        if(f.exists()){
             ObjectInputStream ois = new ObjectInputStream(new FileInputStream(f));
             obj = ois.readObject();
             ois.close();
        }
        return obj;
    }
    
    /**
     * 向指定文件中存储对象
     * @param obj
     * @param path
     * @throws Exception
     */
    public static void addObjectToFile(Object obj , String path) throws Exception{
        File f = new File(path);
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(f));
        oos.writeObject(obj);
        oos.close();
    }
}
View Code

 

posted @ 2019-09-14 14:44  一y样  阅读(342)  评论(0编辑  收藏  举报