[JavaWeb学习日记]JSP+Cookie+Filter与登录+CRUD案例

目录

 一.JSP

二.EL表达式与JSTL标签

三.Cookie

四.Session

五.Filter 

六. 登录+CRUD:品牌增删改查案例

Demo一览

1.导包

2.构建包结构

3.创建数据库表tb_brand与user

4.创建实体类

5.mybatis的配置文件和logback配置文件

6.写接口

7.工具类:生成图片与SqlSession创建 

8.写service方法

 9.css

10. Filter过滤器限制必须登录

 11.index.jsp,login.jsp与register.jsp

 12.登录注册的Servlet

 13.增删改查有关的jsp与Servlet


如今JSP已不再是热门的前端工具,不建议深入学习,而Cookie与Filter可以了解了解

通过maven建立web工程,工程目录如下,学习的内容为java代码以及两个jsp文件

pom需要导入的依赖:

    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
    </dependency>
    <!--使用jsp需要导入的包-->
    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>jsp-api</artifactId>
      <version>2.2</version>
    </dependency>
    <!--使用jstl标签需要导入的两个包-->
    <dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>
    <dependency>
      <groupId>taglibs</groupId>
      <artifactId>standard</artifactId>
      <version>1.1.2</version>
    </dependency>


 一.JSP

1.JSP(JavaServerPages):既可以写html,又能写java代码
    会把jsp文件转换为java文件并编译执行,本质为Servlet服务资源
2.使用在jsp中引用别的类:需要导包
3.在jsp文件中写java代码:<%xxx%>
4.插入数据到前端代码上:<%=xxx%>

index.jsp: 

<%@ page import="org.example.pojo.Brand" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<%
    List<Brand> brands = new ArrayList<>();
    System.out.println("HelloJSP!");
    String str="JSP!";
%>
<%="你好,"+str%><br>
</body>
</html>

IDE控制台与浏览器都会有输出


二.EL表达式与JSTL标签

案例:获取servlet传过来的集合对象中的数据
EL表达式:主要功能为获取在请求转发/cookie/session中存储的键为XXX的数据
JSTL:用标签替换JSP上面的java代码,如判断与循环
1.使用EL表达式开启需要
    声明:<%@page isELIgnored="false" %>
    jsp文件中使用el表达式获取数据:${xxx}
2.使用jstl标签需要
    1.pom文件导包
    2.引入taglib标签:<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    3.常见的jstl标签:c:if与c:forEach
3.c:if标签
    指定判断条件:test属性
4.c:foreach标签指定
    1.遍历的数据:items属性
    2.遍历数据中单个元素的名字:var属性(var.xxx会调用该对象的类中对应的getXxx方法)
    3.遍历过程中的序号名:varStatus属性
        varStatus的属性:index从0开始计数|count从1开始计数
    4.指定遍历时设置var的开始,结束,步长:begin,end,step

jstl.jsp:

<%@page isELIgnored="false" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title></head>
<body>
<c:if test="true"><h3>true</h3></c:if>
<c:if test="${status==1}"><h3>${status}</h3></c:if>
<table border="1" cellspacing="0" width="800">
    <c:forEach items="${brands}" var="brand" varStatus="status">
        <tr align="center">
            <td>${status.count}</td>
            <td>${brand.brandName}></td>
            <td>${brand.companyName}></td>
            <td>${brand.ordered}</td>
            <td>${brand.description}</td>
            <td>
                <c:if test="${brand.status==1}"><%="启用"%></c:if>
                <c:if test="${brand.status==0}"><%="禁用"%></c:if>
            </td>
            <td>
                <a href="">修改 </a>
                <a href="">删除</a>
            </td>
        </tr>
    </c:forEach>
</table>
<hr>
<c:forEach begin="1" end="10" step="1" var="i">
    <a href="">${i}</a>
</c:forEach>
</body>
</html>
public class Brand {
    private Integer id;
    private String brandName;
    private String companyName;
    private Integer ordered;
    private String description;
    private Integer status;
    public Brand() {
    }
    public Brand(Integer id, String brandName, String companyName, String description) {
        this.id = id;
        this.brandName = brandName;
        this.companyName = companyName;
        this.description = description;
    }
    public Brand(Integer id, String brandName, String companyName, Integer ordered, String description, Integer status) {
        this.id = id;
        this.brandName = brandName;
        this.companyName = companyName;
        this.ordered = ordered;
        this.description = description;
        this.status = status;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getBrandName() {
        return brandName;
    }
    public void setBrandName(String brandName) {
        this.brandName = brandName;
    }
    public String getCompanyName() {
        return companyName;
    }
    public void setCompanyName(String companyName) {
        this.companyName = companyName;
    }
    public Integer getOrdered() {
        return ordered;
    }
    public void setOrdered(Integer ordered) {
        this.ordered = ordered;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    public Integer getStatus() {
        return status;
    }
    public void setStatus(Integer status) {
        this.status = status;
    }

    @Override
    public String toString() {
        return "Brand{" +
                "id=" + id +
                ", brandName='" + brandName + '\'' +
                ", companyName='" + companyName + '\'' +
                ", ordered=" + ordered +
                ", description='" + description + '\'' +
                ", status=" + status +
                '}';
    }
}

 Servlet: 把数据存储到request域中,再转发到jsp资源中。


@WebServlet("/jsp")
public class JSPDemo extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        List<Brand> brands = new ArrayList<>();
        brands.add(new Brand(1,"三只松鼠","三只松鼠",100,"三只松鼠,好吃不上火",1));
        brands.add(new Brand(2,"优衣库","优衣库",200,"优衣库,服适人生",0));
        brands.add(new Brand(3,"小米","小米科技有限公司",1000,"为发烧而生",1));
        request.setAttribute("status",1);
        request.setAttribute("brands",brands);
        request.getRequestDispatcher("/jstl.jsp").forward(request,response);
    }
}


