day63-webservice 11.cxf整合spring
如果我们有Spring配置文件,怎么把WebService整合到Spring里面,用Ioc容器来管理这个Bean.
做项目的时候一般都是分层:Dao层、Service层.Service层要调Dao层,就需要把Dao层注入进来.Spring采用注解的形式来管理这些Bean.Spring也有配置文件的形式.
还有一种注解@Component和@Service、@Repository是同等类型的.@Service知道我是业务层,@Repository知道我是数据库层.
@Component适合于无法分层的类或接口.咱们做项目的时候不一定说所有的类都属于某一层.比如说你就是想做一个定时器服务,就是说后台运行这样一个服务.那它肯定会不属于Dao也不属于Service.但是你还想让它用这个Spring的容器管理起来,那你这个就得用@Component了,没法分层的都用@Component.
我们习惯使用@Repository,还有@Autowired.@Autowired的特点是?@Resource是javax.annotation下面的,不是Spring的东西.@Autowired是Spring的东西,它与Spring联系比较紧密.@Autowired会按照类型来做匹配.就是你做注入的时候它会找接口PersonDao的实现类.那如果找到了就把它注入进来.如果是找到一个就把它注入进来,如果是找到两个或者是三个就使用另外一个注解.
试一试personDao是不是能够被调用.怎么把这个接口PersonServiceImpl给它发布到外面呢?通过Spring的配置文件.如果现在要把PersonServiceImpl发布到外面去,客户端也得有这个调用它的这种业务逻辑.生成代码来调用.
在web.xml里面需要把Spring的容器初始化.
classpath*:cxf*.xml,classpath*:beans.xml
加载多个配置文件.*是代表一种匹配模式,那么如果说咱们的配置文件都以同样的一个前缀来做的话,那么这边你可以不要它了.
还是说生成一下代码,把代码生成一下它.
默认在Spring容器里面创建的Bean都是单例的.com.rl.person.ws.service不是要替换掉com.rl.person.service,因为com.rl.person.service是内部系统要用,com.rl.person.ws.service是提供给外部系统调用的.它们俩没有太多关系.
多了一个方法getPersonAll(),重新部署项目到tomcat服务器上.
要重新生成一下客户端的代码.
回顾一下这几个步骤,WebService要整合于Spring,那么它也是Bean.我们在做项目的时候所有的Bean都要被Spring来管理。既然由Spring来管理那么你就要遵守它的规则,那么我们这边以注解的形式来管理。首先你在Spring里面要配置这样一个扫描器,扫描com.rl.person下的所有的这些类.只要你带有注解,带有@Repository、@Service还有@Component、@Controller类似这样的注解都给你纳入到Spring里面去管理。
咱们常用的在本地使用的这种Service,那这种Service它依赖于我们Dao.是这种写法.在上面类上加@Service注解然后注入Dao使用@Autowired.咱们WebService的这种Bean对于Dao这些注入跟它是一模一样的.WebService它跟Spring无缝整合.WebService就是多了一个@WebService注解,别的东西跟普通的Service一模一样,就多了这么一样东西@WebService注解放在接口上。
那这些配置跟我们之前的配置是一样的。配置带有接口的这种WebService的服务类.那这样它和我们的Spring就做了一个完整的整合。
com.rl.person.ws.service.impl.PersonServiceWSImpl这里面的业务逻辑是对数据库进行修改,那这是添加/变更.假如http://localhost:8080/spring_cxf/service/person?wsdl放在外面被别人知道了是不是有点危险呢?确实是挺危险的,他往里面给你随便加东西呢?如果有修改的东西被别人知道了是随便加的。那咱们做的话这种安全策略多种多样。
咱们认识你是我的合作方那我才让你调.可以不可以从业务逻辑来实现它?可以从业务逻辑来实现它。
@Override public void add(Person person) { // TODO Auto-generated method stub personDao.add(person); }
这个东西是咱们要来执行的业务逻辑。那你这边可不可以给个密码,设置调用这个方法的密码。那如果你这边调用的话密码输入错误就不让你调,因为你是非法的,那如果你输入的是对的那我才让你调。
package com.rl.cxf.web.client; import java.util.List; import com.rl.spring.Person; import com.rl.spring.PersonServiceWS; import com.rl.spring.PersonServiceWSService; public class WebSpringClient { public static void main(String[] args) { PersonServiceWSService psws = new PersonServiceWSService(); PersonServiceWS personService = psws.getPersonServiceWSPort(); Person person = new Person(); person.setName("八戒"); person.setGender("公"); person.setAddress("高老庄"); //personService.add(person); //String result = personService.add(person,"456788"); String result = personService.add(person,"123456"); System.out.println(result);//如果说你的密码错了,证明你这边没有执行你的业务逻辑 List<Person> pList = personService.getPersonAll(); for (Person p : pList) { System.out.println("姓名:"+ p.getName()+" 性别: "+p.getGender() +" 地址:"+p.getAddress()); } } }
package com.rl.constant; public interface Constants { //存常量 public static final String ws_pass = "123456"; }
package com.rl.model; public class Person { String name; String gender; String address; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }
package com.rl.person.dao; import java.util.List; import com.rl.model.Person; public interface PersonDao { public void add(Person person); public List<Person> getPersonAll(); }
package com.rl.person.dao.impl; import java.util.ArrayList; import java.util.List; import org.springframework.stereotype.Repository; import com.rl.model.Person; import com.rl.person.dao.PersonDao; @Repository //仓库 public class PersonDaoImpl implements PersonDao{ List<Person> pList = new ArrayList<Person>(); @Override public void add(Person person) { // TODO Auto-generated method stub pList.add(person); } @Override public List<Person> getPersonAll() { // TODO Auto-generated method stub return pList; } }
package com.rl.person.service; import com.rl.model.Person; public interface PersonService { public void add(Person person); }
package com.rl.person.service.impl; //import javax.inject.Qualifier; import org.springframework.beans.factory.annotation.Autowired; //import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; import com.rl.model.Person; import com.rl.person.dao.PersonDao; import com.rl.person.service.PersonService; @Service //@Component适合于无法分层的类或接口 public class PersonServiceImpl implements PersonService{ @Autowired //@Qualifier(value="")//value指定你要注入谁,你不可能三个都注入的. PersonDao personDao;//注入Dao @Override public void add(Person person) { // TODO Auto-generated method stub personDao.add(person); } }
package com.rl.person.ws.service; import java.util.List; import javax.jws.WebService; import com.rl.model.Person; @WebService//证明你是一个WebService的类 public interface PersonServiceWS { //public void add(Person person); public String add(Person person,String password); public List<Person> getPersonAll(); }
package com.rl.person.ws.service.impl; import java.util.List; import javax.jws.WebService; import org.springframework.beans.factory.annotation.Autowired; import com.rl.constant.Constants; import com.rl.model.Person; import com.rl.person.dao.PersonDao; import com.rl.person.ws.service.PersonServiceWS; @WebService//可以的,它也受Spring Ioc容器注解的管理,只要你放在扫描器以内就行 public class PersonServiceWSImpl implements PersonServiceWS { @Autowired PersonDao personDao; @Override //public void add(Person person) { public String add(Person person,String password) { // TODO Auto-generated method stub //核对密码,一般会采用MD5做加密.那现在咱们就不加密了. //正确代码,错误代码(或者说错误代码到底是哪种错误代码) String flag = "success"; if(Constants.ws_pass.equals(password)){ personDao.add(person); }else{ flag = "pass_error"; } return flag; } @Override public List<Person> getPersonAll() { // TODO Auto-generated method stub return personDao.getPersonAll(); } }
<?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:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://wwww.springframework.org/schema/tx/spring-tx-3.0.xsd" > <!-- 使用注解的形式做开发 --> <context:component-scan base-package="com.rl.person"></context:component-scan><!-- 扫描器 --> </beans>
<?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:jaxws="http://cxf.apache.org/jaxws" xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns:cxf="http://cxf.apache.org/core" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd"> <!-- 引入CXF Bean定义如下,早期的版本中使用 --> <import resource="classpath:META-INF/cxf/cxf.xml" /> <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" /> <import resource="classpath:META-INF/cxf/cxf-servlet.xml" /> <jaxws:server address="/person" serviceClass="com.rl.person.ws.service.PersonServiceWS"> <!-- 服务接口的实现类 --> <jaxws:serviceBean> <bean class="com.rl.person.ws.service.impl.PersonServiceWSImpl"></bean> </jaxws:serviceBean> <jaxws:inInterceptors> <bean class="org.apache.cxf.interceptor.LoggingInInterceptor"></bean> </jaxws:inInterceptors> <jaxws:outInterceptors> <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"></bean> </jaxws:outInterceptors> </jaxws:server> </beans>
<?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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <!-- 使用Spring的监听器 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class><!-- 初始化Spring的容器,cxf.xml本身就是一个Spring的容器.可以把cxf.xml作为Spring的容器进行加载. --> <!-- 能加载Spring文件的类,这个类叫什么? --> </listener> <context-param> <param-name>contextConfigLocation</param-name><!-- param-name不能再指定config-location,而是要指定ContextLoaderListener里面读取Spring文件的那个Key --> <param-value>classpath*:cxf*.xml,classpath*:beans.xml</param-value> </context-param> <servlet> <servlet-name>cxf</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> <!-- <init-param> <param-name>config-location</param-name> <param-value>classpath:cxf.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> --> </servlet> <servlet-mapping> <servlet-name>cxf</servlet-name> <url-pattern>/service/*</url-pattern> <!-- 拦截这种请求 --> </servlet-mapping> </web-app>