Javaweb复习资料(二)(下)

简介: Javaweb复习资料(二)

六、cookie


https://yangyongli.blog.csdn.net/article/details/117912761


七、session


https://yangyongli.blog.csdn.net/article/details/117914643


八、jsp(※)


1 JSP基础


1.1 JSP简介


JSP全称是Java Server Page,它和Servlet一样,也是sun公司推出的一套开发动态web资源的技术,称为JSP/Servlet规范。JSP的本质其实就是一个Servlet。


1.2 JSP和HTML以及Servlet的适用场景


image.png


1.3 JSP简单入门


创建JavaWeb工程



在index.jsp中填写内容


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>JSP的入门</title>
  </head>
  <body>
      这是第一个JSP页面
  </body>
</html>


部署项目


沿用会话管理工程的部署方式即可。


测试运行



1.4 JSP说明


写在之前: 明确JSP就是一个Servlet。是一个特殊的Servlet。


JSP的原理:


客户端提交请求


——Tomcat服务器解析请求地址


——找到JSP页面


——Tomcat将JSP页面翻译成Servlet的java文件


——将翻译好的.java文件编译成.class文件


——返回到客户浏览器上。


1)执行过程分析图



2)JSP的.java文件内容分析(看不懂跳过,反jsp本质就是servlet)


当我们打开index.jsp翻译的java文件看到的就是public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase类的声明,然后我们在Tomcat的源码中找到类的声明,如下图:



这张图一出场,就表明我们写的JSP它本质就是一个HttpServlet了。



同时,我们在index_jsp.java文件中找到了输出页面的代码,并且在浏览器端查看源文件,看到的内容是一样的。这也就是说明,我们的浏览器上的内容,在通过jsp展示时,本质都是用out.write()输出出来的。


讲到这里,我们应该清楚的认识到,JSP它是一个特殊的Servlet,主要是用于展示动态数据。它展示的方式是用流把数据输出出来,而我们在使用JSP时,涉及HTML的部分,都与HTML的用法一致,这部分称为jsp中的模板元素,在开发过程中,先写好这些模板元素,因为它们决定了页面的外观。


2 JSP应用


2.1 JSP语法


1)Java代码块


在jsp中,可以使用java脚本代码。形式为:<% 此处写java代码 %>


但是,在实际开发中,极少使用此种形式编写java代码。同时需要注意的是:


<%
    在里面写java程序脚本需要注意:这里面的内容由tomcat负责翻译,翻译之后是service方法的成员变量
%>


示例:


<!--Java代码块-->
<% out.println("这是Java代码块");%>
<hr/>


2)JSP表达式


在jsp中,可以使用特定表达式语法,形式为:<%=表达式%>


jsp在翻译完后是out.print(表达式内容);


所以:<%out.print("当前时间);%>和<%="当前时间"%>是一样的。


在实际开发中,这种表达式语法用的也很少使用。


示例:


<!--JSP表达式-->
<%="这是JSP表达式"%><br/>
就相当于<br/>
<%out.println("这是没有JSP表达式输出的");%>


3)JSP声明


在JSP中也可以声明一些变量,方法,静态方法,形式为:<%! 声明的内容 %>

使用JSP声明需要注意:


<%! 
    需要注意的是: 写在里面的内容将会被tomcat翻译成全局的属性或者类方法。
%>                                    


示例:


<!--JSP声明-->
<%! String str = "声明语法格式";%>
<%=str%>


4)JSP注释


在使用JSP时,它有自己的注释,形式为:<%–注释–%>


需要注意的是:


在Jsp中可以使用html的注释,但是只能注释html元素,不能注释java程序片段和表达式。同时,被html注释部分会参与翻译,并且会在浏览器上显示


jsp的注释不仅可以注释java程序片段,也可以注释html元素,并且被jsp注释的部分不会参与翻译成.java文件,也不会在浏览器上显示。


示例:


<%--JSP注释--%>
<!--HTML注释-->


5)语法的示例