三.Cookie

会话跟踪:HTTP协议每次向浏览器请求数据时,会将该请求视为新请求
服务器需要识别多次请求是否来自同一浏览器以便在多次请求间共享数据
1.查看cookies:谷歌控制台application
2.Cookies的实现基于HTTP协议(响应头,请求头),Session基于cookie实现(发送sessionId)
3.发送cookie:以键值对的形式创建cookie,使用响应对象添加cookie
4.设置cookie对象的在浏览器中的存活时间:单位为秒,cookie默认为浏览器关闭cookie消失
5.接收cookie:通过请求对象接收所有cookie数组并遍历
@WebServlet("/cookie")
public class CookieDemo extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Cookie cookie = new Cookie("username", "zhangsan");
        cookie.setMaxAge(60);
        response.addCookie(cookie);

        Cookie[] cookies = request.getCookies();
        for (Cookie c : cookies) {System.out.println(c.getName() + ":" + c.getValue());}
    }
}

访问目标路径两次得到如下结果: 


四.Session

1.存Session:通过请求对象存储数据到Session中
2.获取session对象中对应键的值,后移除键值对
3.在web.xml中设置session存活时间
@WebServlet("/session")
public class SessionDemo extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response){
        HttpSession session=request.getSession();
        session.setAttribute("username","zhangsan");
        System.out.println(session.getAttribute("username"));
        session.removeAttribute("username");
    }
}

web.xml:

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <session-config>
    <!--单位分钟-->
    <session-timeout>1</session-timeout>
  </session-config>
</web-app>


五.Filter 

用于拦截访问的资源

//拦截资源目录,和@WebServlet一样的写法
@WebFilter("/session")
public class FilterDemo implements Filter {
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("拦截资源后放行......");
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("放行后输出......");
    }
    public void init(FilterConfig filterConfig) {}
    public void destroy() {}
}


六. 登录+CRUD:品牌增删改查案例

Demo一览

1.导包
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.32</version>
    </dependency>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.5</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>jsp-api</artifactId>
      <version>2.2</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>
    <dependency>
      <groupId>taglibs</groupId>
      <artifactId>standard</artifactId>
      <version>1.1.2</version>
    </dependency>

2.构建包结构

