以前在網上有看一篇文章,以爲場景描述的很切合實際,就是dubbo常常是內部協做提供服務用的,可是若是涉及到對外服務調用,更多仍是提供http,這樣就必須實現服務轉換爲http調用,這篇文章設計仍是很巧妙,利用了spring mvc的特性。css
文章的出處:http://blog.csdn.net/qq_18661793/article/details/71156210html
在這咱們根據實際的使用,對它進行更進一步的調整,先配置pom.xmljava
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.crossoverJie</groupId> <artifactId>dubbo-http</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>dubbo-http Maven Webapp</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <build> <resources> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> <include>**/*.ini</include> </includes> <filtering>false</filtering> </resource> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> </resources> </build> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.7</version> <scope>test</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jsp-api</artifactId> <version>2.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-juli</artifactId> <version>7.0.27</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient-cache</artifactId> <version>4.2.5</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpmime</artifactId> <version>4.2.5</version> </dependency> <!-- Spring 在 3.2.13版本後,要單獨引用 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.2.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>4.2.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.2.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>4.2.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.2.5.RELEASE</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.18</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.7.1</version> </dependency> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>1.9.11</version> </dependency> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.16</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.1.26</version> </dependency> <!-- 其餘經常使用包 begin --> <dependency> <groupId>commons-attributes</groupId> <artifactId>commons-attributes-api</artifactId> <version>2.1</version> </dependency> <dependency> <groupId>commons-attributes</groupId> <artifactId>commons-attributes-compiler</artifactId> <version>2.1</version> </dependency> <dependency> <groupId>ant</groupId> <artifactId>ant</artifactId> <version>1.6.5</version> </dependency> <dependency> <groupId>commons-beanutils</groupId> <artifactId>commons-beanutils-core</artifactId> <version>1.8.0</version> </dependency> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.10</version> </dependency> <dependency> <groupId>commons-collections</groupId> <artifactId>commons-collections</artifactId> <version>3.2.2</version> </dependency> <dependency> <groupId>commons-dbcp</groupId> <artifactId>commons-dbcp</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>commons-httpclient</groupId> <artifactId>commons-httpclient</artifactId> <version>3.1</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.4</version> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.6</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.1.3</version> </dependency> <dependency> <groupId>commons-pool</groupId> <artifactId>commons-pool</artifactId> <version>1.6</version> </dependency> <dependency> <groupId>net.sf.ezmorph</groupId> <artifactId>ezmorph</artifactId> <version>1.0.6</version> </dependency> <!-- 其餘經常使用包 end' --> <dependency> <groupId>org.javassist</groupId> <artifactId>javassist</artifactId> <version>3.21.0-GA</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.8.5.1</version> <exclusions> <exclusion> <artifactId>spring</artifactId> <groupId>org.springframework</groupId> </exclusion> </exclusions> </dependency> <!-- redis begin --> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.8.0</version> </dependency> <!-- redis end --> <!-- /Spring 升級4+ 依賴的JSON包 --> <dependency> <groupId>com.google.inject</groupId> <artifactId>guice</artifactId> <version>4.1.0</version> </dependency> <dependency> <groupId>com.netflix.curator</groupId> <artifactId>curator-framework</artifactId> <version>1.1.10</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>2.5.0</version> </dependency> </dependencies> </project>
spring 相關的配置以下下圖:web
dubbo的xml配置以下:spring-dubbo-config.xml的內容:redis
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <dubbo:application name="ssm-service" /> <dubbo:registry id="dubbo-registry" address="zookeeper://192.168.43.33:2181" username="srp" password="srp" client="curator" file="/tmp/dubbo.cachr" /> <dubbo:monitor protocol="registry" /> <dubbo:protocol name="dubbo" port="20884" /> </beans>
spring-dubbo-provider.xml的內容:spring
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <bean id="userFacade" class="com.crossoverJie.api.impl.DemoApiImpl" /> <dubbo:service interface="com.crossoverJie.api.DemoApi" ref="userFacade" /> </beans>
spring-mvc的內容:數據庫
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 採用註釋的方式配置bean --> <context:annotation-config /> <!-- 配置要掃描的包 --> <context:component-scan base-package="com.crossoverJie" /> <!--dubbo服務暴露爲http服務--> <bean class="com.crossoverJie.dubbo.http.conf.HttpProviderConf"> <property name="usePackage"> <list> <!--須要暴露服務的接口包名,可多個--> <value>com.crossoverJie.api</value> </list> </property> </bean> <!--處理靜態資源--> <mvc:default-servlet-handler /> <mvc:annotation-driven/> <!-- 定義跳轉的文件的先後綴 ,視圖模式配置--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 這裏的配置個人理解是自動給後面action的方法return的字符串加上前綴和後綴,變成一個 可用的url地址 --> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> </beans>
下面截圖這塊的內容實際使用中能夠改成從數據庫獲取服務名的方式,apache
com.crossoverJie.api和spring-dubbo-provider種的「com.crossoverJie.api.DemoApi」是有對應關係的。json
java代碼中,有一個核心控制http請求的control類,我對其進行了改寫,能更適應多參數的post請求,即把請求的參數都放入map中相似一個表單的請求。api
package com.crossoverJie.api.controller; import com.alibaba.fastjson.JSON; import com.crossoverJie.dubbo.http.conf.HttpProviderConf; import com.crossoverJie.dubbo.http.req.HttpRequest; import com.crossoverJie.dubbo.http.rsp.HttpResponse; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeansException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Controller; import org.springframework.util.CollectionUtils; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import java.lang.reflect.Field; @Controller @RequestMapping({"/dubboapi"}) public class DubboController implements ApplicationContextAware { private static final Logger logger = LoggerFactory.getLogger(DubboController.class); @Autowired private HttpProviderConf httpProviderConf; private final Map<String, Class<?>> cacheMap = new HashMap(); protected ApplicationContext applicationContext; @ResponseBody @RequestMapping(value={"/{service}/{method}"}, method={org.springframework.web.bind.annotation.RequestMethod.POST}) public String api(HttpRequest httpRequest, HttpServletRequest request, @RequestParam Map<String,String> map,@PathVariable String service, @PathVariable String method) { logger.debug("ip:{}-httpRequest:{}", getIP(request), JSON.toJSONString(httpRequest)); String invoke = invoke(httpRequest, service, method,map); logger.debug("callback :" + invoke); return invoke; } private String invoke(HttpRequest httpRequest, String service, String method,Map<String,String> map) { httpRequest.setService(service); httpRequest.setMethod(method); HttpResponse response = new HttpResponse(); logger.debug("input param:" + JSON.toJSONString(httpRequest)); if (!CollectionUtils.isEmpty(httpProviderConf.getUsePackage())) { boolean isPac = false; for (String pac : httpProviderConf.getUsePackage()) { if (service.startsWith(pac)) { isPac = true; break; } } if (!isPac) { logger.error("service is not correct,service=" + service); response.setCode("2"); response.setSuccess(false); response.setDescription("service is not correct,service=" + service); } } try { Class<?> serviceCla = (Class)cacheMap.get(service); if (serviceCla == null) { serviceCla = Class.forName(service); logger.debug("serviceCla:" + JSON.toJSONString(serviceCla)); cacheMap.put(service, serviceCla); } Method[] methods = serviceCla.getMethods(); Method targetMethod = null; for (Method m : methods) { if (m.getName().equals(method)) { targetMethod = m; break; } } if (method == null) { logger.error("method is not correct,method=" + method); response.setCode("2"); response.setSuccess(false); response.setDescription("method is not correct,method=" + method); } Object bean = applicationContext.getBean(serviceCla); Object result = null; Class<?>[] parameterTypes = targetMethod.getParameterTypes(); if (parameterTypes.length == 0) { result = targetMethod.invoke(bean, new Object[0]); } /*else if (parameterTypes.length == 1) { Object json = JSON.parseObject(httpRequest.getParam(), parameterTypes[0]); result = targetMethod.invoke(bean, new Object[] { json }); } */else { result = targetMethod.invoke(bean, map); logger.info("Can have map parameter"); response.setSuccess(true); response.setCode("1"); response.setDescription("Can only have one parameter"); } return JSON.toJSONString(result); } catch (ClassNotFoundException e) { logger.error("class not found", e); response.setSuccess(false); response.setCode("2"); response.setDescription("class not found"); } catch (InvocationTargetException e) { logger.error("InvocationTargetException", e); response.setSuccess(false); response.setCode("2"); response.setDescription("InvocationTargetException"); } catch (IllegalAccessException e) { logger.error("IllegalAccessException", e); response.setSuccess(false); response.setCode("2"); response.setDescription("IllegalAccessException"); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } return JSON.toJSONString(response); } private String getIP(HttpServletRequest request) { if (request == null) return null; String s = request.getHeader("X-Forwarded-For"); if ((s == null) || (s.length() == 0) || ("unknown".equalsIgnoreCase(s))) { s = request.getHeader("Proxy-Client-IP"); } if ((s == null) || (s.length() == 0) || ("unknown".equalsIgnoreCase(s))) { s = request.getHeader("WL-Proxy-Client-IP"); } if ((s == null) || (s.length() == 0) || ("unknown".equalsIgnoreCase(s))) { s = request.getHeader("HTTP_CLIENT_IP"); } if ((s == null) || (s.length() == 0) || ("unknown".equalsIgnoreCase(s))) { s = request.getHeader("HTTP_X_FORWARDED_FOR"); } if ((s == null) || (s.length() == 0) || ("unknown".equalsIgnoreCase(s))) { s = request.getRemoteAddr(); } if (("127.0.0.1".equals(s)) || ("0:0:0:0:0:0:0:1".equals(s))) try { s = InetAddress.getLocalHost().getHostAddress(); } catch (UnknownHostException unknownhostexception) { return ""; } return s; } public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } }
被這個control類引用的還有:
package com.crossoverJie.dubbo.http.conf; import java.util.List; public class HttpProviderConf { private List<String> usePackage; public List<String> getUsePackage() { return usePackage; } public void setUsePackage(List<String> usePackage) { this.usePackage = usePackage; } }
上面這個類跟相對應,我的以爲使用意義不是太大。
package com.crossoverJie.dubbo.http.req; public class HttpRequest { private String param; private String service; private String method; public String getParam() { return param; } public void setParam(String param) { this.param = param; } public String getService() { return service; } public void setService(String service) { this.service = service; } public String getMethod() { return method; } public void setMethod(String method) { this.method = method; } }
package com.crossoverJie.dubbo.http.rsp; import java.io.Serializable; public class HttpResponse implements Serializable { private static final long serialVersionUID = -552828440320737814L; private boolean success; private String code; private String description; public boolean isSuccess() { return success; } public void setSuccess(boolean success) { this.success = success; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } }
接下來咱們寫一下測試相關類:
package com.crossoverJie.api.impl; import java.util.Map; import com.alibaba.dubbo.config.annotation.Service; import com.alibaba.fastjson.JSON; import com.crossoverJie.api.DemoApi; /** * Function: * @author chenjiec * Date: 2017/3/1 下午11:42 * @since JDK 1.7 */ @Service public class DemoApiImpl implements DemoApi { /** * 獲取用戶信息 * * @param userId * @return * @throws RuntimeException */ public String readMsg(Map<String,String> arg) throws RuntimeException { String json_str=JSON.toJSONString(arg); return json_str; } }
package com.crossoverJie.api; import java.util.Map; public interface DemoApi { String readMsg(Map<String,String> arg)throws RuntimeException; }
以上是服務器接口相關類
http請求工具類
package com.crossoverJie.dto; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.URL; import java.util.Map; import java.util.Map.Entry; public class HttpUtil { public static String http(String url, Map<String, String> params) { URL u = null; HttpURLConnection con = null; // 構建請求參數 StringBuffer sb = new StringBuffer(); if (params != null) { for (Entry<String, String> e : params.entrySet()) { sb.append(e.getKey()); sb.append("="); sb.append(e.getValue()); sb.append("&"); } sb.substring(0, sb.length() - 1); } System.out.println("send_url:" + url); System.out.println("send_data:" + sb.toString()); // 嘗試發送請求 try { u = new URL(url); con = (HttpURLConnection) u.openConnection(); //// POST 只能爲大寫,嚴格限制,post會不識別 con.setRequestMethod("POST"); con.setDoOutput(true); con.setDoInput(true); con.setUseCaches(false); con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); OutputStreamWriter osw = new OutputStreamWriter(con.getOutputStream(), "UTF-8"); osw.write(sb.toString()); osw.flush(); osw.close(); } catch (Exception e) { e.printStackTrace(); } finally { if (con != null) { con.disconnect(); } } // 讀取返回內容 StringBuffer buffer = new StringBuffer(); try { //必定要有返回值,不然沒法把請求發送給server端。 BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "UTF-8")); String temp; while ((temp = br.readLine()) != null) { buffer.append(temp); buffer.append("\n"); } } catch (Exception e) { e.printStackTrace(); } return buffer.toString(); } }
http請求調用類
package com.crossoverJie.api.controller; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.URL; import java.net.URLConnection; import java.util.HashMap; import java.util.List; import java.util.Map; import com.crossoverJie.dto.HttpUtil; public class HttpRequestTest { /** * 向指定URL發送GET方法的請求 * * @param url * 發送請求的URL * @param param * 請求參數,請求參數應該是 name1=value1&name2=value2 的形式。 * @return URL 所表明遠程資源的響應結果 */ public static String sendGet(String url, String param) { String result = ""; BufferedReader in = null; try { String urlNameString = url + "?" + param; URL realUrl = new URL(urlNameString); // 打開和URL之間的鏈接 URLConnection connection = realUrl.openConnection(); // 設置通用的請求屬性 connection.setRequestProperty("accept", "*/*"); connection.setRequestProperty("connection", "Keep-Alive"); connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); // 創建實際的鏈接 connection.connect(); // 獲取全部響應頭字段 Map<String, List<String>> map = connection.getHeaderFields(); // 遍歷全部的響應頭字段 for (String key : map.keySet()) { System.out.println(key + "--->" + map.get(key)); } // 定義 BufferedReader輸入流來讀取URL的響應 in = new BufferedReader(new InputStreamReader( connection.getInputStream())); String line; while ((line = in.readLine()) != null) { result += line; } } catch (Exception e) { System.out.println("發送GET請求出現異常!" + e); e.printStackTrace(); } // 使用finally塊來關閉輸入流 finally { try { if (in != null) { in.close(); } } catch (Exception e2) { e2.printStackTrace(); } } return result; } /** * 向指定 URL 發送POST方法的請求 * * @param url * 發送請求的 URL * @param param * 請求參數,請求參數應該是 name1=value1&name2=value2 的形式。 * @return 所表明遠程資源的響應結果 */ public static String sendPost(String url, String param) { PrintWriter out = null; BufferedReader in = null; String result = ""; try { URL realUrl = new URL(url); // 打開和URL之間的鏈接 URLConnection conn = realUrl.openConnection(); // 設置通用的請求屬性 conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); // 發送POST請求必須設置以下兩行 conn.setDoOutput(true); conn.setDoInput(true); // 獲取URLConnection對象對應的輸出流 out = new PrintWriter(conn.getOutputStream()); // 發送請求參數 out.print(param); // flush輸出流的緩衝 out.flush(); // 定義BufferedReader輸入流來讀取URL的響應 in = new BufferedReader( new InputStreamReader(conn.getInputStream())); String line; while ((line = in.readLine()) != null) { result += line; } } catch (Exception e) { System.out.println("發送 POST 請求出現異常!"+e); e.printStackTrace(); } //使用finally塊來關閉輸出流、輸入流 finally{ try{ if(out!=null){ out.close(); } if(in!=null){ in.close(); } } catch(IOException ex){ ex.printStackTrace(); } } return result; } public void testMaprequest() { Map parames = new HashMap<String, String>(); parames.put("num", "456"); parames.put("id", "123"); parames.put("name", "srp"); // 若是地址欄中有aaa這個參數,則默認選擇地址欄的,若是沒有則選擇添加的參數 parames.put("userid", "aaa_value"); String sr=HttpUtil.http("http://localhost:8080/dubbo-http/dubboapi/com.crossoverJie.api.DemoApi/readMsg", parames); System.out.println(sr); } public static void main(String[] args) { HttpRequestTest rs =new HttpRequestTest(); rs.testMaprequest(); } }
上面代碼中:http://localhost:8080/dubbo-http/dubboapi/com.crossoverJie.api.DemoApi/readMsg
dubbo-http是我取的項目名稱,dubboapi就是對於上面那個control類的註解內容,com.crossoverJie.api.DemoApi對於接口服務,readMsg對應類中被調用的方法,parames是一個map參數。在實際使用中應該還要有證書之類的,保證接口被調用的安全性。
最後看下web.xml的內容配置:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <display-name>Archetype Created Web Application</display-name> <welcome-file-list> <welcome-file>turnToIndex.jsp</welcome-file> </welcome-file-list> <!-- Spring和mybatis的配置文件 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:spring/*.xml</param-value> </context-param> <!-- 編碼過濾器 --> <filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <async-supported>true</async-supported> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- Spring監聽器 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 防止Spring內存溢出監聽器 --> <listener> <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class> </listener> <!-- Spring MVC servlet --> <servlet> <servlet-name>SpringMVC</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> <async-supported>true</async-supported> </servlet> <servlet-mapping> <servlet-name>SpringMVC</servlet-name> <!-- 此處能夠能夠配置成*.do,對應struts的後綴習慣 /表示攔截全部請求 --> <url-pattern>/</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <!-- 配置SESSION超時,單位是分鐘 --> <session-config> <session-timeout>30</session-timeout> </session-config> <!-- druid 監控 --> <filter> <filter-name>DruidWebStatFilter</filter-name> <filter-class>com.alibaba.druid.support.http.WebStatFilter</filter-class> <init-param> <param-name>exclusions</param-name> <param-value>*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*,/download/*</param-value> </init-param> </filter> <filter-mapping> <filter-name>DruidWebStatFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <servlet> <servlet-name>DruidStatView</servlet-name> <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class> <init-param> <!-- 用戶名 --> <param-name>loginUsername</param-name> <param-value>druid</param-value> </init-param> <init-param> <!-- 密碼 --> <param-name>loginPassword</param-name> <param-value>druid</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>DruidStatView</servlet-name> <url-pattern>/druid/*</url-pattern> </servlet-mapping> <!-- 確保靜態資源能夠被訪問 --> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.jpg</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.png</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.gif</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.js</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.css</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.swf</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.html</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.txt</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.ico</url-pattern> </servlet-mapping> <error-page> <error-code>404</error-code> <location>/notfound.jsp</location> </error-page> </web-app>
總體項目運行結果以下:
返回了一json 字符串