JSP语法完整示例代码


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>JSP语法</title>
</head>
<body>
<!--Java代码块-->
<% out.println("这是Java代码块");%>
<hr/>
<!--JSP表达式-->
<%="这是JSP表达式"%><br/>
就相当于<br/>
<%out.println("这是没有JSP表达式输出的");%>
<hr/>
<!--JSP声明-->
<%! String str = "声明语法格式";%>
<%=str%>
<hr/>
<%--JSP注释--%>
<!--HTML注释-->
</body>
</html>


JSP语法运行结果



2.2 JSP指令


1)page指令


  • language: 告知引擎,脚本使用的是java,默认是java,支持java。不写也行。


  • extends:告知引擎,JSP对应的Servlet的父类是哪个,不需要写,也不需要改。


  • import:告知引擎,导入哪些包(类)。


注意:


引擎会自动导入:java.lang.*,javax.servlet.*,javax.servlet.http.*,javax.servlet.jsp.*


导入的形式: (用Eclipse:Alt+/ 自动导入)


​<%@page import=”java.util.Date,java.util.UUID”%>
或者:
​<%@page import=”java.util.Date”%>
​<%@page import=”java.util.UUID”%> 


  • session:告知引擎是否产生HttpSession对象,即是否在代码中调用


  • request.getSession()。默认是true。


  • buffer:JspWriter用于输出JSP内容到页面上。告知引擎,设定他的缓存大小。默认8kb。


  • errorPage:告知引擎,当前页面出现异常后,应该转发到哪个页面上(路径写法:/代表当前应用)


小贴士:当在errorpage上使用了isErrorPage=true之后,ie8有时候不能正常显示


配置全局错误页面:web.xml


<error-page>    
    <exception-type>java.lang.Exception</exception-type>                
    <location>/error.jsp</location>
</error-page>
<error-page>
    <error-code>404</error-code>
    <location>/404.html</location>
</error-page>                                 


当使用了全局错误页面,就无须再写errorPage来实现转到错误页面,而是由服务器负责跳转到错误页面。


  • isErrorPage:告知引擎,是否抓住异常。如果该属性为true,页面中就可以使用exception对象,打印异常的详细信息。默认值是false。


  • contentType:告知引擎,响应正文的MIME类型。contentType="text/html;charset=UTF-8"


相当于response.setContentType("text/html;charset=UTF-8");


  • pageEncoding:告知引擎,翻译jsp时(从磁盘上读取jsp文件)所用的码表。pageEncoding="UTF-8"相当于告知引擎用UTF-8读取JSP


  • isELIgnored:告知引擎,是否忽略EL表达式,默认值是false,不忽略。


2)include指令


语法格式:<%@include file="" %>该指令是包含外部页面。


属性:file,以/开头,就代表当前应用。


使用示例



在编译成的java servlet文件中是这样的,也就是说,include.jsp 后续 代码可以直接使用 included.jsp 中的 str变量。



3)taglib指令


语法格式:<%taglib uri="" prefix=""%>


作用:该指令用于引入外部标签库。html标签和jsp标签不用引入。


属性:


  • uri:外部标签的URI地址。


  • prefix:使用标签时的前缀。


2.3 JSP细节


1)九大隐式对象


什么是隐式对象呢?它指的是在jsp中,可以不声明就直接使用的对象。


它只存在于jsp中,因为java类中的变量必须要先声明再使用。


其实jsp中的隐式对象也并非是未声明,只是它是在翻译成.java文件时声明的。所以我们在jsp中可以直接使用。


也就是说下面的对象在jsp中可以直接使用。


image.png


2)PageContext对象


简介


它是JSP独有的对象,Servlet中没有这个对象。本身也是一个域(作用范围)对象,但是它可以操作其他3个域对象中的属性。而且还可以获取其他8个隐式对象。


生命周期

它是一个局部变量,所以它的生命周期随着JSP的创建而诞生,随着JSP的结束而消失。每个JSP页面都有一个独立的PageContext。


常用方法



在上图中,同学们发现没有页面域操作的方法,其实是定义在了PageContext的父类JspContext中,如下图所示:



3)四大域对象


image.png