3.创建数据库表tb_brand与user
4.创建实体类
public class Brand {
    private Integer id;
    private String brandName;
    private String companyName;
    private Integer ordered;
    private String description;
    private Integer status;
    public Brand() {
    }
    public Brand(Integer id, String brandName, String companyName, Integer ordered, String description, Integer status) {
        this.id = id;
        this.brandName = brandName;
        this.companyName = companyName;
        this.ordered = ordered;
        this.description = description;
        this.status = status;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getBrandName() {
        return brandName;
    }
    public void setBrandName(String brandName) {
        this.brandName = brandName;
    }
    public String getCompanyName() {
        return companyName;
    }
    public void setCompanyName(String companyName) {
        this.companyName = companyName;
    }
    public Integer getOrdered() {
        return ordered;
    }
    public void setOrdered(Integer ordered) {
        this.ordered = ordered;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    public Integer getStatus() {
        return status;
    }
    public void setStatus(Integer status) {
        this.status = status;
    }
    @Override
    public String toString() {
        return "Brand{" +
                "id=" + id +
                ", brandName='" + brandName + '\'' +
                ", companyName='" + companyName + '\'' +
                ", ordered=" + ordered +
                ", description='" + description + '\'' +
                ", status=" + status +
                '}';
    }
}
public class User {
    private Integer id;
    private String username;
    private String password;

    public User() {
    }

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

    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;
    }
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

5.mybatis的配置文件和logback配置文件

mybatis.config

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <typeAliases>
        <package name="org.example.pojo"/>
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql:///db1?useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <package name="org.example.mapper"/>
    </mappers>
</configuration>

logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>[%level] %boldGreen(%logger{15}) - %msg %n</pattern>
        </encoder>
    </appender>
    <root level="DEBUG">
        <appender-ref ref="Console"/>
    </root>
</configuration>

BrandMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.example.mapper.BrandMapper">
    <resultMap id="brandResultMap" type="Brand">
        <id column="id" property="id"/>
        <result column="brand_name" property="brandName"/>
        <result column="company_name" property="companyName"/>
    </resultMap>
</mapper>

UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.example.mapper.UserMapper">
</mapper>

6.写接口
public interface BrandMapper {
    @ResultMap("brandResultMap")
    @Select("select * from tb_brand")
    List<Brand> selectAll();
    @Insert("insert into tb_brand values (null,#{brandName},#{companyName},#{ordered},#{description},#{status})")
    void add(Brand brand);
    @ResultMap("brandResultMap")
    @Select("select * from tb_brand where id=#{id}")
    Brand selectById(int id);

    @Update("update tb_brand set brand_name=#{brandName}," +
            "company_name=#{companyName}," +
            "ordered=#{ordered}," +
            "description=#{description}," +
            "status=#{status} " +
            "where id=#{id}")
    void update(Brand brand);
    @Delete("delete from tb_brand where id=#{id}")
    void deleteById(int id);
}
public interface UserMapper {
    @Select("select * from user where username = #{username} and password = #{password}")
    User select(@Param("username") String username, @Param("password") String password);
    @Select("select * from user where username = #{username}")
    User selectByUsername(String username);
    @Insert("insert into user values(null,#{username},#{password})")
    void add(User user);
}

7.工具类:生成图片与SqlSession创建 
public class  CheckCodeUtil {//生成验证码工具类
    public static final String VERIFY_CODES = "123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private static Random random = new Random();
    public static void main(String[] args) throws Exception{
        OutputStream fos=new FileOutputStream("D:\\IDEACode\\demo2\\Web\\web-demo4-brandDemo\\src\\main\\webapp\\imgs\\a.jpg");
        String checkCode=CheckCodeUtil.outputVerifyImage(100,50,fos,4);
        System.out.println(checkCode);
    }
    //输出随机验证码图片流,并返回验证码值(一般传入输出流,响应response页面端,Web项目用的较多)
    //图片宽高,输出流与数据长度
    //返回验证码数据
    public static String outputVerifyImage(int w, int h, OutputStream os, int verifySize) throws IOException {
        String verifyCode = generateVerifyCode(verifySize);
        outputImage(w, h, os, verifyCode);
        return verifyCode;
    }
    //使用系统默认字符源生成验证码
    public static String generateVerifyCode(int verifySize) {
        return generateVerifyCode(verifySize, VERIFY_CODES);
    }
    //使用指定源生成验证码
    public static String generateVerifyCode(int verifySize, String sources) {
        // 未设定展示源的字码,赋默认值大写字母+数字
        if (sources == null || sources.length() == 0) {
            sources = VERIFY_CODES;
        }
        int codesLen = sources.length();
        Random rand = new Random(System.currentTimeMillis());
        StringBuilder verifyCode = new StringBuilder(verifySize);
        for (int i = 0; i < verifySize; i++) {
            verifyCode.append(sources.charAt(rand.nextInt(codesLen - 1)));
        }
        return verifyCode.toString();
    }
    //生成随机验证码文件,并返回验证码值 (生成图片形式,用的较少)
    public static String outputVerifyImage(int w, int h, File outputFile, int verifySize) throws IOException {
        String verifyCode = generateVerifyCode(verifySize);
        outputImage(w, h, outputFile, verifyCode);
        return verifyCode;
    }
    //生成指定验证码图像文件
    public static void outputImage(int w, int h, File outputFile, String code) throws IOException {
        if (outputFile == null) {
            return;
        }
        File dir = outputFile.getParentFile();
        //文件不存在
        if (!dir.exists()) {
            //创建
            dir.mkdirs();
        }
        try {
            outputFile.createNewFile();
            FileOutputStream fos = new FileOutputStream(outputFile);
            outputImage(w, h, fos, code);
            fos.close();
        } catch (IOException e) {
            throw e;
        }
    }
    //输出指定验证码图片流
    public static void outputImage(int w, int h, OutputStream os, String code) throws IOException {
        int verifySize = code.length();
        BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        Random rand = new Random();
        Graphics2D g2 = image.createGraphics();
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        // 创建颜色集合,使用java.awt包下的类
        Color[] colors = new Color[5];
        Color[] colorSpaces = new Color[]{Color.WHITE, Color.CYAN,
                Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, Color.ORANGE,
                Color.PINK, Color.YELLOW};
        float[] fractions = new float[colors.length];
        for (int i = 0; i < colors.length; i++) {
            colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)];
            fractions[i] = rand.nextFloat();
        }
        Arrays.sort(fractions);
        // 设置边框色
        g2.setColor(Color.GRAY);
        g2.fillRect(0, 0, w, h);
        Color c = getRandColor(200, 250);
        // 设置背景色
        g2.setColor(c);
        g2.fillRect(0, 2, w, h - 4);
        // 绘制干扰线
        Random random = new Random();
        // 设置线条的颜色
        g2.setColor(getRandColor(160, 200));
        for (int i = 0; i < 20; i++) {
            int x = random.nextInt(w - 1);
            int y = random.nextInt(h - 1);
            int xl = random.nextInt(6) + 1;
            int yl = random.nextInt(12) + 1;
            g2.drawLine(x, y, x + xl + 40, y + yl + 20);
        }
        // 添加噪点
        // 噪声率
        float yawpRate = 0.05f;
        int area = (int) (yawpRate * w * h);
        for (int i = 0; i < area; i++) {
            int x = random.nextInt(w);
            int y = random.nextInt(h);
            // 获取随机颜色
            int rgb = getRandomIntColor();
            image.setRGB(x, y, rgb);
        }
        // 添加图片扭曲
        shear(g2, w, h, c);
        g2.setColor(getRandColor(100, 160));
        int fontSize = h - 4;
        Font font = new Font("Algerian", Font.ITALIC, fontSize);
        g2.setFont(font);
        char[] chars = code.toCharArray();
        for (int i = 0; i < verifySize; i++) {
            AffineTransform affine = new AffineTransform();
            affine.setToRotation(Math.PI / 4 * rand.nextDouble() * (rand.nextBoolean() ? 1 : -1), (w / verifySize) * i + fontSize / 2, h / 2);
            g2.setTransform(affine);
            g2.drawChars(chars, i, 1, ((w - 10) / verifySize) * i + 5, h / 2 + fontSize / 2 - 10);
        }
        g2.dispose();
        ImageIO.write(image, "jpg", os);
    }
    private static Color getRandColor(int fc, int bc) {//随机颜色
        if (fc > 255) {
            fc = 255;
        }
        if (bc > 255) {
            bc = 255;
        }
        int r = fc + random.nextInt(bc - fc);
        int g = fc + random.nextInt(bc - fc);
        int b = fc + random.nextInt(bc - fc);
        return new Color(r, g, b);
    }
    private static int getRandomIntColor() {
        int[] rgb = getRandomRgb();
        int color = 0;
        for (int c : rgb) {
            color = color << 8;
            color = color | c;
        }
        return color;
    }
    private static int[] getRandomRgb() {
        int[] rgb = new int[3];
        for (int i = 0; i < 3; i++) {
            rgb[i] = random.nextInt(255);
        }
        return rgb;
    }
    private static void shear(Graphics g, int w1, int h1, Color color) {
        shearX(g, w1, h1, color);
        shearY(g, w1, h1, color);
    }

