ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

2022-09-03 第二小组 张晟源(JAVAWebMVC)

2022-09-05 20:00:58  阅读:188  来源: 互联网

标签:username 03 String gender 09 JAVAWebMVC vip password public


JAVAWeb

一,MVC架构

是一种软件架构模式,把整个软件分为三层:Model,view,controller

Model:模型---获取数据,并处理,返回给 controller

  entity:数据库实体类 User --- user表

  service:业务控制层,其余的活都交给 service

  dao:数据模型层 --- 操作数据库,执行 sql

View:视图 --- 看得见的页面,渲染数据,页面

controller:控制器 --- nservlet,接请求,给响应

 

耦合度:代码之间的关联关系

为什么分层:降低耦合度

 

调用关系:

  View 层发起请求 -- Controller -- Service -- Dao -- Service -- Controller -- View

 

可以用一个 servlet 处理多个 post 请求:利用反射

可以定一个约定,必须提交到    /admin/xx.do

当前的servlet只接受 *.do 结尾的请求

写 *.do时,前面不能写  /

配置servlet映射时,* 和 / 不能同时出现,/* 除外

 

MVC 设计模式理念:一张表,一个 entity,一个servlet

 

二,MVC设计模式小例子

工程目录如下

1.View层编写

进行一个用户注册的界面,并指定接受请求并处理该页面的Servlet,View主要由就是jsp,html页面构成。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="register">
    <form>
        <p>
            账号:<input type="text" name="username" v-model="user.username" @blur="verifyUsername" placeholder="用户名在6-12位">
            <span>{{msg}}</span>
        </p>
        <p>
            密码:<input type="password" name="password" v-model="user.password">
        </p>
        <p>
            姓名:<input type="text" name="name" v-model="user.name">
        </p>
        <p>
            性别:<input type="radio" value="男" name="gender" v-model="user.gender"> 男
            <input type="radio" value="女" name="gender" v-model="user.gender"> 女
        </p>
        <p>
            头像:<input type="file" name="profile" ref="profile">
        </p>
        <p>
            <input type="button" value="提交" @click="registerData">
        </p>
    </form>
</div>
<script src="static/js/vue.js"></script>
<script src="static/js/axios.min.js"></script>
<script>
    const register = new Vue({
        el:"#register",
        data:{
            msg:"",
            user:{
                gender:'男'
            }
        },
        methods:{
            async verifyUsername() {
                if(this.user.username.length < 6 || this.user.username.length > 12){
                    this.msg = "用户名必须在6-12位";
                    return false;
                }
                //    定义一个标记
                let flag = false;
                //    在这个函数中,验证用户名
                //    发ajax请求到后台,验证用户名
                //    ajax是异步请求,ajax会单独开辟一个线程来自己走,和我们的主JS程序不在同一个线程内
                //    我们需要让我们的ajax和我们的主JS在同一个线程内
                //    通过async 和 await修饰符就把ajax改成了同步请求
                await axios.get("admin/checkUser.do?username=" + this.user.username).then(response=>{
                    // console.log(response.data);
                    this.msg = response.data.message;
                    if(response.data.code == '0'){
                        flag = false;
                    }
                    if(response.data.code == '1'){
                        flag = true;
                    }
                });
                // 返回值是一个Promise对象。是一个特殊的对象。3个属性
                return flag;
            },
            registerData(){
                // 这个result就是上面函数返回的Promise对象
                let result = this.verifyUsername();
                // ES6语法的“解构”,把上面函数的返回值拿到
                result.then(r => {
                    // 带有文件上传的数据提交
                    if(r) {
                    //    要求,如果上传的数据中包含了二进制数据(文件),需要使用formData,来封装数据
                        let formData = new FormData();
                        formData.append("username",this.user.username);
                        formData.append("password",this.user.password);
                        formData.append("name",this.user.name);
                        formData.append("gender",this.user.gender);
                    //    头像,文件怎么拼?
                    //    this.$refs.profile.files[0],获取对应的文件的二进制形式
                    //    $refs:代表设置了ref属性的表单元素
                    //    profile:找到ref属性为profile的表单元素
                    //    files[0]:找到ref属性为profile的第一个表单元素
                        formData.append("profile",this.$refs.profile.files[0]);
                    //    发请求
                    //    axios的完整写法
                        axios({
                            method:"post",
                            url:"admin/addVip.do",
                            data:formData,
                            // 请求头
                            /*
                            * 'content-Type':'multipart/form-data'
                            * 代表我要传输的数据以多部分的格式来传输。
                            * HTML要求提交文件:multipart/form-data
                            * 提交普通的数据:application/x-www-form-urlencoded
                            * */
                            headers:{
                                'content-Type':'multipart/form-data'
                            }
                        }).then(response => {
                           let data = response.data;
                           alert(data.message);
                           if(data.code == '1'){
                               location.href = "login.html";
                           }
                        })
                    }
                });
            }
        }
    });
</script>

</body>
</html>

2.Controller层的编写

Controller接受View层请求的Servlet

package com.jsoft.mvc.controller;


import com.alibaba.fastjson.JSON;
import com.jsoft.mvc.entity.Vip;
import com.jsoft.mvc.service.VipService;
import com.jsoft.mvc.service.impl.VipServiceImpl;
import com.jsoft.mvc.util.MessageUtil;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.time.LocalDate;
import java.util.UUID;