4)四大域对象作用范围


pageContext


作用范围:当前jsp页面;


作用:获取九大内置对象;


常用方法:getAttribute()、setAttribute()、removeAttribute()、findAttribute()


httpServletRequest


作用范围:一次请求范围内,转发有效重定向失效;


作用:将servlet中的数据通过request对象带到jsp页面;


httpSession


作用范围:存活时间内(默认30分钟),一次会话内有效,转发和重定向都有效;


servletContext


作用范围:整个web应用;


在jsp的九大内置对象中,servletContext对应application;


2.4 JSP最佳实战效果——MVC模型


  • M:model ,通常用于封装数据,封装的是数据模型。


  • V:view ,通常用于展示数据。动态展示用jsp页面,静态数据展示用html。


  • C:controller ,通常用于处理请求和响应。一般指的是Servlet。


Servlet:擅长处理业务逻辑,不擅长输出显示界面。在web开发中多用于控制程序逻辑(流程)。所以我们称之为:控制器。


JSP:擅长显示界面,不擅长处理程序逻辑。在web开发中多用于展示动态界面。所以我们称之为:视图。


例如:



九、知识补充:


JDK、JRE、JVM和SDK是啥啊都?


JDK(Java Development Kit) 是 Java 语言的软件开发工具包(SDK)。


在JDK的安装目录下有一个jre目录,里面有两个文件夹bin和lib,在这里可以认为bin里的就是jvm,lib中则是jvm工作所需要的类库,而jvm和 lib合起来就称为jre。


JRE(Java Runtime Environment,Java运行环境),包含JVM标准实现及Java核心类库。JRE是Java运行环境,并不是一个开发环境,所以没有包含任何开发工具(如编译器和调试器)


JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。


在安装目录下是这样的



根据上面我们可以画成下面的关系图



SDK是Software Development Kit 一般指软件开发包,可以包括函数库、编译程序等(可以效仿API去理解),是给java应用程序开发者使用的。


Servlet编写三种方式


我们在实现Servlet功能时,可以选择以下三种方式:


1. 第一种:实现Servlet接口,接口中的方法必须全部实现。


使用此种方式,表示接口中的所有方法在需求方面都有重写的必要。此种方式支持最大程度的自定义(我理解的就是真的个性化)。


2. 第二种:继承GenericServlet,


继承GenericServlet,service方法必须重写,其他方可根据需求,选择性重写。


使用此种方式,表示只在接收和响应客户端请求这方面有重写的需求,而其他方法可根据实际需求选择性重写,使我们的开发Servlet变得简单。但是,此种方式是和HTTP协议无关的。


比如说下面重写了 service方法


public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
    HttpServletRequest request;
    HttpServletResponse response;
    try {
        request = (HttpServletRequest)req;
        response = (HttpServletResponse)res;
    } catch (ClassCastException var6) {
        throw new ServletException("non-HTTP request or response");
    }
    this.service(request, response);
}


service源码


protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String method = req.getMethod();
    long lastModified;
    if (method.equals("GET")) {
        lastModified = this.getLastModified(req);
        if (lastModified == -1L) {
            this.doGet(req, resp);
        } else {
            long ifModifiedSince;
            try {
                ifModifiedSince = req.getDateHeader("If-Modified-Since");
            } catch (IllegalArgumentException var9) {
                ifModifiedSince = -1L;
            }
            if (ifModifiedSince < lastModified / 1000L * 1000L) {
                this.maybeSetLastModified(resp, lastModified);
                this.doGet(req, resp);
            } else {
                resp.setStatus(304);
            }
        }
    } else if (method.equals("HEAD")) {
        lastModified = this.getLastModified(req);
        this.maybeSetLastModified(resp, lastModified);
        this.doHead(req, resp);
    } else if (method.equals("POST")) {
        this.doPost(req, resp);
    } else if (method.equals("PUT")) {
        this.doPut(req, resp);
    } else if (method.equals("DELETE")) {
        this.doDelete(req, resp);
    } else if (method.equals("OPTIONS")) {
        this.doOptions(req, resp);
    } else if (method.equals("TRACE")) {
        this.doTrace(req, resp);
    } else {
        String errMsg = lStrings.getString("http.method_not_implemented");
        Object[] errArgs = new Object[]{method};
        errMsg = MessageFormat.format(errMsg, errArgs);
        resp.sendError(501, errMsg);
    }
}


