1.建一个maven web项目
新建一个maven项目,next,第一个框不要勾选
选择maven-archetype-webapp,建一个web项目
键入项目组织id与项目id
一般此时搭建的只是最基本的骨架,还缺了很多东西,我们可以自己按需求去增加。
右键项目,build path,编辑jre,选择默认
web项目的基本构造就出来了
再新建目录,在main和test下面新建resources,然后再build path里的source添加关联
最后再增加服务器jboss的包,整个web项目框架就基本没有报错的搭建起来了
2.最基本的讲完了,现在开始做一个resteasy的简单实例。
2.1首先,配置pom.xml,为项目添加下载resteasy的jar,下面给出jar的配置版本(可去网上查看最新版本)
<dependencies> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-jaxrs</artifactId> <version>2.2.1.GA</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.10</version> </dependency> </dependencies>
lombok是一个用来简化代码的工具,后面给出的代码有用到,也可以不用,但要自己写set,get及类的初始化
ps1:此时可能出现的错误,提示缺少依赖包,如下图,解决办法:右键maven---update project 一下,使新的包在本地生效,一般就能解决问题。
ps2:如果update项目后报JavaServer Faces 2.0 requires Dynamic Web Module 2.5 or newer之类的错误,就是你的web版本太旧,此时项目右键properties—project facets—Dynamic Web Module,修改为3.0的版本,一般就能解决。
ps3:如果在面版不能修改,此时,你就需要去底层修改web的版本了,首先更改maven生成的web.xml的web-app标签内容,再去项目底层demo\.settings路径下,修改org.eclipse.wst.common.project.facet.core.xml文件的配置,将其都改为3.0的版本。下面分别为旧的web.xml,新的web.xml,以及.core.xml的配置
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>Archetype Created Web Application</display-name> </web-app>
<web-app 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_3_0.xsd" version="3.0"> </web-app>
2.2配置web.xml,注册resources的模式有三种:
2.2.1手动注册resources的模式
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>Archetype Created Web Application</display-name> <!-- 1. 使用手动注册resources的模式,必须启动ResteasyBootstrap监听 --> <!-- 要发布成resteasy服务的资源类 --> <context-param> <param-name>resteasy.resources</param-name> <param-value>com.fengyuan.restapi.UserService</param-value> </context-param> <!-- 对应<servlet-mapping>的url,必须设置prefix做初始过滤,访问例子:http://localhost:8080/demo/service/userservice/users --> <context-param> <param-name>resteasy.servlet.mapping.prefix</param-name> <param-value>/service</param-value> </context-param> <!-- 启动服务监听器,初始化resteasy核心组件 --> <listener> <listener-class> org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap </listener-class> </listener> <!-- url服务请求的分发控制器 --> <servlet> <servlet-name>resteasy-servlet</servlet-name> <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class> </servlet> <servlet-mapping> <servlet-name>resteasy-servlet</servlet-name> <url-pattern>/service/*</url-pattern> </servlet-mapping> </web-app>
2.2.2手动指定Application的模式
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>Archetype Created Web Application</display-name> <!-- 方法2:不启用手动注册resources的模式和ResteasyBootstrap监听,创建一个类并且继承javax.ws.rs.core.Application,并且手动增加REST服务 --> <!-- 对应<servlet-mapping>的url,必须设置prefix做初始过滤,访问例子:http://localhost:8080/demo/service/userservice/users --> <context-param> <param-name>resteasy.servlet.mapping.prefix</param-name> <param-value>/service</param-value> </context-param> <!-- url服务请求的分发控制器 --> <servlet> <servlet-name>resteasy-servlet</servlet-name> <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class> <init-param> <param-name>javax.ws.rs.Application</param-name> <param-value>com.mk.rest.RestApplication</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>resteasy-servlet</servlet-name> <url-pattern>/service/*</url-pattern> </servlet-mapping> </web-app>
2.2.3自动Scan的模式,我使用这种模式,启动项目时,会报类似下面的错误
17:56:16,506 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/demo]] (MSC service thread 1-6) Exception sending context initialized event to listener instance of class org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap: java.lang.RuntimeException: Unable to find a public constructor for class org.jboss.resteasy.core.AsynchronousDispatcher at org.jboss.resteasy.plugins.server.resourcefactory.POJOResourceFactory.registered(POJOResourceFactory.java:35) [resteasy-jaxrs-2.3.2.Final.jar:] at org.jboss.resteasy.core.ResourceMethodRegistry.addResourceFactory(ResourceMethodRegistry.java:121) [resteasy-jaxrs-2.3.2.Final.jar:] at org.jboss.resteasy.core.ResourceMethodRegistry.addResourceFactory(ResourceMethodRegistry.java:107) [resteasy-jaxrs-2.3.2.Final.jar:] at org.jboss.resteasy.core.ResourceMethodRegistry.addResourceFactory(ResourceMethodRegistry.java:84) [resteasy-jaxrs-2.3.2.Final.jar:] at org.jboss.resteasy.core.ResourceMethodRegistry.addPerRequestResource(ResourceMethodRegistry.java:73) [resteasy-jaxrs-2.3.2.Final.jar:] at org.jboss.resteasy.spi.ResteasyDeployment.registration(ResteasyDeployment.java:367) [resteasy-jaxrs-2.3.2.Final.jar:] at org.jboss.resteasy.spi.ResteasyDeployment.start(ResteasyDeployment.java:225) [resteasy-jaxrs-2.3.2.Final.jar:] at org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap.contextInitialized(ResteasyBootstrap.java:28) [resteasy-jaxrs-2.3.2.Final.jar:] at org.apache.catalina.core.StandardContext.contextListenerStart(StandardContext.java:3392) [jbossweb-7.0.13.Final.jar:] at org.apache.catalina.core.StandardContext.start(StandardContext.java:3850) [jbossweb-7.0.13.Final.jar:] at org.jboss.as.web.deployment.WebDeploymentService.start(WebDeploymentService.java:90) [jboss-as-web-7.1.1.Final.jar:7.1.1.Final] at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811) at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_80] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_80] at java.lang.Thread.run(Thread.java:745) [rt.jar:1.7.0_80] 17:56:16,567 ERROR [org.apache.catalina.core.StandardContext] (MSC service thread 1-6) Error listenerStart 17:56:16,568 ERROR [org.apache.catalina.core.StandardContext] (MSC service thread 1-6) Context [/demo] startup failed due to previous errors 17:56:16,603 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-6) MSC00001: Failed to start service jboss.web.deployment.default-host./demo: org.jboss.msc.service.StartException in service jboss.web.deployment.default-host./demo: JBAS018040: Failed to start context at org.jboss.as.web.deployment.WebDeploymentService.start(WebDeploymentService.java:95) at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811) [jboss-msc-1.0.2.GA.jar:1.0.2.GA] at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746) [jboss-msc-1.0.2.GA.jar:1.0.2.GA] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_80] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_80] at java.lang.Thread.run(Thread.java:745) [rt.jar:1.7.0_80] 17:56:16,817 INFO [org.jboss.as.server] (DeploymentScanner-threads - 2) JBAS015870: Deploy of deployment "demo.war" was rolled back with failure message {"JBAS014671: Failed services" => {"jboss.web.deployment.default-host./demo" => "org.jboss.msc.service.StartException in service jboss.web.deployment.default-host./demo: JBAS018040: Failed to start context"}} 17:56:16,872 INFO [org.jboss.as.server.deployment] (MSC service thread 1-8) JBAS015877: Stopped deployment demo.war in 59ms 17:56:16,873 INFO [org.jboss.as.controller] (DeploymentScanner-threads - 2) JBAS014774: Service status report JBAS014777: Services which failed to start: service jboss.web.deployment.default-host./demo: org.jboss.msc.service.StartException in service jboss.web.deployment.default-host./demo: JBAS018040: Failed to start context 17:56:16,875 ERROR [org.jboss.as.server.deployment.scanner] (DeploymentScanner-threads - 1) {"JBAS014653: Composite operation failed and was rolled back. Steps that failed:" => {"Operation step-2" => {"JBAS014671: Failed services" => {"jboss.web.deployment.default-host./demo" => "org.jboss.msc.service.StartException in service jboss.web.deployment.default-host./demo: JBAS018040: Failed to start context"}}}}
原因不明,下面我的自动扫描配置,希望有大神能指点下
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>Archetype Created Web Application</display-name> <!-- 方法3: 使用自动Scan的模式,必须启动ResteasyBootstrap监听,报错,原因不明 --> <context-param> <param-name>resteasy.scan</param-name> <param-value>true</param-value> </context-param> <!-- 对应<servlet-mapping>的url,必须设置prefix做初始过滤,访问例子:http://localhost:8080/wang/service/userservice/users --> <context-param> <param-name>resteasy.servlet.mapping.prefix</param-name> <param-value>/service</param-value> </context-param> <!-- 启动服务监听器,初始化resteasy核心组件 --> <listener> <listener-class> org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap </listener-class> </listener> <!-- url服务请求的分发控制器 --> <servlet> <servlet-name>resteasy-servlet</servlet-name> <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class> </servlet> <servlet-mapping> <servlet-name>resteasy-servlet</servlet-name> <url-pattern>/service/*</url-pattern> </servlet-mapping> </web-app>
2.3下面给出简单的java类
新建一个简单的User类,使用了lombok插件注解(可以简化代码,自动生成set,get等方法),lombok的安装方法自行百度,安装后还要在pxm.xml里配置,见上文
package com.fengyuan.domain; import lombok.AllArgsConstructor; import lombok.Data; @Data @AllArgsConstructor public class User { private String name; private int age; private String tel; }
要发布的资源类UserService
package com.fengyuan.restapi; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import com.fengyuan.domain.User; @Path("userservice") // 服务路径 public class UserService { /** * 初始化三个用户数据,存入map中,key为用户id,value为用户对象 */ static Map<Integer, User> userMap = new HashMap<>(); static { User user1 = new User("Lee", 24, "138***"); userMap.put(1, user1); User user2 = new User("Cathy", 25, "188***"); userMap.put(2, user2); User user3 = new User("Aaron", 26, "186***"); userMap.put(3, user3); } /** * 获取指定id的用户 * * @param id * @return */ @GET @Path("user/{id}") // 具体服务的路径, id是入参 @Produces("application/json") // 返回的格式 public User getById(@PathParam("id") Integer id) { return (User) userMap.get(id); } /** * 以json格式返回所有用户 * * @return */ @GET @Path("users") @Produces("application/json") public List<User> getUsers() { List<User> userList = new ArrayList<User>(); for (Entry<Integer, User> user : userMap.entrySet()) { userList.add(user.getValue()); } return userList; } }
测试结果
下面给出Application的模式的代码
package com.mk.rest; import java.util.HashSet; import java.util.Set; import com.fengyuan.restapi.UserService; public class RestApplication extends javax.ws.rs.core.Application{ private Set<Object> singletons = new HashSet<Object>(); /*在这里增加资源类*/ public RestApplication () { singletons.add(new MessageRestService()); singletons.add(new UserService()); } @Override public Set<Object> getSingletons() { return singletons; } }
后续会边学习边给出resteasy的其他复杂实例,欢迎随时指正~~~~