前言:
一直以來都對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!"; } }
后來我用百度的搜索地址在手動輸入中文關鍵字的情況下在各個瀏覽器中做實驗,發現都不會存在這樣的問題,如果正在瀏覽這篇文章的您知道其中的解決方法,還望不吝賜教。