3. 第三种:继承HttpServle


继承HttpServlet,它是javax.servlet.http包下的一个抽象类,是GenericServlet的子类。如果我们选择继承HttpServlet时,只需要重写doGet和doPost方法,不要覆盖service方法。


使用第三种方式,表示我们的请求和响应需要和HTTP协议相关。也就是说,我们是通过HTTP协议来访问的。那么每次请求和响应都符合HTTP协议的规范。请求的方式就是HTTP协议所支持的方式(目前我们只知道GET和POST,而实际HTTP协议支持7种请求方式,GET POST PUT DELETE TRACE OPTIONS HEAD )。


例如:


import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
//@WebServlet(name = "thirdServlet", urlPatterns = "/servlet")
//我们还可以进一步简化,因为我们发现其实name属性好像没啥用
//@WebServlet(urlPatterns = "/servlet")
//到这一步之后,还可以精简到底,如果括号里面只有一个值,那么默认表示的就是urlPattern
@WebServlet("/servlet")
public class ThirdServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }
}


request获取请求参数


HttpServletRequest对象获取请求参数的常用方法,以及把获取到的请求参数封装到实体类中的方式。首先,我们先来创建一个Servlet对象


/**
 * 封装请求正文到javabean(数据模型)
 */
public class RequestDemo3 extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        /*
         * 把下面
         *    1)获取请求参数
         *    2)封装请求参数到实体类中
         * 中定义的test1到test8逐个添加到此处来运行即可。
         */
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }
}


接下来,我们在来准备一个表单页面:


<html>
<head>
  <title>login to request demo 3</title>
</head>
<body>
<form action="/day10_1122_requestresponse/RequestDemo3" method="post">
  用户名:<input type="text" name="username" /><br/>
  密码:<input type="password" name="password" /><br/>
  性别:<input type="radio" name="gender" value="1" checked>男
  <input type="radio" name="gender" value="0">女
  <br/>
  <input type="submit" value="注册" />
</form>
</body>
</html>


现在,我们开始分析HttpServletRequest对象用于获取请求参数的方法:


1. 获取请求参数


getParameter()方法的示例代码


/**
 * 获取请求正文,一个名称对应一个值。                没有使用确认密码
 * @param request
 * @param response
 * @throws ServletException
 * @throws IOException
 */
private void test1(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    //1.获取请求正文
    String username = request.getParameter("username");
    String password = request.getParameter("password");
    String gender = request.getParameter("gender");
    System.out.println(username+","+password+","+gender);
}


getParameterValues()方法的示例代码


/**
 * 获取请求正文,一个名称可能对应多个值                 使用了确认密码
 * @param request
 * @param response
 * @throws ServletException
 * @throws IOException
*/
private void test2(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    //1.获取请求正文
    String username = request.getParameter("username");
    String[] password = request.getParameterValues("password");//当表单中有多个名称是一样时,得到是一个字符串数组
    String gender = request.getParameter("gender");
    System.out.println(username+","+Arrays.toString(password)+","+gender);
}


<html>
<head>
  <title>login to request demo 4</title>
</head>
<body>
<form action="/day10_1122_requestresponse/RequestDemo4" method="post" enctype="multipart/form-data">
  用户名:<input type="text" name="username" /><br/>
  密码:<input type="password" name="password" /><br/>
  确认密码:<input type="password" name="password" /><br/>
  性别:<input type="radio" name="gender" value="1" checked>男
  <input type="radio" name="gender" value="0">女
  <br/>
  <input type="submit" value="注册" />
</form>
</body>
</html>


getParameterNames()方法的示例代码