    private static void shearX(Graphics g, int w1, int h1, Color color) {
        int period = random.nextInt(2);
        boolean borderGap = true;
        int frames = 1;
        int phase = random.nextInt(2);
        for (int i = 0; i < h1; i++) {
            double d = (double) (period >> 1)
                    * Math.sin((double) i / (double) period
                    + (6.2831853071795862D * (double) phase)
                    / (double) frames);
            g.copyArea(0, i, w1, 1, (int) d, 0);
            if (borderGap) {
                g.setColor(color);
                g.drawLine((int) d, i, 0, i);
                g.drawLine((int) d + w1, i, w1, i);
            }
        }
    }
    private static void shearY(Graphics g, int w1, int h1, Color color) {
        int period = random.nextInt(40) + 10; // 50;
        boolean borderGap = true;
        int frames = 20;
        int phase = 7;
        for (int i = 0; i < w1; i++) {
            double d = (double) (period >> 1)
                    * Math.sin((double) i / (double) period
                    + (6.2831853071795862D * (double) phase)
                    / (double) frames);
            g.copyArea(i, 0, 1, h1, 0, (int) d);
            if (borderGap) {
                g.setColor(color);
                g.drawLine(i, (int) d, i, 0);
                g.drawLine(i, (int) d + h1, i, h1);
            }
        }
    }
}
public class SqlSessionFactoryUtil {
    static SqlSessionFactory sqlSessionFactory;
    static { try {sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));}catch (Exception e){e.printStackTrace();}}
    public static SqlSessionFactory getssf(){
        return sqlSessionFactory;
    }
}

8.写service方法
public class BrandService {
    SqlSessionFactory sqlSessionFactory= SqlSessionFactoryUtil.getssf();
    public List<Brand> selectAll(){
        SqlSession sqlSession=sqlSessionFactory.openSession(true);
        BrandMapper mapper =sqlSession.getMapper(BrandMapper.class);
        List<Brand> brands=mapper.selectAll();
        sqlSession.close();
        return brands;
    }
    public void add(Brand brand){
        SqlSession sqlSession=sqlSessionFactory.openSession(true);
        BrandMapper mapper =sqlSession.getMapper(BrandMapper.class);
        mapper.add(brand);
        sqlSession.close();
    }
    public Brand selectById(int id){//更新数据时回显数据
        SqlSession sqlSession=sqlSessionFactory.openSession(true);
        BrandMapper mapper =sqlSession.getMapper(BrandMapper.class);
        Brand brand=mapper.selectById(id);
        sqlSession.close();
        return brand;
    }
    public void update(Brand brand){
        SqlSession sqlSession=sqlSessionFactory.openSession(true);
        BrandMapper mapper =sqlSession.getMapper(BrandMapper.class);
        mapper.update(brand);
        sqlSession.close();
    }
    public void deleteById(int id){
        SqlSession sqlSession=sqlSessionFactory.openSession(true);
        BrandMapper mapper =sqlSession.getMapper(BrandMapper.class);
        mapper.deleteById(id);
        sqlSession.close();
    }
}
public class UserService {
    SqlSessionFactory sqlSessionFactory= SqlSessionFactoryUtil.getssf();
    public User login(String username, String password){//登录需要设置cookie给浏览器,需要返回用户对象
        SqlSession sqlSession=sqlSessionFactory.openSession(true);
        UserMapper mapper=sqlSession.getMapper(UserMapper.class);
        User user=mapper.select(username,password);
        sqlSession.close();
        return user;
    }
    public boolean register(User user){
        SqlSession sqlSession=sqlSessionFactory.openSession(true);
        UserMapper mapper=sqlSession.getMapper(UserMapper.class);
        User u=mapper.selectByUsername(user.getUsername());
        if(u==null){mapper.add(user);}
        sqlSession.close();
        return u==null;
    }
}

 9.css

login.css

* {
    margin: 0;
    padding: 0;
}

html {
    height: 100%;
    width: 100%;
    overflow: hidden;
    margin: 0;
    padding: 0;
    background: url(../imgs/Desert1.jpg) no-repeat 0px 0px;
    background-repeat: no-repeat;
    background-size: 100% 100%;
    -moz-background-size: 100% 100%;
}

body {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
}

#loginDiv {
    width: 37%;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 380px;
    background-color: rgba(75, 81, 95, 0.3);
    box-shadow: 7px 7px 17px rgba(52, 56, 66, 0.5);
    border-radius: 5px;
}

#name_trip {
    margin-left: 50px;
    color: red;
}

p {
    margin-top: 30px;
    margin-left: 20px;
    color: azure;
}


#remember{
    margin-left: 15px;
    border-radius: 5px;
    border-style: hidden;
    background-color: rgba(216, 191, 216, 0.5);
    outline: none;
    padding-left: 10px;
    height: 20px;
    width: 20px;
}
#username{
    width: 200px;
    margin-left: 15px;
    border-radius: 5px;
    border-style: hidden;
    height: 30px;
    background-color: rgba(216, 191, 216, 0.5);
    outline: none;
    color: #f0edf3;
    padding-left: 10px;
}
#password{
    width: 202px;
    margin-left: 15px;
    border-radius: 5px;
    border-style: hidden;
    height: 30px;
    background-color: rgba(216, 191, 216, 0.5);
    outline: none;
    color: #f0edf3;
    padding-left: 10px;
}
.button {
    border-color: cornsilk;
    background-color: rgba(100, 149, 237, .7);
    color: aliceblue;
    border-style: hidden;
    border-radius: 5px;
    width: 100px;
    height: 31px;
    font-size: 16px;
}

