JWS实现WebService

article/2025/9/22 21:38:10

    WebService估计大家都有听过或者使用过。Java有几种常用的方式实现webservice,本文主要是讨论JWS实现。

什么是webservice

    简单而言,webservice就是通过SOAP协议在Web上提供的服务,使用WSDL文件进行说明。其特点是走SOAP协议而不是http协议,且传输的数据格式是xml而不是字符串。因为xml的特性,webservice具有跨语言跨平台的特点,而且xml可以封装复杂的对象,甚至可以使用xml加密数据。但由于涉及xml解析,速度相对慢一些。

实现webservice的方式

    webservice分为服务端和客户端。服务端提供功能接口,客户端通过wsdl文件(xml格式)获取相关信息并调用接口。服务端搭建常用的方式有3种:JWS、Axis(Axis2)、CXF。客户端常用的调用方式有6种:wsimport、JDK提供的相关API、URLConnection、Ajax、axis、cxf。

    我们先了解一下JWS提供的一些注解:

@WebService

    @WebService:用于指定该类是webservice的服务器类。其属性值有:

  • serviceName:对外发布的服务名,对应wsdl:service,缺省值为Java类名+Service

  • endpointInterface:服务端点接口的完整, 指定SEI(Service EndPoint Interface)服务端点接口,一般使用接口在项目的相对路径

  • name:webservice的名称。在默认情况下,该值是实现XML webservice的类的名称,对应wsdl:portType 。缺省值为 Java 类或接口的非限定名称

  • portName:webservice的端口名称。对应wsdl:portName。缺省值为WebService.name+Port

  • targetNamespace:指定名称空间,一般使用接口实现类的包名的反缀

  • wsdlLocation:指定用于定义webservice的wsdl文档的 Web 地址,默认是发布地址+?wsdl。

@WebMethod

    @WebMethod:用于指定服务接口(SEI)上的方法,或JavaBeans 端点的服务器端点实现类。注意@WebMethod必须使用在@WebService注释的类中。其属性值有:

  • operationName:对应wsdl:opereation。即客户端调用时的方法名,可以理解为隐藏服务端实际的方法名而对外暴露用于调用的方法名。缺省值为方法名

  • action:定义此操作的行为。对于SOAP绑定,此值将确定SOAPAction头的值。缺省值为Java方法的名称

  • exclude:指定是否从WebService中排除某一方法。缺省值为false

@WebParam

    @WebParam:注释用于定制从单个参数至WebService消息部件和XML元素的映射。注意要用在SEI的方法,或JavaBeans 端点的服务器端点实现类。

  • name:参数的名称。如果不指定,参数名将会默认逐个替换成arg0、arg1…至argn(假设参数个数为n+1个)

  • partName:定义用于表示此参数的 wsdl:part属性的名称

  • targetNamespace:指定参数的XML名称空间。缺省值为WebService的targetNamespace

  • mode:参数的流向(IN、OUT、INOUT的一种)

  • header:指定参数是在消息头还是消息体中。缺省值为 false

搭建webservice服务端

    先创建一个springboot的项目,具体操作这里就省略了,大伙都懂得怎么搭建的。下面的案例就以查找学生成绩作为例子。

     idea提供快速搭建webservice项目的功能,虽然是很方便,但很多情况下都是在已有的项目中引用webservice,那么快速搭建项目的功能就显得不够灵活。这里就省略不说了。

    好了,我们看看怎么用JWS搭建webservice服务端吧~

服务接口和服务接口实现类

    为了方便后续客户端的调用,这里采用面向接口编程。

import com.javatest.po.StudentScore;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;/*** webservice服务端接口类*/
@WebService
public interface JAXTestService {/**提供调用的方法,使用@WebMethod注释*/@WebMethod(operationName = "getStudentScoreById")StudentScore getStudentScore(@WebParam(name = "id") long id);
}

    创建对应的实现类。如果不采用面向接口编程,直接创建服务类也是可以的。