/**
 * 获取请求正文,一个名称一个值。但是先要获取正文名称的枚举(key的枚举)       没有使用确认密码
 * @param request
 * @param response
 * @throws ServletException
 * @throws IOException
*/
private void test3(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    //1.获取请求正文名称的枚举
    Enumeration<String> names = request.getParameterNames();
    //2.遍历正文名称的枚举
    while(names.hasMoreElements()){
        String name = names.nextElement();
        String value = request.getParameter(name);
        System.out.println(name+":"+value);
    }
}


总结:


以上三个方法可以获取表单提交过来的请求参数。


参数的名称是一个字符串,参数的值可能是一个字符串,也可能是一个字符串数组。


2. 封装请求参数到实体类中


我们通过上面的方法可以获取到请求参数,但是如果参数过多,在进行传递时,方法的形参定义将会变得非常难看。此时我们应该用一个对象来描述这些参数,它就是实体类。这种类的定义,从基础阶段我们就开始使用了。在基础阶段,我们做过一个学生管理系统,用到了一个Student的类,它就是用于描述一个学生的实体类。


我们现在要做的就是把表单中提交过来的数据填充到实体类中。


第一种:最简单直接的封装方式


/**
 * 封装请求正文到User对象中                 没有使用确认密码
 * @param request
 * @param response
 * @throws ServletException
 * @throws IOException
 */
private void test4(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    //1.获取请求正文
    String username = request.getParameter("username");
    String password = request.getParameter("password");
    String gender = request.getParameter("gender");
    //2.创建一个User对象
    User user = new User();
    System.out.println("封装前:"+user.toString());
    //3.把请求正文封装到user对象中
    user.setUsername(username);
    user.setPassword(password);
    user.setGender(gender);
    System.out.println("封装后:"+user.toString());
}


第二种:使用反射方式封装


此种封装的使用要求是,表单<input>标签的name属性取值,必须和实体类中定义的属性名称一致。