#subDiv {
    text-align: center;
    margin-top: 30px;
}
#loginMsg{
    text-align: center;
    color: aliceblue;
}
#errorMsg{
    text-align: center;
    color:red;
}

register.css

* {
    margin: 0;
    padding: 0;
    list-style-type: none;
}
.reg-content{
    padding: 30px;
    margin: 3px;
}
a, img {
    border: 0;
}

body {
    background-image: url("../imgs/reg_bg_min.jpg") ;
    text-align: center;
}

table {
    border-collapse: collapse;
    border-spacing: 0;
}

td, th {
    padding: 0;
    height: 90px;

}
.inputs{
    vertical-align: top;
}

.clear {
    clear: both;
}

.clear:before, .clear:after {
    content: "";
    display: table;
}

.clear:after {
    clear: both;
}

.form-div {
    background-color: rgba(255, 255, 255, 0.27);
    border-radius: 10px;
    border: 1px solid #aaa;
    width: 424px;
    margin-top: 150px;
    margin-left:1050px;
    padding: 30px 0 20px 0px;
    font-size: 16px;
    box-shadow: inset 0px 0px 10px rgba(255, 255, 255, 0.5), 0px 0px 15px rgba(75, 75, 75, 0.3);
    text-align: left;
}

.form-div input[type="text"], .form-div input[type="password"], .form-div input[type="email"] {
    width: 268px;
    margin: 10px;
    line-height: 20px;
    font-size: 16px;
}

.form-div input[type="checkbox"] {
    margin: 20px 0 20px 10px;
}

.form-div input[type="button"], .form-div input[type="submit"] {
    margin: 10px 20px 0 0;
}

.form-div table {
    margin: 0 auto;
    text-align: right;
    color: rgba(64, 64, 64, 1.00);
}

.form-div table img {
    vertical-align: middle;
    margin: 0 0 5px 0;
}

.footer {
    color: rgba(64, 64, 64, 1.00);
    font-size: 12px;
    margin-top: 30px;
}

.form-div .buttons {
    float: right;
}

input[type="text"], input[type="password"], input[type="email"] {
    border-radius: 8px;
    box-shadow: inset 0 2px 5px #eee;
    padding: 10px;
    border: 1px solid #D4D4D4;
    color: #333333;
    margin-top: 5px;
}

input[type="text"]:focus, input[type="password"]:focus, input[type="email"]:focus {
    border: 1px solid #50afeb;
    outline: none;
}

input[type="button"], input[type="submit"] {
    padding: 7px 15px;
    background-color: #3c6db0;
    text-align: center;
    border-radius: 5px;
    overflow: hidden;
    min-width: 80px;
    border: none;
    color: #FFF;
    box-shadow: 1px 1px 1px rgba(75, 75, 75, 0.3);
}

input[type="button"]:hover, input[type="submit"]:hover {
    background-color: #5a88c8;
}

input[type="button"]:active, input[type="submit"]:active {
    background-color: #5a88c8;
}
.err_msg{
    color: red;
    padding-right: 170px;
}
#password_err,#tel_err{
    padding-right: 195px;
}

#reg_btn{
    margin-right:50px; width: 285px; height: 45px; margin-top:20px;
}

#checkCode{
    width: 100px;
}

#changeImg{
    color: aqua;
}

10. Filter过滤器限制必须登录
设置放行资源:通过获取的路径来判断是否包含目标字符串
检测用户是否登录:判断session里面是否有user
@WebFilter("/*")
public class LoginFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
        HttpServletRequest req = (HttpServletRequest) request;
        String[] urls = {"/css/", "/img/", "/login.jsp", "/register.jsp", "/loginServlet", "registerServlet", "/checkCodeServlet"};
        String uri=req.getRequestURI();
        for (String u : urls) {
            if (uri.contains(u)||"/web_demo4_brandDemo_war/".equals(uri)) {
                System.out.println("[DEBUG]请求服务器资源..."+uri);
                chain.doFilter(request, response);
                return;
            }
        }
        if (req.getSession().getAttribute("user") == null) {
            System.out.println("[DEBUG]用户未登录访问数据资源,携带提示信息返回登录界面...");
            req.setAttribute("login_msg", "您尚未登陆");
            req.getRequestDispatcher("/login.jsp").forward(request, response);
            return;
        }
        System.out.println("[DEBUG]用户合法访问服务器资源..."+uri);
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {}
}

 11.index.jsp,login.jsp与register.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
</body>
<script>
    location.href="/web_demo4_brandDemo_war/login.jsp"
</script>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@page isELIgnored="false" %>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>login</title>
    <link href="css/login.css" rel="stylesheet">
</head>

<body>
    <div id="loginDiv" style="height: 350px">
        <form action="/web_demo4_brandDemo_war/loginServlet" id="form" method="post">
            <h1 id="loginMsg">LOGIN IN</h1>
            <%--el表达式获取请求转发中的提示信息--%>
            <div id="errorMsg">${login_msg}${register_msg}</div>
            <%--el表达式也可以获取cookie--%>
            <p>Username:<input id="username" name="username" type="text" value="${cookie.username.value}"></p>
            <p>Password:<input id="password" name="password" type="password" value="${cookie.password.value}"></p>
            <p>Remember:<input id="remember" name="remember" value="on" type="checkbox"></p>
            <div id="subDiv">
                <input type="submit" class="button" value="login up">
                <input type="reset" class="button" value="reset">
                <a href="register.jsp">没有账号?</a>
            </div>
        </form>
    </div>
</body>

</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@page isELIgnored="false" %>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>欢迎注册</title>
    <link href="css/register.css" rel="stylesheet">
</head>