@WebServlet("*.do")
@MultipartConfig // 用来标记当前的servlet要接收多部分的数据格式,当前的servlet可以接收文件
public class VipController extends HttpServlet {

//    Controller调用service
    private VipService vipService = new VipServiceImpl();

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        // 利用反射取到对应的方法名
        String servletPath = req.getServletPath();
        String methodName = servletPath.substring(1);
        methodName = methodName.substring(methodName.lastIndexOf("/") + 1,methodName.length() - 3);
        try {
            Method method = getClass().getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
            method.invoke(this,req,resp);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    private void addVip(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        PrintWriter out = resp.getWriter();

        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String name = req.getParameter("name");
        String gender = req.getParameter("gender");
        Vip vip = new Vip(username,password,name,gender);

        // 处理文件上传
        Part part = req.getPart("profile");

        String fileName = part.getSubmittedFileName();
        InputStream inputStream = part.getInputStream();
        // 文件名,防止出现一样的名字
        fileName = UUID.randomUUID() + fileName;

        // 根据日期创建图片所放的位置
        LocalDate localDate = LocalDate.now();
        String prePath = "/" + localDate.getYear() + "/" + localDate.getMonthValue() + "/";
        File file = new File("E:/upload" + prePath);
        if(!file.exists()){
//            创建多级目录
            file.mkdirs();
        }
        fileName = prePath + fileName;

        OutputStream outputStream = new FileOutputStream("E:/upload/" + fileName);
        byte [] b = new byte[1024];
        int len;
        while((len = inputStream.read(b))!= -1){
            outputStream.write(b,0,len);
        }

//        在数据库中同步保存文件的路径,只保存文件名
        vip.setProfile(fileName);

        int i = vipService.register(vip);
        if(i > 0) {
            out.write(JSON.toJSONString(new MessageUtil(1,"注册成功,请登录!")));
        } else {
            out.write(JSON.toJSONString(new MessageUtil(0,"注册失败,请重新填写!")));
        }

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

3.Model层的编写

Model层在具体的编写中包括dao层和bean层还有service层。

(1)bean层的编写

package com.jsoft.mvc.entity;

import java.io.Serializable;

/*
*   和表对应的实体类,entity
*   要求:
*       1.类名和表名相同
*       2.类中的属性名和表中的字段名相同
*       3.类中只能有对应的set,get方法和需要用到的构造器,如果有需要,可以写toString。
*       4.序列化。实现序列化接口
* */
public class Vip implements Serializable {


    private static final long serialVersionUID = -2352642267221918764L;
    private Integer id;
    private String username;
    private String password;
    private String name;
    private String gender;
    private String profile;
    private String salt;

    public Vip() {}

    public Vip(String username, String password,String name ,String gender ) {
        this.username = username;
        this.password = password;
        this.name = name;
        this.gender = gender;
    }

    public Vip(String username, String password) {
        this.username = username;
        this.password = password;
    }

    public String getSalt() {
        return salt;
    }

    public void setSalt(String salt) {
        this.salt = salt;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getProfile() {
        return profile;
    }

    public void setProfile(String profile) {
        this.profile = profile;
    }

    @Override
    public String toString() {
        return "Vip{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", gender='" + gender + '\'' +
                ", name='" + name + '\'' +
                ", profile='" + profile + '\'' +
                ", salt='" + salt + '\'' +
                '}';
    }
}

(2)dao层负责与数据库交互

public interface VipDao {

    int save(Vip vip) throws Exception;

    Vip findUserByUsername(String username) throws Exception;

}

return后的方式是工程目录下util工具类的连接数据库的方法

public class VipDaoImpl extends DAOImpl<Vip> implements VipDao {
    @Override
    public int save(Vip vip) throws Exception {
        String sql = "insert into vip(username,password,name,gender,salt,profile) values(?,?,?,?,?,?)";
        return update(sql,vip.getUsername(),vip.getPassword(),vip.getName(),vip.getGender(),vip.getSalt(),vip.getProfile());
    }

    @Override
    public Vip findUserByUsername(String username) throws Exception {
        String sql = "select id,username,password,name,gender,profile,salt from vip where username = ? ";
        return get(sql,username);
    }
}

4.Service层的编写

public interface VipService {

//    注册的方法
    int register(Vip vip);

    boolean checkUserIsExists(String username);

    boolean login(Vip vip);

}
public class VipServiceImpl implements VipService {

    private VipDao dao = new VipDaoImpl();

    @Override
    public int register(Vip vip) {
//        注册的业务执行的就是保存的操作
        try {
//            密码的加密处理
            // 生成盐
            String salt = MD5Util.getSalt();
            // 对密码进行加密
            // 加密过后还要重新赋值给vip
            vip.setPassword(MD5Util.stringToMD5(vip.getPassword() + salt));
            vip.setSalt(salt);
            return dao.save(vip);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public boolean checkUserIsExists(String username) {
        try {
            Vip vip = dao.findUserByUsername(username);
            /*
            *    如果根据用户名查到的vip是null,说明用户名可用,用户名在数据中是没有的
            *   如果返回值是true,则用户名可用
            * */
            return Objects.isNull(vip);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}

对密码进行加密,使用MD5 + 盐的方式,利用工具类的 MD5Util (需要导包)

public class MD5Util {

    /*
        获取加密的盐
     */
    public static String getSalt(){
        String words = "qwertyuiopasdfghjklzxcvbnm,./;'[]=/*-+!@#$^&%*()<>?";
        StringBuilder strb = new StringBuilder();
        // 随机获取8个字符,当作盐
        for (int i = 0; i < 8; i++) {
            strb.append(words.charAt((int) Math.floor(Math.random() * words.length())));
        }
        return strb.toString();
    }

    /*
        MD5加密
        MD5 + 盐 加密
     */
    public static String stringToMD5(String str){
        return DigestUtils.md2Hex(str.getBytes());
    }
}

 

标签:username,03,String,gender,09,JAVAWebMVC,vip,password,public
来源: https://www.cnblogs.com/shenmimao/p/16651924.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有