/**
 * 封装请求正文到javabean中                   没有使用确认密码
 * 使用反射+内省实现数据模型的封装
 * 内省:是sun公司推出的一套简化反射操作的规范。把javabean中的元素都封装成一个属性描述器。
 *          属性描述器中会有字段信息,get和set方法(取值或存值)
 * @param request
 * @param response
 * @throws ServletException
 * @throws IOException
*/
private void test5(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    //1.获取请求正文名称的枚举
    Enumeration<String> names = request.getParameterNames();
    User user = new User();
    System.out.println("封装前:"+user.toString());
    //2.遍历正文名称的枚举
    while(names.hasMoreElements()){
        String name = names.nextElement();
        String value = request.getParameter(name);
        try{
            //1.拿到User对象中的属性描述器。是谁的属性描述器:是由构造函数的第一个参数决定的。第二个参数是指定javabean的字节码
            PropertyDescriptor pd = new PropertyDescriptor(name, User.class);//参数指的就是拿哪个类的哪个属性的描述器
            //2.设置javabean属性的值
            Method method = pd.getWriteMethod();
            //3.执行方法
            method.invoke(user, value);//第一个参数是指的给哪个对象,第二个参数指的是赋什么值
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    System.out.println("封装后:"+user.toString());
} 


第三种:使用反射封装,同时请求参数的值是一个数组


此种方式其实就是针对请求参数中包含name属性相同的参数,例如:密码和确认密码,还有爱好。


/**
 * 获取请求正文的关系映射Map<String,String[]>        使用确认密码
 * @param request
 * @param response
 * @throws ServletException
 * @throws IOException
 */
private void test6(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    //1.获取请求正文的映射关系
    Map<String,String[]> map = request.getParameterMap();
    //2.遍历集合
    for(Map.Entry<String,String[]> me : map.entrySet()){
        String name = me.getKey();
        String[] value = me.getValue();
        System.out.println(name+":"+Arrays.toString(value));
    }
} 


当我们把请求参数获取出来之后,就要考虑如何针对数组的反射了,具体代码如下:


 /**
 * 封装请求正文到javabean。使用的是反射+内省            使用了确认密码
 * @param request
 * @param response
 * @throws ServletException
 * @throws IOException
 */
private void test7(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    //1.获取请求正文的映射关系
    Map<String,String[]> map = request.getParameterMap();
    Users user = new Users();
    System.out.println("封装前:"+user.toString());
    //2.遍历集合
    for(Map.Entry<String,String[]> me : map.entrySet()){
        String name = me.getKey();
        String[] value = me.getValue();
        try{
            //1.拿到User对象中的属性描述器。是谁的属性描述器:是由构造函数的第一个参数决定的。第二个参数是指定javabean的字节码
            PropertyDescriptor pd = new PropertyDescriptor(name, Users.class);//参数指的就是拿哪个类的哪个属性的描述器
            //2.设置javabean属性的值
            Method method = pd.getWriteMethod();
            //3.执行方法
            //判断参数到底是几个值
            if(value.length > 1){//最少有2个元素
                method.invoke(user, (Object)value);//第一个参数是指的给哪个对象,第二个参数指的是赋什么值
            }else{
                method.invoke(user, value);//第一个参数是指的给哪个对象,第二个参数指的是赋什么值
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    System.out.println("封装后:"+user.toString());
}


当我们写完此种封装方式之后,同学们可以发现,我们绝大多数封装都可以使用这段代码来实现。并且,无论是谁来写这段通用的封装代码,其代码内容都是大同小异的。**那么,我们就可以得出一个很有趣的结论:一般遇到这种情况时,肯定有人帮我们写好了,我们只需要用就行了。**我们后面还会遇到类似这样的情况。


此时,帮我们写好这段封装代码的是apache软件基金会,我们前面学习的tomcat也是它提供的。它里面有一个开源工具包集合commons,里面有很多开源工具类,今天我们就来讲解第一个:commons-beanutils。


第四种:使用apache的commons-beanutils实现封装


实现代码:


/**
 * 终极方法:使用beanutils实现请求正文封装到javabean中       使用了确认密码
 * 要想使用beanutils,需要先导包
 * @param request
 * @param response
 * @throws ServletException
 * @throws IOException
 */
private void test8(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    Users user = new Users();
    System.out.println("封装前:"+user.toString());
    try{
        BeanUtils.populate(user, request.getParameterMap());//就这一句话
    }catch(Exception e){
        e.printStackTrace();
    }
    System.out.println("封装后:"+user.toString());
}



相关文章
|
26天前
|
Web App开发 SQL Java
javaweb实现分页(二)
javaweb实现分页(二)
18 1
|
26天前
|
SQL 关系型数据库 MySQL
javaweb实现分页查询(一)
javaweb实现分页查询(一)
17 0
|
26天前
|
SQL 关系型数据库 MySQL
javaweb中实现分页,持续更新……
javaweb中实现分页,持续更新……
15 1
|
3月前
|
Java 数据库 数据安全/隐私保护
基于Java的公务员考试资料共享平台的设计与实现
基于Java的公务员考试资料共享平台的设计与实现
48 0
|
1月前
|
Java Spring 容器
[JavaWeb]——过滤器filter与拦截器Interceptor的使用、执行过程、区别
[JavaWeb]——过滤器filter与拦截器Interceptor的使用、执行过程、区别
|
1月前
JavaWeb 开发之 ServletContext 的和使用
JavaWeb 开发之 ServletContext 的和使用
21 1
|
20天前
|
SQL 前端开发 Java
Java后端进阶之路: JavaWeb(四)
Java后端进阶之路: JavaWeb
33 1
|
XML SQL Java
Java后端进阶之路: JavaWeb(三)
Java后端进阶之路: JavaWeb
30 1
|
2月前
|
设计模式 XML 前端开发
JavaWeb 会话_过滤_监听器
JavaWeb 会话_过滤_监听器
26 0
|
3月前
|
SQL JSON 前端开发
JavaWeb:商品管理系统(Vue版)
JavaWeb商品管理系统是一个使用Java语言开发的,用于管理商品信息的Web应用程序。它提供了一套完整的功能,包括商品的增加、删除、修改和查询等操作。
51 2
JavaWeb:商品管理系统(Vue版)