在B/S系统泛滥的今天,信息共享、系统集成,相信大家对这些名称肯定不会陌生,在企业大量分散的信息系统中怎样提供数据共享、将个系统集成到一起、从而提高工作效率,作为信息系统建设者们无疑都会想到提供web service,但作为初次体验者,对于很多概念肯定共有很多困惑,尤其是看到各个OpenAPI的不同提供方式时,更加疑惑,如google map api采用了AJAX方式,通过javascript提供API,而淘宝TOP则采用直接的HTTP+XML请求方式,最令人疑惑的是教材上讲的WSDL、UDDI从没有在这些API中出现过,如果你仔细查找资料了的话,在一些天气API中也还是有用到的。其实WebService原来有两种方式,一是SOAP协议方式,在这种方式下需要WSDL,UDDI等,第二种方式是REST方式,这种方式根本不需要WSDL,UDDI等。
        在SOA的基础技术实现方式中WebService占据了很重要的地位,通常我们提到WebService第一想法就是SOAP消息在各种传输协议上交互。近几年REST的思想伴随着SOA逐渐被大家接受,同时各大网站不断开放API提供给开发者,也激起了REST风格WebService的热潮,并且REST方式现在看来是更加流行。

        还有一点就是APP风靡众生的今天,那么API的开放就更是迫在眉睫,所波逐流,我们采用REST方式提供一次服务试试

        SSH项目目前已成为作坊开发的主流框架,在现有系统中怎样向外提供REST方式的服务呢?
        首先既然是SSH集成的项目,里面既然已经有了Spring,我们不妨就采用Spring构建Rest服务

        Step1:
        在原来的web.xml中关于struts的filter后添加一个servlet,使其支持spring的mvc,代码如下:

<servlet> 
        <servlet-name>rest</servlet-name> 
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>   
        <init-param> 
                <param-name>contextConfigLocation</param-name> 
                <param-value>classpath:spring/rest-servlet.xml</param-value> 
        </init-param> 
        <load-on-startup>0</load-on-startup> 
</servlet> 
<servlet-mapping>   
        <servlet-name>rest</servlet-name>   
        <url-pattern>/restful/*</url-pattern>   
</servlet-mapping>

         Step2:
        此时你可能发现一个问题,你原来的web.xml中配置的关于struts2的filter处理的是

<filter-name>struts2</filter-name> 
<url-pattern>/*</url-pattern>

         这样一来,你原来的struts岂不是要过滤你现在的rest服务,那么可以采取重写原来struts的filterStrutsPrepareAndExecuteFilter,使其不拦截“/restful/*”的请求,代码如下

public class MyStrutsFilter extends StrutsPrepareAndExecuteFilter { 
        private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(MyStrutsFilter.class); 
        @Override 
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 
                HttpServletRequest req = (HttpServletRequest) request; 
                String path = req.getRequestURI(); 
                if(path.contains("/restful/")) { 
                        log.debug("跳过struts"); 
                        chain.doFilter(request, response); 
                } else { 
                        log.debug("进入struts"); 
                        super.doFilter(request, response, chain); 
                } 
        } 
}

          同时更改web.xml中的原来struts的filter为

<filter-name>struts2</filter-name> 
<filter-class> 
    com.cdthgk.project.base.action.MyStrutsFilter 
    <!--org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter--> 
</filter-class>

         Step3:
        在Step1还有一个关于spring的rest-servlet.xml文件,其代码如下

<description>Spring MVC for Restful</description> 
<!--检测注解--> 
<context:component-scan base-package="com.cdthgk.management.rest" /> 
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />   
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />   
<!-- 注册视图解析器,说白了就是根据返回值指定到某个页面 -->       
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">   
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />   
    <property name="prefix" value="/"></property><!--页面文件的路径,在根目录下--> 
</bean>

         Step4:
        接下来我们就可以码我们的java代码了,使其提供rest方式的服务,其他不解释,实例代码如下    

package com.cdthgk.management.rest; 
import java.io.OutputStreamWriter; 
import java.io.PrintWriter; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
import org.springframework.stereotype.Controller; 
import org.springframework.web.bind.annotation.PathVariable; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 
@Controller 
@RequestMapping("/testREST") 
public class RestFulWSAction { 
 // TODO ① 
 @RequestMapping(value="/getEmployer/{id}/{name}", method=RequestMethod.GET) 
 public void get(HttpServletRequest request, HttpServletResponse response, @PathVariable String id, @PathVariable String name) { 
  StringBuilder msg = new StringBuilder(); 
  // TODO ② 
  msg.append("{\"msg\":\"").append(name).append("——这是你刚才传入的第二个参数\"}"); 
  printData(response, msg); 
 } 
  
 private void printData(HttpServletResponse response, StringBuilder msg) { 
        try { 
         response.setContentType("text/html;charset=utf-8"); 
            response.setCharacterEncoding("UTF-8"); 
            PrintWriter out = new PrintWriter(new OutputStreamWriter(response.getOutputStream(), "UTF-8")); 
            out.println(msg); 
            out.close(); 
        } catch (Exception e) {   
            e.printStackTrace();   
        } 
    } 
}

         Step5:
        我们的业务不可能就是这样简单的处理,肯定还有复杂的逻辑处理、数据操作,那么你仍然可以使用原来的service
        在上一步的代码中只需注入原来的service即可,其完整实例如下:
        在上面的代码中TODO ①处加入,这就是你将注入的service

@Autowired 
private EmployerService employerService;

       在TODO ②处加入你的接口调用        

employerService.getEmployer(id);

 

发布评论

分享到:

IT虾米网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

Activiti的流程委托功能[getAssignee与getOwner的区别]详解
你是第一个吃螃蟹的人
发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。