<body>
    <div class="form-div">
        <div class="reg-content">
            <h1>欢迎注册</h1>
            <span>已有帐号?</span> <a href="login.jsp">登录</a>
        </div>
        <form id="reg-form" action="/web_demo4_brandDemo_war/registerServlet" method="post">
            <table>
                <tr>
                    <td>用户名</td>
                    <td class="inputs">
                        <input name="username" type="text" id="username"><br>
                        <span id="username_exi" class="err_msg" style="display: none">用户已存在</span><br>
                        <span id="username_err" class="err_msg">${register_msg}</span>
                    </td>
                </tr>
                <tr>
                    <td>密码</td>
                    <td class="inputs">
                        <input name="password" type="password" id="password"><br>
                        <span id="password_err" class="err_msg" style="display: none">密码格式有误</span>
                    </td>
                </tr>
                <tr>
                    <td>验证码</td>
                    <td class="inputs">
                        <input name="checkCode" type="text" id="checkCode">
                        <%--访问图片生成服务请求图片资源--%>
                        <img id="checkImg" src="/web_demo4_brandDemo_war/checkCodeServlet">
                        <a href="" id="changeImg">看不清?</a>
                    </td>
                </tr>
            </table>
            <div class="buttons">
                <input value="注 册" type="submit" id="reg_btn">
            </div>
            <br class="clear">
        </form>
    </div>
</body>
<script>
    //在这里如果不加后面的问号与数据,点击图片不会改变
    changeImg= function () {document.getElementById("checkImg").src = "/web_demo4_brandDemo_war/checkCodeServlet?" + new Date().getMilliseconds();}
    document.getElementById("changeImg").onclick = changeImg
    document.getElementById("checkImg").onclick = changeImg
</script>

</html>


 12.登录注册的Servlet

生成图片:通过响应数据的输出流生成图片,并且把验证码设置为Session的键值对

@WebServlet("/checkCodeServlet")
public class CheckCodeServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String checkCode= CheckCodeUtil.outputVerifyImage(100,50,response.getOutputStream(),4);
        System.out.println("[DEBUG]验证码为:"+checkCode);
        System.out.println("[DEBUG]返回生成的图片...");
        request.getSession().setAttribute("checkCodeGen",checkCode);
    }
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}
@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        String username=request.getParameter("username");
        String password=request.getParameter("password");
        User user=new UserService().login(username,password);
        if (user==null){
            System.out.println("[DEBUG]登录失败,携带提示消息登陆界面...");
            request.setAttribute("login_msg","用户名密码错误");
            request.getRequestDispatcher("/login.jsp").forward(request,response);
            return;
        }
        System.out.println("[DEBUG]登录成功,添加session,跳转到查询界面...");
        if("on".equals(request.getParameter("remember"))) {
            System.out.println("[DEBUG]用户点击了记住我,添加cookie...");
            Cookie[] cookies = {new Cookie("username",username),new Cookie("password",username)};
            for (Cookie cookie : cookies) {
                cookie.setMaxAge(60);
                response.addCookie(cookie);
            }
        }
        request.getSession().setAttribute("user",user);
        response.sendRedirect(request.getContextPath()+"/selectAllServlet");
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}
@WebServlet("/registerServlet")
public class RegisterServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        if(!((String)request.getSession().getAttribute("checkCodeGen")).equalsIgnoreCase(request.getParameter("checkCode"))){
            System.out.println("[DEBUG]验证码错误,携带提示信息返回注册界面...");
            request.setAttribute("register_msg","验证码错误");
            request.getRequestDispatcher("/register.jsp").forward(request,response);
            return;
        }
        boolean flag=new UserService().register(new User(request.getParameter("username"),request.getParameter("password")));
        if(flag){
            System.out.println("[DEBUG]用户注册成功,携带提示消息返回登录界面...");
            request.setAttribute("register_msg","注册成功,请登录");
            request.getRequestDispatcher("/login.jsp").forward(request,response);
        }else {
            System.out.println("[DEBUG]用户登录失败,携带提示消息返回注册界面...");
            request.setAttribute("register_msg","用户名已存在,注册失败");
            request.getRequestDispatcher("/register.jsp").forward(request,response);
        }
    }
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

 13.增删改查有关的jsp与Servlet

brand.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@page isELIgnored="false" %>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>

<body>
    <h2>${user.username},欢迎您</h2><br>
    <input type="button" value="新增" id="add"><br>
    <hr>
    <table border="1" cellspacing="0" width="800">
        <tr>
            <th>序号</th>
            <th>品牌名称</th>
            <th>企业名称</th>
            <th>排序</th>
            <th>品牌介绍</th>
            <th>状态</th>
            <th>操作</th>
        </tr>
        <c:forEach items="${brands}" var="brand" varStatus="status">
            <tr align="center">
                <td>${status.count}</td>
                <td>${brand.brandName}</td>
                <td>${brand.companyName}</td>
                <td>${brand.ordered}</td>
                <td>${brand.description}</td>
                <c:if test="${brand.status==1}">
                    <td><%="启用"%></td>
                </c:if>
                <c:if test="${brand.status==0}">
                    <td><%="禁用"%></td>
                </c:if>
                <td>
                    <a href="/web_demo4_brandDemo_war/selectByIdServlet?id=${brand.id}">修改</a>
                    <a href="/web_demo4_brandDemo_war/deleteServlet?id=${brand.id}">删除</a>
                </td>
            </tr>
        </c:forEach>
    </table>
</body>
<script>
    document.getElementById("add").onclick = function () {
        location.href = "/web_demo4_brandDemo_war/addBrand.jsp";
    }
