我正在努力实现以下目标.
从Request中读取自定义标头及其值:
name: username
Run Code Online (Sandbox Code Playgroud)
现在,作为响应,我想name:value在HTTP响应中返回相同的标头对.
我正在使用JAX-RS webservice的Jersey 2.0实现.
当我发送请求URL时Http://localhost/test/,请求头也会被传递(暂时,虽然Firefox插件 - 硬编码).
收到该URL的请求后,将调用以下方法:
@GET
@Produces(MediaType.APPLICATION_JSON)
public UserClass getValues(@Context HttpHeaders header) {
MultivaluedMap<String, String> headerParams = header.getRequestHeaders();
String userKey = "name";
headerParams.get(userKey);
// ...
return user_object;
}
Run Code Online (Sandbox Code Playgroud)
我怎么能实现这个目标?任何指针都会很棒!
我使用AppFuse创建了一个基本的应用程序shell,并按照AppFuse教程使用Jax-RS创建了一个简单的RESTful服务.这很好用.调用http://localhost:8080/services/api/persons将Person对象的集合作为具有正确数据的Json格式字符串返回.
我现在想要从Appfuse公开的RESTful服务中访问ServletRequest和ServletResponse对象(使用另一个需要这些对象的库).
我认为应该通过添加@Context注释来实现,例如关注此StackOverflow帖子和此论坛帖子.
但是,如果我添加@Context标记(见下文),它编译正常但在服务器重新启动时抛出异常(附在底部).
这是以下声明@WebService:
@WebService
@Path("/persons")
public interface PersonManager extends GenericManager<Person, Long> {
@Path("/")
@GET
@Produces(MediaType.APPLICATION_JSON)
List<Person> read();
...
}
Run Code Online (Sandbox Code Playgroud)
这里是我认为我会称之为@Context注释的实现类:
@Service("personManager")
public class PersonManagerImpl extends GenericManagerImpl<Person, Long> implements PersonManager {
PersonDao personDao;
@Context ServletRequest request; // Exception thrown on launch if this is present
@Context ServletContext context; // Exception thrown on launch of this is present
...
}
Run Code Online (Sandbox Code Playgroud)
希望我错过了一些简单的东西,要么包括要使其工作,要么意识到获得ServletRequest是不可能的,因为......任何线索都会受到欢迎.
我在IntelliJ的Tomcat上运行它. …
我编写了调用Jersey客户端API的代码,后者又调用了一个不受我控制的Web服务.我不希望我的单元测试调用实际的Web服务.
为调用Jersey客户端API的代码编写单元测试的最佳方法是什么?我应该使用Jersey服务器API编写JAX-RS Web服务,然后使用Jersey Test Framework进行单元测试吗?或者我应该模拟泽西岛网络服务电话?我可以访问JMock.或者我应该尝试另一种方法?
在我的研究中,我发现这个讨论描述了各种选项,但我找到了一个完整的解决方案.是否有可用的代码示例显示建议的JUnit方法?我在泽西文档中找不到任何内容.
这是相关的源代码:
public String getResult(URI uri) throws Exception {
// error handling code removed for clarity
ClientConfig clientConfig = new DefaultClientConfig();
Client client = Client.create(clientConfig);
WebResource service = client.resource(uri);
String result = service.accept(accept).get(String.class);
return result;
}
Run Code Online (Sandbox Code Playgroud)
以下是我想传递的测试代码示例.我想测试(1)传入有效的URI并获取有效的字符串,以及(2)传递无效(无论出于何种原因 - 无法访问或未授权)URI并获得异常.
@Test
public void testGetResult_ValidUri() throws Exception {
String xml = retriever.getResult(VALID_URI);
Assert.assertFalse(StringUtils.isBlank(xml));
}
@Test(expected = IllegalArgumentException.class)
public void testGetResult_InvalidUri() throws Exception {
retriever.getResult(INVALID_URI);
}
Run Code Online (Sandbox Code Playgroud)
以上所有内容都是我的代码所做的简单描述.实际上,在它上面有一个接受两个URI的层,首先尝试调用第一个URI,如果该URI失败,那么它会尝试调用第二个URI.我希望单元测试包括(1)第一个URI成功,(2)第一个URI失败,第二个URI成功,(3)两个URI都失败.这段代码非常复杂,我想使用JUnit测试这些不同的场景,但要做到这一点,我需要运行实际的替代Web服务或模拟Jersey客户端API调用.
我正在使用Jersey开发RESTful服务,它可以很好地处理GET方法.但我只能null使用该POST方法获取参数.这是我项目的示例代码.
<form action="rest/console/sendemail" method="post">
<input type="text" id="email" name="email">
<button type="submit">Send</button>
</form>
Run Code Online (Sandbox Code Playgroud)
@POST
@Path("/sendemail")
public Response sendEmail(@QueryParam("email") String email) {
System.out.println(email);
return new Response();
}
Run Code Online (Sandbox Code Playgroud)
我从帖子收到的电子邮件始终为空.有人有想法吗?
我将QueryParam更改为FormParam,我得到的参数仍为null.
在REST服务中向客户端返回响应的所有可能性中,我看到了两种看起来相同的可能性:抛出WebApplicationException(可能使用Response实例)或返回Response实例.
为什么使用一种可能性而不是另一种可能性,因为结果相同?这与使用的REST框架有关,可以配置为在异常和常规响应之间做出不同反应吗?
我正在将JAX-RS Web服务部署到Tomcat servlet容器.
我见过代码示例,它们使用以下两种方法之一来指示web.xml文件中的资源:
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.example</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
Run Code Online (Sandbox Code Playgroud)
...期望资源驻留在com.example包中,我想通过Java RTTI发现.
<servlet>
<servlet-name>jersey-serlvet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>full.qualified.name.to.MyApplication</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
Run Code Online (Sandbox Code Playgroud)
... MyApplication类明确标识资源类:
public class MyApplication extends javax.ws.rs.core.Application {
public Set<Class<?>> getClasses() {
Set<Class<?>> s = new HashSet<Class<?>>();
s.add(ResourceA.class);
return s;
}
Run Code Online (Sandbox Code Playgroud)
使用单一方法与其他方法纯粹是品味和配置工作的问题,需要考虑哪些权衡取舍?就个人而言,我更喜欢方法2提供的更细粒度的控制,但是maven Jersey 2.7原型:
mvn archetype:generate -DarchetypeArtifactId=jersey-quickstart-webapp \
-DarchetypeGroupId=org.glassfish.jersey.archetypes -DinteractiveMode=false \
-DgroupId=com.example -DartifactId=simple-service-webapp -Dpackage=com.example \
-DarchetypeVersion=2.7
Run Code Online (Sandbox Code Playgroud)
......正在使用方法1,这让我思考.
尝试在Tomcat上启动Jersey应用程序时,我遇到了一个非常奇怪的错误.相同的代码适用于其他计算机.我尝试重新安装tomcat,我所有的maven依赖项,甚至是Eclipse和Java本身,没有运气.我觉得看起来像是一个糟糕的泽西版本正在加载?
任何指向正确的方向将不胜感激.
这是有效的pom:http://pastebin.com/NacsWTjz
而实际的pom:http://pastebin.com/H6sHe4ce
2015-02-13 13:43:40,870 [localhost-startStop-1] ERROR org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/middleware-server] - StandardWrapper.Throwable
java.lang.NoSuchMethodError: javax.ws.rs.core.Application.getProperties()Ljava/util/Map;
at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:304)
at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:285)
at org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.java:311)
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:170)
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:358)
at javax.servlet.GenericServlet.init(GenericServlet.java:158)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1231)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1144)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1031)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4901)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5188)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1409)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1399)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Run Code Online (Sandbox Code Playgroud) 我已经google了很多,仍然感到困惑的是上面的每一个究竟是什么意思.
以下是我对它的理解:
我下载了每个jar并尝试反编译并查看其中的内容,但我只能在所有这些中找到接口而不是实现.
我在maven shade插件生成的重复警告的上下文中面临这些问题,并且需要正确理解上面的内容以找出要排除的内容和原因.
我试图在不使用JMX选项或web.xml选项的情况下禁用WADL.简单的JAX-RS应用程序类如下:
@ApplicationPath("resources")
public class TestWADL
extends Application
{
public Map<String, Object> getProperties()
{
Map<String, Object> props = new HashMap();
props.put("jersey.config.server.wadl.disableWadl", true);
return props;
}
}
Run Code Online (Sandbox Code Playgroud)
在WebLogic 12.2.1上,当属性设置为"true"时,它不会被部署.如果"jersey.config.server.wadl.disableWadl"更改为"com.jersey.config.server.wadl.disableWadl",则会部署但WADL仍处于活动状态.尝试使用"com.sun.jersey.config.server.wadl.disableWadl",但部署发生但WADL处于活动状态.
部署期间出错:
failed to preload on startup in Web application: "jersey-test".
A MultiException has 1 exceptions. They are:
1. org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=WadlApplicationContext,parent=JaxRsMonitoringListener,qualifiers={},position=-1,optional=false,self=false,unqualified=null,1563651367)
at org.jvnet.hk2.internal.ThreeThirtyResolver.resolve(ThreeThirtyResolver.java:75)
at org.jvnet.hk2.internal.Utilities.justInject(Utilities.java:946)
at org.jvnet.hk2.internal.ServiceLocatorImpl.inject(ServiceLocatorImpl.java:981)
at org.jvnet.hk2.internal.ServiceLocatorImpl.inject(ServiceLocatorImpl.java:971)
at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:617)
at org.glassfish.jersey.server.ApplicationHandler.access$500(ApplicationHandler.java:184)
at org.glassfish.jersey.server.ApplicationHandler$3.call(ApplicationHandler.java:350)
at org.glassfish.jersey.server.ApplicationHandler$3.call(ApplicationHandler.java:347)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.processWithException(Errors.java:255)
at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:347)
at …Run Code Online (Sandbox Code Playgroud) 我是JAX-RS的新手,我正在努力理解@Context注释应该如何工作.
在javadoc的有六类(列表Application,UriInfo,Request,HttpHeaders,SecurityContext,Providers).但是,我在Web上找到了使用此注释与其他类型的代码,例如:
@GET
public String something(@Context HttpServletRequest req) {
}
Run Code Online (Sandbox Code Playgroud)
是否有可用于此注释的受支持类型列表?此列表是否在标准的实施之间发生变化?
我正在尝试使用Jersey,我担心我会编写无法移植到其他JAX-RS实现的代码.
jax-rs ×10
java ×9
jersey ×8
rest ×6
appfuse ×1
jersey-2.0 ×1
json ×1
jsr ×1
jsr311 ×1
junit ×1
maven ×1
parameters ×1
post ×1
servlets ×1
tomcat ×1
unit-testing ×1
web-services ×1
weblogic ×1