import com.javatest.po.StudentScore;
import com.javatest.service.StudentScoreService;
import com.javatest.webservice.server.JAXTestService;
import org.springframework.beans.factory.annotation.Autowired;
import javax.jws.WebService;
import javax.xml.ws.Endpoint;
​
/*** webservice服务端实现类。注意,如果使用面向接口,那么在此实现类中必须通过endpointInterface指定服务端接口类*/
@WebService(targetNamespace = "http://impl.server.webservice.javatest.com/",    // 命名空间一般为包名的倒置endpointInterface = "com.javatest.webservice.server.JAXTestService"
)
@Service
public class JAXTestServiceImpl implements JAXTestService {@Autowiredprivate StudentScoreService service;@Overridepublic StudentScore getStudentScore(long id) {return service.selectByPrimaryKey(id);}// 发布服务public static void main(String[] args) {// 指定服务urlString url = "http://localhost:9010/javatest/webservice/getJAX";// 指定服务实现类JAXTestService server = new JAXTestServiceImpl();// 通过Endpoint发布服务Endpoint.publish(url, server);}
}

    执行main方法就可以发布webservice了。在浏览器中输入http://localhost:9010/javatest/webservice/getJAX?wsdl,如果返回下图,则说明服务发布成功。
在这里插入图片描述
    这里要注意哦:wsdl文档在执行发布服务的方法后就已经确定,后续手动修改wsdl文档是无法生效的,需要重新发布。

不完美的优化

    上述的部署的方式有个弊端,一旦springboot项目部署,这个main方法就无法手动执行了,自然webservice的服务端就无法启动。首先想到的是在启动类上添加webservice,或者在开启服务的同时也开启webservice。但这样会存在端口冲突的问题。在不使用其他技术的前提下,找了很久也没有找到共用端口的方法。当然,用cxf的Springbus就能解决这个问题,这个在后面会讲述。
    注意:下面两种方式api接口和webservice不能共用同一个端口,相当于同时开启两个服务。

方法1:直接在启动类上开启webservice服务

    注意:SpringApplication.run必须写在webservice服务上面

@SpringBootApplication
@MapperScan("com.javatest.dao")
@ServletComponentScan
public class JavaTestApplication {public static void main(String[] args) {SpringApplication.run(JavaTestApplication.class);// 指定服务url,注意,配置的api接口的端口号与webservice接口的端口号不能一致String url = "http://localhost:9011/javatest/webservice/getJAX";// 指定服务实现类JAXTestService server = new JAXTestServiceImpl();// 通过Endpoint发布服务Endpoint.publish(url, server);}
}

方法2:使用ApplicationContext事件机制。

    创建一个ApplicationListener的子类,配置webservice服务。
    注意:使用该方法时,webservice的实现类可以用@Service注解。而前述的ApplicationListener子类则必须用@Service,@Component或者@Configuration注解,以便交给Spring容器管理

import com.javatest.webservice.server.impl.JAXTestServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.ContextRefreshedEvent;
import javax.xml.ws.Endpoint;@Configuration
public class WebServiceApplication implements ApplicationListener<ContextRefreshedEvent> {private static Logger log = LoggerFactory.getLogger(WebServiceApplication.class);private String wsdlUrl = "http://localhost:9011/javatest/webservice/getJAX";@Overridepublic void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {Endpoint.publish(wsdlUrl,new JAXTestServiceImpl());log.info("webservice服务启动成功,wsdl地址:" + wsdlUrl + "?wsdl");}
}

     此时执行springboot的启动类,就能同时部署两个项目(springboot的项目和webservice项目)。上例中,9010提供常规的api接口,9011则提供webservice接口。

利用cxf消息总线发布

     如果想将api接口和webservice接口都用同一个端口对外发布,除了使用nginx反向代理之外,也可以使用cxf的bus。此时需要引入cxf的依赖和增加一个配置类:

    依赖:

<!--cxf依赖-->
<dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-spring-boot-starter-jaxws</artifactId><version>3.2.4</version>
</dependency>

     配置类:

import org.apache.cxf.Bus;
import org.apache.cxf.bus.spring.SpringBus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.xml.ws.Endpoint;/**使用cxf发布webservice服务,实现同一端口同时提供API和webservice*/
@Configuration
public class WebServiceConfig implements WebMvcConfigurer {// 新增消息总线@Bean(name = Bus.DEFAULT_BUS_ID)public SpringBus springBus() {return new SpringBus();}// 注入webservice实现类的bean@Beanpublic JAXTestServiceImpl JAXTestService() {return new JAXTestServiceImpl();}// 创建一个endpoint@Beanpublic Endpoint endpointForResources() {EndpointImpl endpoint = new EndpointImpl(springBus(), JAXTestService());endpoint.publish("/getJAX");return endpoint;}
}

