前言:
一直以来都对WebService感兴趣,但因为难以理解WebService到底是什么,所以了解甚少。周二的时候有个跟我关系比较好的同事想要自己写个WebService的小Demo,希望能够做成在浏览器中输入类似:
http://localhost:8080/XXX/方法?属性=值
这样格式的连接,点击进入就可以在页面上得到想要的数据的效果。
我之前做的C#实现WebService是URL中带了.asmx的,同事用Java实现的传统WebService是后面带了wsdl的,都不是想要的格式。
对于这个问题我也很好奇,就在网上找了很多资料,终于在两天后写了个能够通过想要的那种URL格式访问的WebService。
正文:
1、Jersey是用来实现WebService的一种框架。进入Jersey官网(https://jersey.java.net/)下载需要用到的jar包
2、在MyEclipse中创建一个Web Project(我的项目名为JavaRestDemo)
3、将下载的jar包(我用的是jersey-bundle-1.19.jar)放入/JavaRestDemo/WebRoot/WEB-INF/lib/
4、创建包net.meng.main,并在其中创建类HelloWorld.java,代码如下:
package net.meng.main; import javax.servlet.http.HttpServletResponse; import javax.ws.rs.*; import javax.ws.rs.core.*; @Path("/helloworld") public class HelloWorld { @Context HttpServletResponse response; @GET @Produces(MediaType.TEXT_PLAIN) public String getResult(@QueryParam("name") String name){ return result(name); } @POST @Produces(MediaType.TEXT_PLAIN) public String postResult(@QueryParam("name") String name){ return result(name); } private String result(String name){ response.setCharacterEncoding("UTF-8"); // 解决变量name含有中文时出现的乱码问题 return "My name is " + name + ", Hello World!"; } }
5、修改WebRoot/WEB-INF/web.xml文件的内容为:
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <servlet> <servlet-name>helloworldservlet</servlet-name> <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> <init-param> <param-name>com.sun.jersey.config.property.packages</param-name> <param-value>net.meng.main</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>helloworldservlet</servlet-name> <url-pattern>/rest/*</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
6、部署到Tomcat并启动
7、在浏览器地址栏中输入http://localhost:8080/JavaRestDemo/rest/helloworld?name=聆道,就能看到页面显示如下:
(用的是猎豹浏览器,谷歌浏览器效果也一样)
至此,一个HelloWorld版Rest形式的WebService宣告完成。
后记:
其实这篇文章周四就可以发表的了,但后来我为了保险起见用火狐和IE测了一下,直接输入网址加后面的中文(关键字手打),回车后会显示乱码,就像这样:
(火狐,手动输入网址回车后)
(IE,手动输入网址回车后)
我把谷歌和火狐的地址栏链接复制出来作了对比,同样是“聆梦”两个字,结果却不同:
谷歌浏览器显示的地址栏链接:
http://localhost:8080/JavaRestDemo/rest/helloworld?name=%E8%81%86%E6%A2%A6
火狐浏览器显示的地址栏链接:
http://localhost:8080/JavaRestDemo/rest/helloworld?name=%F1%F6%C3%CE
然后通过站长工具的 把网址以UrlEncode编码/UrlDecode解码 进行解码,发现谷歌是用UTF-8编码的,火狐是用gb2312编码的,但因为是地址栏直接输入中文,传入服务器后服务器只能按固定的字符编码进行解码,这才导致结果差异。
为了让三个浏览器显示效果一致,我通过改变
response.setCharacterEncoding("gb2312");
和
name = new String(request.getParameter("name").getBytes("ISO-8859-1"),"gb2312");
取值的不同做了几组实验,起初是想试试看什么情况下能够让结果都是正常的,后来在UTF-8和gb2312间切换了好多次,都是猎豹和谷歌“站队”,IE和火狐“站队”,偶尔调皮的IE还会“搞特殊”。实验过程记录如下图:
其中“转”代表从别的页面跳转到结果页面的情况,“输”代表直接在地址栏输入中文关键字的情况。依次是猎豹、IE、火狐、谷歌。
看样子是都设为UTF-8的时候能保证比较多的情况是正常的,所以最终HelloWorld.java的代码如下:
package net.meng.main; import java.io.UnsupportedEncodingException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.ws.rs.*; import javax.ws.rs.core.*; @Path("/helloworld") public class HelloWorld { @Context HttpServletRequest request; @Context HttpServletResponse response; @GET @Produces(MediaType.TEXT_PLAIN) public String getResult(@QueryParam("name") String name){ return result(name); } @POST @Produces(MediaType.TEXT_PLAIN) public String postResult(@QueryParam("name") String name){ return result(name); } private String result(String name){ try { name = new String(request.getParameter("name").getBytes("ISO-8859-1"),"UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } response.setCharacterEncoding("UTF-8"); return "My name is " + name + ", Hello World!"; } }
后来我用百度的搜索地址在手动输入中文关键字的情况下在各个浏览器中做实验,发现都不会存在这样的问题,如果正在浏览这篇文章的您知道其中的解决方法,还望不吝赐教。