</script>
</html>
@WebServlet("/selectAllServlet")
public class SelectAllServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("[DEBUG]查询并显示所有数据...");
        request.setAttribute("brands",new BrandService().selectAll());
        request.getRequestDispatcher("/brand.jsp").forward(request,response);
    }
    //这里的doPost在jsp中不访问,但最好写,如果别的资源使用post方式请求转发
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}
@WebServlet("/deleteServlet")
public class DeleteServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("[DEBUG]用户选择删除数据...");
        req.setCharacterEncoding("UTF-8");
        new BrandService().deleteById(Integer.parseInt(req.getParameter("id")));;
        resp.sendRedirect("/web_demo4_brandDemo_war/selectAllServlet");
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}

addBrand.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java"%>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>添加品牌</title>
</head>

<body>
    <h3>添加品牌</h3>
    <form action="/web_demo4_brandDemo_war/addServlet" method="post">
        品牌名称:<input name="brandName" value="淘宝"><br>
        企业名称:<input name="companyName" value="阿里巴巴"><br>
        排序状况:<input name="ordered" value="10"><br>
        描述信息:<textarea rows="5" cols="20" name="description">阿里巴巴</textarea><br>
        状态信息:
        <input type="radio" name="status" value="0" checked>禁用
        <input type="radio" name="status" value="1">启用<br>
        <input type="submit" value="提交">
    </form>
</body>

</html>
@WebServlet("/addServlet")
public class AddServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("[DEBUG]用户添加数据...");
        req.setCharacterEncoding("UTF-8");
        new BrandService().add(new Brand(null,
                req.getParameter("brandName"),
                req.getParameter("brandName"),
                Integer.parseInt(req.getParameter("ordered")),
                req.getParameter("description"),
                Integer.parseInt(req.getParameter("status"))));
        resp.sendRedirect("/web_demo4_brandDemo_war/selectAllServlet");
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}

update.jsp

<%@page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@page isELIgnored="false" %>
<!DOCTYPEhtml>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>修改品牌</title>
</head>

<body>
<h3>修改品牌</h3>
<form action="/web_demo4_brandDemo_war/addServlet" method="post">
    <%--隐藏id--%>
    <input name="id" value="${brand.id}" type="hidden">
    品牌名称:<input name="brandName" value="${brand.brandName}"><br>
    企业名称:<input name="companyName" value="${brand.companyName}"><br>
    排序状况:<input name="ordered" value="${brand.ordered}"><br>
    描述信息:<textarea rows="5" cols="20" name="description">${brand.description}</textarea><br>
    状态信息:
    <input type="radio" name="status" value="0" <c:if test="${brand.status==0}">checked</c:if>>禁用
    <input type="radio" name="status" value="1" <c:if test="${brand.status==1}">checked</c:if>>启用<br>
    <input type="submit" value="提交">
</form>
</body>

</html>
<%@page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@page isELIgnored="false" %>
<!DOCTYPEhtml>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>修改品牌</title>
</head>

<body>
<h3>修改品牌</h3>
<form action="/web_demo4_brandDemo_war/updateServlet" method="post">
    <%--隐藏id--%>
    <input name="id" value="${brand.id}" type="hidden">
    品牌名称:<input name="brandName" value="${brand.brandName}"><br>
    企业名称:<input name="companyName" value="${brand.companyName}"><br>
    排序状况:<input name="ordered" value="${brand.ordered}"><br>
    描述信息:<textarea rows="5" cols="20" name="description">${brand.description}</textarea><br>
    状态信息:
    <input type="radio" name="status" value="0" <c:if test="${brand.status==0}">checked</c:if>>禁用
    <input type="radio" name="status" value="1" <c:if test="${brand.status==1}">checked</c:if>>启用<br>
    <input type="submit" value="提交">
</form>
</body>

</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/434367.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Openfeign+Ribbon+Hystrix断路器(服务降级)

热部署对于Hystrix的热不是不是很明显 所以最好修改代码之后重启服务 简介 在微服务架构中存在多个可直接调用的服务,这些服务若在调用时出现故障会导致连锁效应,也就是可能让整个系统变得不可用,这种情况我们称之为服务雪崩效应. 服务雪崩效应通常发生在微服务架构中&…

【详识JAVA语言】String 类1

String类的重要性 在C语言中已经涉及到字符串了&#xff0c;但是在C语言中要表示字符串只能使用字符数组或者字符指针&#xff0c;可以使用标准库提 供的字符串系列函数完成大部分操作&#xff0c;但是这种将数据和操作数据方法分离开的方式不符合面相对象的思想&#xff0c;而…

SpringCloud微服务-RabbitMQ快速入门

文章目录 RabbitMQ快速入门1、什么是MQ&#xff1f;2、RabbitMQ概述3、RabbitMQ的结构和概念4、常见消息模型5、HelloWorld RabbitMQ快速入门 1、什么是MQ&#xff1f; MQ &#xff08;MessageQueue&#xff09;&#xff0c;中文是消息队列&#xff0c;字面来看就是存放消息的…

【知识整理】MySQL数据库开发设计规范

一、规范背景与目的 MySQL数据库与 Oracle、 SQL Server 等数据库相比&#xff0c;有其内核上的优势与劣势。我们在使用MySQL数据库的时候需要遵循一定规范&#xff0c;扬长避短。 本规范旨在帮助或指导RD、QA、OP等技术人员做出适合线上业务的数据库设计。在数据库变更和处理…

【LabVIEW FPGA】CIC滤波器

一、CIC滤波器应用概述 在通信数字信号上下变频时&#xff0c;经常会用到对数字信号的升采样和降采样&#xff0c;即通过CIC数字速率器实现变采样率。 二、滤波器IP 首先设置滤波器基本参数&#xff08;filter specification&#xff09; 滤波器类型&#xff08;Filter Type…

裸机编程的几种模式、架构、缺陷