     在application.yml中添加cxf路径

cxf:path: /webservice

    运行启动类就能同时提供api和webservice接口了~~

    此时webservice的wsdl文档路径为:http://localhost:9010/javatest/webservice/getJAX?wsdl,即项目路径+cxf路径+endpoint指定的路径

     注意:如果项目引用了cxf的技术,那么就无法使用方法1和方法2的方式,否则可能会出现“Cannot find any registered HttpDestinationFactory from the Bus”的报错。但既然都引用了cxf,倒不如直接用cxf发布。

搭建webservice客户端

     如果不用axis和cxf的话,常用的客户端搭建方式有wsimport、jdk的api和URLConnection/ajax。

wsimport方式搭建Client

    为了测试方便,新建一个springboot项目用于创建客户端,创建方式略。
    注意:在生成服务端相关文件时,服务端需要在已启动的状态,否则将无法通过wsdl从服务端中获取相应文件!
     使用wsimport也有两种方式:

方式1:调用cmd输入命令生成代码

     输入以下命令执行,就可以生成服务端相应的配置和接口文件,将生成的文件放置在客户端相应的文件夹中即可。后面的地址就是服务端的wsdl文档路径。注意:-s和wsdl文档路径之间的点不可省略!!

wsimport -s . http://localhost:9010/javatest/webservice/getJAX?wsdl

     但在实际操作中发现,这样输入命令会容易出现导包的错误。

方式2:程序生成代码

     以idea为例。
在这里插入图片描述
在这里插入图片描述
     选择ok就会自动下载和生成代码了。

客户端调用类

     创建一个controller,对外提供api

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/wsimport")
public class WsImportController {@PostMapping("/getStudentScoreById")public StudentScore getStudentScoreById(long id) {JAXTestServiceImplService implService = new JAXTestServiceImplService();JAXTestService jaxTestService = implService.getJAXTestServiceImplPort();return jaxTestService.getStudentScoreById(id);}
}

     启动客户端发送请求,成功调用webservice。
     小优化:如果服务端方法较多,JAXTestServiceImplService的创建代码是冗余的,可以将其交给Spring容器管理,再注入到controller中。

使用WebService相关API创建Client

     利用Jdk提供的api创建Client,也是需要先用wsimport命令生成代码,但是只需要其中的一些类即可:服务接口类、参数类或返回值类等等。在本示例中,因为方法的返回值是StudentScore类,所以需要的类为JAXTestService接口和StudentScore类。

在这里插入图片描述
     当然,这两个类也可以手写,如果很熟悉的话:-),不过还是强烈建议用程序/指令生成。

生成的service接口的调整

     生成的类放到自定义的位置后,生成的接口(在本例中为JAXTestService)还需要做一定的处理才能使用。首先是ObjectFactory.class是没有用到的,所以对应的注解要注释掉。另外也要将接口中的classname调整为当前的路径,否则会出现类转换出错的错误。
在这里插入图片描述
     修改后的类的代码如下

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;@WebService(name = "JAXTestService", targetNamespace = "http://server.webservice.javatest.com/")
//@XmlSeeAlso({
//    ObjectFactory.class
//})
public interface JAXTestService {/*** @param id* @return*     returns com.javaWebserviceClient.api.StudentScore*/@WebMethod@WebResult(targetNamespace = "")@RequestWrapper(localName = "getStudentScoreById", targetNamespace = "http://server.webservice.javatest.com/", className = "com.javaWebserviceClient.api.GetStudentScoreById")@ResponseWrapper(localName = "getStudentScoreByIdResponse", targetNamespace = "http://server.webservice.javatest.com/", className = "com.javaWebserviceClient.api.GetStudentScoreByIdResponse")public StudentScore getStudentScoreById(@WebParam(name = "id", targetNamespace = "")long id);
}

客户端调用类

     下述的调用类使用了QName来指定wsdl文档中的元素。

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import java.net.URL;@RestController
@RequestMapping("/api")
public class ApiController {@PostMapping("/getStudentScoreById")public StudentScore getStudentScoreById(long id) throws Exception {URL url = new URL("http://localhost:9010/javatest/webservice/getJAX?wsdl");// 指定命名空间和服务名称// 其中targetNamespace和name可在wdsl文档的<wsdl:definitions>标签中找到QName qName = new QName("http://impl.server.webservice.javatest.com/","JAXTestServiceImplService");// 创建对应的服务Service service = Service.create(url,qName);JAXTestService jaxTestService = service.getPort(JAXTestService.class);return jaxTestService.getStudentScoreById(id);}
}

