我正在努力让REST服务在Websphere 8.x中运行,但是当我使用以下web.xml时......
<?xml version="1.0" encoding="UTF-8"?>
<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">
<servlet>
<display-name>jersey</display-name>
<servlet-name>jersey</servlet-name>
<servlet-class>
com.ibm.websphere.jaxrs.server.IBMRestServlet
</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>org.gleason.rest</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
当我尝试启动应用程序时,我得到404,同时eclipse显示以下构建错误...
描述资源路径位置类型 servlet映射“jersey”是指未定义的servlet web.xml / RestTest / WebContent / WEB-INF未知Web问题
这让我相信它没有正确构建,这就是我的index.html工作但JAX-RS失败的原因。
谁能看到我错过的东西?所有的例子都围绕着Application,我宁愿使用package。
答案 0 :(得分:2)
WAS具有基于Apache Wink的JAX-RS实现。您的配置显示了Apache Wink和Jersey(另一个JAX-RS实现)的混合。
答案 1 :(得分:1)
您还可以仅在RestService类中使用Annotations配置休息服务,避免使用web.xml配置
以下是使用GET或POST请求进行测试的快速示例
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.MediaType;
@ApplicationPath("rest")
@Path("/service")
public class RestService extends Application {
@GET
@Produces(MediaType.APPLICATION_JSON)
public Map hello() {
Map map = new HashMap(1);
map.put("Hello", "I'm a REST Service");
return map;
}
@POST //
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Map helloName(HashMap entryMap) {
Map map = new HashMap(1);
map.put("Hello", entryMap.get("Name"));
return map;
}
}
答案 2 :(得分:0)
以下是如何在WAS8中开发和部署REST服务的简单示例。 该示例基于用于管理JSON配置的API,即列出,获取,上载等。
package se.xyz;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
//Use the ApplicationPath annotation do specify the URI path to your REST API
@ApplicationPath("api")
public class RestAPIRegistrationServlet extends Application {
@Override
public Set<Object> getSingletons() {
Set<Object> tSet = new HashSet<Object>();
//add an instance of your API class to the set of API´s.
tSet.add(new ConfigRestAPI());
return tSet;
}
}
以下是管理JSON配置的API。 注意 API正在使用ConfigManager来处理配置。该类未包含在示例中。
package se.xyz;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import org.apache.wink.common.model.wadl.WADLGenerator;
//Specify the ConfigRestAPI part of the URI path
@Path("/configs")
public class ConfigRestAPI{
private static Logger _LOGGER = Logger.getLogger(ConfigRestAPI.class.getName());
@javax.ws.rs.OPTIONS
@Produces("application/vnd.sun.wadl+xml")
public org.apache.wink.common.model.wadl.Application getOptions(@Context Application app,
@Context HttpServletRequest aHttpServletRequest) {
logAccess(aHttpServletRequest);
Set<Object> tObjectSet = app.getSingletons();
Set<Class<?>> tClassSet = new HashSet<Class<?>>();
for (Object tObject : tObjectSet) {
tClassSet.add(tObject.getClass());
}
org.apache.wink.common.model.wadl.Application wadlAppDoc = new WADLGenerator().generate("", tClassSet);
/* modify the wadlAppDoc JAXB model if you want to add additional information */
return wadlAppDoc;
}
@GET
@Path("/list")
@Produces(MediaType.APPLICATION_JSON)
public Response list(@Context HttpServletRequest aHttpServletRequest) {
logAccess(aHttpServletRequest);
try {
ResponseBuilder tResponseBuilder =
Response.ok(ConfigManager.getInstance().fetchConfigs(), MediaType.APPLICATION_JSON);
Response tResponse = tResponseBuilder.build();
return tResponse;
} catch (Throwable e) {
_LOGGER.log(Level.SEVERE, e.getMessage(), e);
throw new WebApplicationException(e, Response.serverError()
.entity(e.getClass().getName() + ", Message: " + e.getMessage()).build());
}
}
private boolean isNullOrBlank(String aVal){
return aVal == null || "".equals(aVal.trim());
}
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response fetch(@QueryParam("id") String id, @Context HttpServletRequest aHttpServletRequest) {
logAccess(aHttpServletRequest);
try {
if (isNullOrBlank(id)) {
return Response.serverError().entity("id cannot be null or blank").build();
}
ResponseBuilder tResponseBuilder =
Response.ok(ConfigManager.getInstance().fetchConfig(id), MediaType.APPLICATION_JSON);
Response tResponse = tResponseBuilder.build();
return tResponse;
} catch (Throwable e) {
_LOGGER.log(Level.SEVERE, e.getMessage(), e);
throw new WebApplicationException(e, Response.serverError()
.entity(e.getClass().getName() + ", Message: " + e.getMessage()).build());
}
}
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.TEXT_PLAIN)
public Response store(String aConfig, @QueryParam("id") String id, @Context HttpServletRequest aHttpServletRequest) {
logAccess(aHttpServletRequest);
try {
if (isNullOrBlank(id)) {
return Response.serverError().entity("id cannot be null or blank").build();
}
ConfigManager.getInstance().storeConfig(aConfig, id);
} catch (Throwable e) {
_LOGGER.log(Level.SEVERE, e.getMessage(), e);
throw new WebApplicationException(e, Response.serverError()
.entity(e.getClass().getName() + ", Message: " + e.getMessage()).build());
}
ResponseBuilder tResponseBuilder = Response.ok();
Response tResponse = tResponseBuilder.build();
return tResponse;
}
@PUT
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.TEXT_PLAIN)
public Response update(String aConfig, @QueryParam("id") String id, @Context HttpServletRequest aHttpServletRequest) {
logAccess(aHttpServletRequest);
try {
if (isNullOrBlank(id)) {
return Response.serverError().entity("id cannot be null or blank").build();
}
ConfigManager.getInstance().updateConfig(aConfig, id);
} catch (Throwable e) {
_LOGGER.log(Level.SEVERE, e.getMessage(), e);
throw new WebApplicationException(e, Response.serverError()
.entity(e.getClass().getName() + ", Message: " + e.getMessage()).build());
}
ResponseBuilder tResponseBuilder = Response.ok();
Response tResponse = tResponseBuilder.build();
return tResponse;
}
@DELETE
@Produces(MediaType.TEXT_PLAIN)
public Response delete(@QueryParam("id") String id, @Context HttpServletRequest aHttpServletRequest) {
logAccess(aHttpServletRequest);
try {
if (isNullOrBlank(id)) {
return Response.serverError().entity("id cannot be null or blank").build();
}
ConfigManager.getInstance().deleteConfig(id);
} catch (Throwable e) {
_LOGGER.log(Level.SEVERE, e.getMessage(), e);
throw new WebApplicationException(e, Response.serverError()
.entity(e.getClass().getName() + ", Message: " + e.getMessage()).build());
}
ResponseBuilder tResponseBuilder = Response.ok();
Response tResponse = tResponseBuilder.build();
return tResponse;
}
private static void logAccess(HttpServletRequest aHttpServletRequest) {
if (_LOGGER.isLoggable(Level.FINE))
_LOGGER.fine(aHttpServletRequest.getRequestURI() + " called from: " + aHttpServletRequest.getRemoteHost()
+ " (" + aHttpServletRequest.getRemoteAddr() + ")");
}
}
部署REST API后,您可以使用以下方法调用它: 用于列表操作的URI / ContextPath / api / configs /列表上的Http GET。
进一步阅读: http://www.ibm.com/developerworks/websphere/techjournal/1305_gunderson/1305_gunderson.html
答案 3 :(得分:0)
在您的server.xml中,
尝试删除<feature>jaxrs-1.1</feature>
像这样
<featureManager>
<feature>jsp-2.2</feature>
<feature>localConnector-1.0</feature>
<!-- <feature>jaxrs-1.1</feature> -->
</featureManager>
与2个JAX-RS实施存在冲突。