目录 裸机编程模式/架构 1&#xff1a;初始化代码的编写 裸机编程模式/架构 2&#xff1a;轮询模式 裸机编程模式/架构 3&#xff1a;轮询加中断执行模式 裸机编程模式/架构 4&#xff1a;中断定时器主循环的前后台架构 裸机编程模式/架构 5&#xff1a;前后台 状态机架构…

Android开发技巧,最详细的解释小白也能听懂

今天&#xff0c;跟大家聊聊&#xff0c;Framework开发的那些事。 系统应用开发&#xff0c;现在来说&#xff0c;已经开始脱离系统&#xff0c;单独拿出来开发&#xff0c;系统定制接口&#xff0c;已提供给应用调用&#xff0c;用来增强功能。 原生的桌面&#xff0c;拨号&…

C++之获取Windows系统信息

目录 1. 操作系统版本 2. 获取CPU信息 3. 获取内存信息 4. 获取硬盘信息 5.获取网络接口信息 6.获取计算机名称、用户名 在C中&#xff0c;你可以使用Windows API函数来获取Windows系统的各种信息。以下是一些常见的API函数和示例代码&#xff0c;用于获取Windows系统信息…

深入了解 Android 中的 RelativeLayout 布局

RelativeLayout 是 Android 中常用的布局之一&#xff0c;它允许开发者基于子视图之间的相对位置来排列界面元素。在这篇博客中&#xff0c;我们将详细介绍 RelativeLayout 的各种属性&#xff0c;并提供代码示例和解释。 第一个示例 <RelativeLayoutandroid:layout_width…

腾讯云服务器99元一年是真的吗?只要61元!

腾讯云服务器99元一年是真的吗&#xff1f;假的&#xff0c;不要99&#xff0c;只要61元&#xff01;又降价了&#xff01;腾讯云服务器多少钱一年&#xff1f;61元一年起&#xff0c;2核2G3M配置&#xff0c;腾讯云2核4G5M轻量应用服务器165元一年、756元3年&#xff0c;4核16…

数据分析-Pandas数据的直方图探查

数据分析-Pandas数据的直方图探查 数据分析和处理中&#xff0c;难免会遇到各种数据&#xff0c;那么数据呈现怎样的规律呢&#xff1f;不管金融数据&#xff0c;风控数据&#xff0c;营销数据等等&#xff0c;莫不如此。如何通过图示展示数据的规律&#xff1f; 数据表&…

网络编程 24/3/6 作业

1、数据库的增删改 #include <myhead.h> int main(int argc, const char *argv[]) {//定义数据库句柄指针sqlite3 *kdbNULL;//打开数据库&#xff0c;不存在则创建if(sqlite3_open("./my.db",&kdb)!SQLITE_OK){printf("sqlite3_open error\n");…

如何解决无法联网的IP代理问题

目录 前言 一、检查网络连接问题 二、检查IP代理配置问题 三、更换IP代理 四、使用IP池 总结 前言 在进行网络爬虫、数据采集等涉及到频繁请求的操作中&#xff0c;IP代理是一个必不可少的工具。通过使用IP代理&#xff0c;我们可以隐藏真实的IP地址&#xff0c;防止被目…

解决DBeaver执行脚本报错No active connection

解决DBeaver执行脚本报错No active connection 1、报错问腿 2、问题解决 2.1、右键点击该数据库&#xff0c;选择SQL编辑器&#xff0c;选择新建SQL编辑器&#xff0c;然后将sql语句复制过去。 或者左击选中数据库后直接使用快捷键 Ctrl] 2.2、在Project-General中找到Scr…

Nginx入门

Nginx入门 本章目标 Ninux简介 安装 Nginx配置 负载均衡 静态化处理 本章内容 一、什么是Nginx&#xff1f; Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器&#xff0c;同时也提供了IMAP/POP3/SMTP服务。Nginx是由伊戈尔赛索耶夫为俄罗斯访问量第二的http:/…

Claude3深夜震撼发布!模型特点分析,附使用教程

Claude3深夜震撼发布&#xff01;模型特点分析&#xff0c;附使用教程 引言 最新发布的Claude3引起了广泛关注&#xff0c;这次发布一举推出了三个不同类型的模型&#xff0c;分别是Claude 3 Haiku、Claude 3 Sonnet和Claude 3 Opus。每个模型都具有独特的特点和能力&#xff…

逆向案例五、爬取b站评论,表单MD5加密

1.便捷写爬虫网站&#xff1a; Convert curl commands to code 使用流程&#xff1a;又点击想要抓的包&#xff0c;复制URL&#xff08;base&#xff09;格式复制 在上面链接中粘贴即可 2.找到含有评论的包&#xff08;即main?oid)&#xff1a;观察表单发现两处参数在变化&…

protobuf 25.3在window的安装

1、下载地址 protobuf 25.3 下载完后&#xff0c;执行下面语句更新第三方库 git submodule update --init --recursive2、 cmake安装 注意&#xff1a;编译需要在vs2019及以上&#xff0c;因为abseil-cpp的编译需要是vs2019及以上

Nacos基础(注册中心和配置中心)

文章目录 参考文章一、 配置管理1、添加依赖2、添加配置信息3、创建例子4、在Nacos创建配置命名空间&#xff1a;配置集配置id配置组加载多配置文件 二、注册中心2.1、添加依赖2.2、添加项目Nacos配置2.3、添加服务发现注解这个时候你启动Nacos 如果遇到跳转链接失效请在评论区…

numpy——基础知识(创建/类型/形状/运算)(python)

简介 NumPy 是一个 Python 包。它代表 Numeric Python。 它是一个由多维数组对象和用于处理数组的例程集合组成的库。 Numeric&#xff0c;即 NumPy 的前身&#xff0c;是由 Jim Hugunin 开发的。 也开发了另一个包 Numarray &#xff0c;它拥有一些额外的功能。 2005年&#…