     启动客户端发送请求,成功调用webservice。

使用URLConnection/Ajax方式创建Client

     URLConnection和Ajax的实现原理是基本一致的,通过模拟soap请求进行webservice调用,只是一个是后台,一个是前端页面。webservice本身也就是走soap协议,所以用urlconnection和ajax显得更底层一些。而使用的关键就是构造soap请求。

URLConnection方式

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;@RestController
@RequestMapping("/url")
public class URLConnectionController {@PostMapping("/getStudentScoreById")public String getStudentScoreById(long id) throws Exception {URL wsUrl = new URL("http://localhost:9010/javatest/webservice/getJAX?wsdl");HttpURLConnection conn = (HttpURLConnection) wsUrl.openConnection();conn.setDoInput(true);conn.setDoOutput(true);conn.setRequestMethod("POST");conn.setRequestProperty("Content-Type", "text/xml;charset=UTF-8");
​OutputStream os = conn.getOutputStream();//请求体String soap = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" " +"xmlns:webs=\"http://server.webservice.javatest.com/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " +"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"+ "<soapenv:Body><webs:getStudentScoreById><id>" + id + "</id></webs:getStudentScoreById></soapenv:Body></soapenv:Envelope>";
​os.write(soap.getBytes());InputStream is = conn.getInputStream();byte[] b = new byte[1024];int len = 0;StringBuilder sb = new StringBuilder();while ((len = is.read(b)) != -1) {String s = new String(b, 0, len, "UTF-8");sb.append(s);}is.close();os.close();conn.disconnect();return sb.toString();}
}

     这里解释一下soap请求如何构建:

     整个soap的内容有一半是固定搭配,不同的有以下几点:

  1. xmlns:webs :后面的webs是自定义的字符串,不是固定的词,其值就是wsdl文档中的namespace,用于指代webservice服务器。

  2. <webs:getStudentScoreById>:webs的含义同上,也就是指webservice服务器。getStudentScoreById也就是要调用的方法名。

  3. <id>" + id + "</id> :这里是为方法的入参赋值。注意标签也不是固定的词!这个在wsdl文档可能会找不到,需要在服务端的接口所定义的方法中找
    在这里插入图片描述
         假如参数没有用@WebParam来指定名称,则默认为arg0、arg1依次到argn(假如方法有n+1个参数)

     调用之后的返回值如下,也是一个soap。

在这里插入图片描述

ajax调用

![在这里插入图片描述](https://img-blog.csdnimg.cn/2020070312503891.png)类似URLConnection,这里贴上其中一个写法:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>ajax调用webservice</title><style type="text/css"></style><script type="text/javascript">var xhr;if (window.XMLHttpRequest) {xhr = new XMLHttpRequest();} else {xhr = new ActiveXObject("Microsoft.XMLHttp");}function sendMsg() {var id = document.getElementById("id");//服务的地址var wsUrl = 'http://localhost:9010/javatest/webservice/getJAX?wsdl';//请求体var soap = '<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:webs=\"http://server.webservice.javatest.com/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><soapenv:Body><webs:getStudentScoreById><id>' + id + '</id></webs:getStudentScoreById></soapenv:Body></soapenv:Envelope>';//打开链接xhr.open('POST', wsUrl, true);//重新设置请求头xhr.setRequestHeader("Content-Type", "text/xml;charset=UTF-8");//设置回掉函数xhr.onreadystatechange = _back;//发送请求xhr.send(soap);}function _back(){if (xhr.readyState == 4) {if (xhr.status == 200) {alert("调用WebService成功了");var ret = xhr.responseXML;var msg = ret.getElementsByTagName('return')[0];document.getElementById("showInfo").innerHTML = msg.textContent;}}}
</script>
</head>
<body>
<input type="button" value="发送soap请求" onclick="sendMsg();"/>
<input type="text" id="id"/>
<div id="showInfo"></div>
</body>
</html>

    上面的写法是有跨域的问题,具体的解决方式这里就不详细探讨了。

    可以看出,URLConnection和ajax方式调用并不是特别方便。

    相似的还有使用httpClient,原理也是发送soap请求,只是发送请求的方式不同而已。

总结

    wsimport是最简便的搭建方式,但缺点是提供的接口越多,下载到本地的文件就越多。一旦业务逻辑调整,wsdl文档更新,那么就要执行wsimport指令重新下载,管理相对麻烦一些。
    jdk提供的api是相对方便的搭建方式,虽然也要用wsimport下载文件,但是保留的文件却比较少。所以相对的,业务逻辑调整时,要修改的文件会较少,甚至不用修改。
    URLConnection和ajax方式个人觉得不太方便,不太建议。最主要是soap请求构建比较麻烦,即便在一些插件的帮助下生成soap请求,写起来也是比较麻烦的。


http://chatgpt.dhexx.cn/article/Hn01ZCSL.shtml

相关文章

WebService 理论详解、JWS(Java Web Service) 快速入门

目录 WebService (web服务)概述 WebService 平台技术 WebService 工作原理 WebService 开发流程 常见 Web Service 框架 JWS(Java Web Service) 概述 JWS(Java Web Service) 快速入门 WebService (web服务)概述 1、WebService&#xff08;Web服务&#xff09;是一种跨语…

一文理解 JWT、JWS、JWE、JWA、JWK、JOSE

原文收录 GitBook——统一接口认证解决方案 JsonWebToken 关于JsonWebToken的专业名词解释&#xff1a; unsecured JWT&#xff1a;默认头部{“alg”: “none”}的jwt令牌JWS(SignedJWT)&#xff1a;已签名的jwt,包含标准jwt结构&#xff1a;header、payload、signatureJWE…

JWS入门

JWS简介 JWS主要用来通过网络部署你的应用程序&#xff0c;它具有安全、稳定、易维护、易使用的特点。用户访问用JWS部署应用程序的站点&#xff0c;下载发布的应用程序&#xff0c;既可以在 线运行&#xff0c;也可以通过JWS的客户端离线运行已下载的应用程序。对同一个应用程…

【C语言】判断一个数是否是完全平方数(两种解法)

题目&#xff1a; 判断一个数是否是完全平方数。 以下数字为完全平方数&#xff1a;42*2,93*3,14412*12,16913*13 有两个方法&#xff0c;可以求完全平方数&#xff1a; 方法一&#xff1a;输入一个数&#xff0c;遍历所有比这个数小的数&#xff0c;只要有其中一个数满足条件…

C语言 输入10个数,将其中最小的数与第一个数对换,将最大的数与最后一个数对换

#include <stdio.h> void input(int *number){ //定义输入10个数的函数int i;printf("请输入10个整数:\n");for(i0;i<10;i)scanf("%d",&number[i]); } void max_min_value(int *number){ //交换函数int *max,*min,*p,temp;maxminnumber; //开…

C语言判断一个数是奇数还是偶数

#include <stdio.h> void main() { int n; scanf("%d",&n); //运用scanf函数可以输入想要的数字 //也可以采用int n&#xff08;取一个数&#xff09;进行运算 if(n%20)//if函数注意&#xff0c;%是取余 printf("%d是一个偶…

python判断三位数水仙花数_Python如何判断一个数字是否为水仙花数

水仙花数是一个三位数,并且每一位数字的三次方的和还等于这个数字。 下面我们来看一下如何用Python判断这个数字是否为水仙花数 工具/原料 电脑 Python开发工具 方法/步骤 1 创建一个变量s,用input代码和用户交互,代码如下: s = input("请输入一个数字:"…

c语言判断一个数是否是素数

1&#xff1a;什么是素数 素数就是一个数只能被1和他本身整除的数我们称之为素数。例如13&#xff0c;17&#xff0c;19一类的数。 2&#xff1a;求出一个数是否是素数的思路 素数是只能被1和本身整除的数&#xff0c;那么如果设这个数为n&#xff0c;那么它就不能被2~n-1整…

python用函数判断一个数是否为素数,python分享是否为素数 python输入并判断一个数是否为素数...

python输入并判断一个数是否为素数 x=int(input("x\n")); i=2; for i in range(2,x+1): if(x%i==0): break;if(i==x and i。 用python 判断一个数是否是素数 小编觉得小编的程序是对的但为什么没办法运行,那个弹出来的窗口是啥意思小编曾千万次的请分享:不要逼小编…

python中判断一个数是否为素数_怎么用python判断一个数是否是素数

先来看下什么是质数&#xff1a; 质数(Prime number)&#xff0c;又称素数&#xff0c;指在大于1的自然数中&#xff0c;除了1和该数自身外&#xff0c;无法被其他自然数整除的数(也可定义为只有1与该数本身两个因数的数)。 简单来说就是&#xff0c;只能除以1和自身的数(需要大…

取到一个数的各个位的方法

计算方式如下&#xff1a; 个位&#xff1a;用这个数除以1对10取余&#xff0c;num / 1 % 10; 因为1除以&#xff08;除了0以外&#xff09;任何数都等于这个数的倒数&#xff0c;所以计算个位可以直接对10取余&#xff08;num%10&#xff09; 来获得。 十位&#xff1a;除以…

得到一个数每一位数字的几种方法

1.&#xff08;最简单暴力&#xff09;直接将数字转换为字符串&#xff0c;然后转换为字符数组输出。 int n12345;char[] charsString.valueOf(n).toCharArray();for(int j0;j<chars.length;j){System.out.print(chars[j]" ");}2.整除法。 int n12345;List<Int…

Html5超链接重置为link状态,去除a标签下划线 html超链接更改颜色和去掉下划线

去掉a标签下划线&#xff1a; 对超链接下划线设置 使用代码"text-decoration" 语法&#xff1a; text-decoration : none || underline || blink || overline || line-through text-decoration参数&#xff1a; none : 无装饰 blink : 闪烁 underline : 下划线 line-…

html5 a标签去下划线,css中如何去掉a标签的下划线?

我们在HTML网页制作过程中&#xff0c;相信大家对css文本超链接这个概念并不陌生。我们都知道想要给某段文本或者指定元素添加一个锚点也就是超链接需要用到HTML中的a标签。 那么有的新手可能就会发现&#xff0c;在使用a标签时文本超链接会自动出现下划线&#xff01;从视觉美…

css中怎么消除a的下划线,如何使用css去掉a标签的下划线?(代码详解)

写html超链接的时候&#xff0c;超链接总是自带下划线&#xff0c;如果不需要下划线&#xff0c;我们需要将其去掉&#xff0c;下面我们就来说一下怎么去掉下划线。 我们在使用超链接的时候&#xff0c;下划线总是伴随着出现&#xff0c;从视觉上来说有着下划线的a标签总是感觉…

MySQL数据库常用命令

活动地址&#xff1a;CSDN21天学习挑战赛 1.对数据库常用命令 1.连接数据库 mysql -u用户名 -p密码 2.显示已有数据库 show databases; 3.创建数据库 create database sqlname; 4.选择数据库 use database sqlname; 5.显示数据库中的表&#xff08;先选择数据库&#xff09; sh…

mysql命令更新数据库_命令操作MySQL数据库

一、连接MYSQL 格式: mysql -h主机地址 -u用户名 -p用户密码 1、 连接到本机上的MYSQL。 首先打开DOS窗口,然后进入目录mysql\bin,再键入命令mysql -u root -p,回车后提示你输密码.注意用户名前可以有空格也可以没有空格,但是密码前必须没有空格,否则让你重新输入密码. 如…

微信小程序小说阅读器/在线故事阅读丨可以android studio运行

《微信小程序小说阅读器后台管理系统|前后分离VUE》该项目含有源码、论文等资料、配套开发软件、软件安装教程、项目发布教程等 本系统包含微信小程序前台和Java做的后台管理系统&#xff0c;该后台采用前后台前后分离的形式使用JavaVUE 微信小程序——前台涉及技术&#xff1a…

微信读书护眼版

微信读书是我目前发现的比较好用的读书平台之一&#xff0c;电子书资源丰富&#xff0c;界面风格还挺舒服&#xff0c;支持app和网页版&#xff0c;唯一难受的就是网页版的背景显示方案太少了&#xff0c;只能切换浅色和深色两种&#xff0c;上班想摸鱼看会书&#xff0c;直刺得…

微信读书产品体验报告

微信读书【5.0.5】产品体验报告 本文预览 微信读书凭借着简洁的风格、丰富的电子版权以及良好的推书、读书的阅读氛围获得了一大批粉丝&#xff0c;在现今短视频类应用占据用户大量时间的今天&#xff0c;为何微信读书像一股清流抓住了用户注意力&#xff0c;它又是怎么去实现…