我正在尝试对我的嵌套实体使用 @JsonView 注释。为了更清楚,假设我们有 2 个实体,每个实体都有自己的视图类。
public class JsonViewAddress {
//some view classes
}
public class Address {
//fields annotated by JsonViewAddress's classes and @JsonProperty
}
public class JsonViewPerson {
//some view classes
}
public class Person {
//some fields (yes annotated with JsonViewPerson classes and @JsonProperty)
//also assume that this is annotated with any JsonViewPerson's class.
private Address address;
}
Run Code Online (Sandbox Code Playgroud)
让我们尝试从响应中使用 Json 类型实现这个 Person 类
@Path("hey")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class Resource {
@GET
@Path("/stack/overflow")
@JsonView(value = { /* WHAT SHOULD …Run Code Online (Sandbox Code Playgroud) 我想使用JAX-RS从我的服务器端java返回一个压缩文件到客户端.
我尝试了以下代码,
@GET
public Response get() throws Exception {
final String filePath = "C:/MyFolder/My_File.zip";
final File file = new File(filePath);
final ZipOutputStream zop = new ZipOutputStream(new FileOutputStream(file);
ResponseBuilder response = Response.ok(zop);
response.header("Content-Type", "application/zip");
response.header("Content-Disposition", "inline; filename=" + file.getName());
return response.build();
}
Run Code Online (Sandbox Code Playgroud)
但我得到的例外情况如下,
SEVERE: A message body writer for Java class java.util.zip.ZipOutputStream, and Java type class java.util.zip.ZipOutputStream, and MIME media type application/zip was not found
SEVERE: The registered message body writers compatible with the MIME media type are:
*/* ->
com.sun.jersey.core.impl.provider.entity.FormProvider …Run Code Online (Sandbox Code Playgroud) 我需要提供一个java REST客户端,它应该包含一个包中所有必需的jar.我选择RestEasy作为REST框架,因为服务器应用程序是在JBoss上完成的.
到目前为止,我发现的几乎所有示例都使用应用程序容器环境,其中提供了这些lib,因此在编译期间只需要Java EE API或使用Maven构建,因此依赖项会自动解决,这可能是一个好主意,当前的标准方法,但由于项目相关的原因,我需要在lib文件夹中的jar,并能够在构建期间包含一个可执行jar.
所以我的问题是,哪个罐子有必要建立一个可以做类似的简单客户端:
ResteasyClient client = new ResteasyClientBuilder().build();
ResteasyWebTarget target = client.target(myURL).queryParam("param",
"value");
Builder builder = target.request(MediaType.APPLICATION_JSON).header("user", "abc");
Invocation invocation = builder.buildGet();
MyResponseObject response = invocation.invoke(MyResponseObject .class);
Run Code Online (Sandbox Code Playgroud) 嗨所有我试图从头开始创建一个休息网络服务.这是我的服务部分
@Path("/Phones")
public class PhonessResource {
@GET
@Produces({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON})
public Response getAllNumbers(){
List<PhoneDetail> list = PhoneDirectoryDao.getInstance().getAllNumbers();
GenericEntity<List<PhoneDetail>> entity = new GenericEntity<List<PhoneDetail>>(list) {};
Response response =Response.ok(entity).status(200).build();
return response;//PhoneDirectoryDao.getInstance().getAllNumbers();
}
}
Run Code Online (Sandbox Code Playgroud)
我的数据模型:我有我的getter和setter以及另一个带有所有属性的构造函数,我没有将它粘贴到更少的问题长度,我在客户端和服务器中使用相同的数据模型
@XmlRootElement(name="PhoneDetail")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(propOrder={"id","firstName","lastName","address","phoneNo","timeStamp"})
public class PhoneDetail {
private int id;
private String firstName;
private String lastName;
private String address;
private String phoneNo;
private Timestamp timeStamp;
public PhoneDetail() {}
}
Run Code Online (Sandbox Code Playgroud)
然后我创建一个java客户端来测试服务.我正在使用NETBEANS IDE,所以我在IDE中选择默认选项来创建它
因此我创建了一个Jersey客户端
public class PhoneCLient {
private WebTarget webTarget;
private Client client;
private static final String BASE_URI = "http://localhost:8080/Phones/webresources";
public PhoneCLient() …Run Code Online (Sandbox Code Playgroud) 我有一个Jersery/JAX-RS客户端,它可以访问一个RESTful API(JSON),它应该返回我的POJO列表:
// Hits: GET localhost:8080/myapp/fizz/widget/{widget_id}
@Override
public List<Widget> getWidgetsByUser(Long id) {
return webResource.path("fizz").path("widget").path(id.toString()).get(List.class);
}
Run Code Online (Sandbox Code Playgroud)
以及用以下方法测试客户端的驱动程序:
public class Driver {
public static void main(String[] args) {
Driver d = new Driver();
d.run();
}
public void run() {
MyAppService myService = getSomehow();
List<Widget> widgets = myService.getWidgetResource().getWidgetsByUser(2L);
for(Widget widget : widgets) {
System.out.println("\t...and it found Widget #" + widget.getCaseId());
}
}
}
Run Code Online (Sandbox Code Playgroud)
当我运行这个时,我得到:
Exception in thread "main" java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.me.myapp.Widget
<stack trace omitted for brevity>
Run Code Online (Sandbox Code Playgroud)
从for循环中抛出异常:
for(Widget widget …Run Code Online (Sandbox Code Playgroud) 我有一个RESTful服务器实现以及一个供客户端进行调用的库,所有这些都使用JAX-RS。服务器组件分为接口FooResource和实现FooResourceService。
为了使客户端和服务器库共享RESTful路径和其他定义,我想将FooResource接口拆分为自己的项目:
@Path(value = "foo")
public interface FooResource {
@GET
public Bar getBar(@PathParam(value = "{id}") int id) {
Run Code Online (Sandbox Code Playgroud)
我想在响应中设置一些标题。一种简单的方法是@Context HttpServletResponse在方法签名中使用:
public Bar getBar(@PathParam(value = "{id}") int id, @Context HttpServletResponse servletResponse) {
Run Code Online (Sandbox Code Playgroud)
但是问题在于这暴露了接口中的实现细节。更具体地说,它突然需要我的REST定义项目(在客户端和服务器库之间共享)来引入javax.servlet-api依赖项-客户端不需要(或不需要)某些东西。
我的RESTful资源服务实现如何设置HTTP响应标头而不在资源接口中引入依赖关系?
我看到一篇推荐我将HttpServletResponse作为类成员注入的帖子。但是,如果我的资源服务实现是单例的,这将如何工作?它是否使用某种具有线程局部变量的代理,或者即使多个线程同时使用singleton类,也能找出正确的servlet响应的代理?还有其他解决方案吗?
我在下面有这样的设置。这是一个简化版本,但我认为它可以理解基本思想。我使用的是 Jersey 2.16、Java 1.8 和 Glassfish Open Source 4.1
public interface IReportService {
String addNewReport(Report report);
}
@Path("reports")
public class ReportResource implements IReportService {
/**
* Service layer.
*/
@EJB
private transient ReportService service;
@POST
@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Produces(MediaType.TEXT_PLAIN)
@Override
public String addNewReport(final Report report) {
return service.addNewReport(report);
}
}
@Stateless
@LocalBean
public class ReportService implements IReportService {
@EJB
private IReportPersistence reportPersistence;
@Context
SecurityContext secContext;
public String addNewReport(final Report report) {
report.setUserName(secContext.getUserPrincipal().getName());
reportPersistence.persist(report);
}
}
Run Code Online (Sandbox Code Playgroud)
但是当我部署并尝试访问 web 服务时,我从安全上下文中得到一个 NullPointer 异常。似乎根本没有注入 …
我正在通过添加单个标头来修改HttpRequest我WebFilter的request使用HttpServletRequestWrapper实现类:
HeaderMapRequestWrapper requestWrapper = new HeaderMapRequestWrapper(request);
requestWrapper.addHeader(OAuth.OAUTH_ACCESS_TOKEN, accessTokenWord);
chain.doFilter(requestWrapper, response);
Run Code Online (Sandbox Code Playgroud)
后doFilter(requestWrapper, response)进行,JAX-RS导致请求到它的资源,其具有@RequestScoped字段:
@Inject
protected HttpServletRequest request;
Run Code Online (Sandbox Code Playgroud)
但是,它不包含任何预期的标头:
@PostConstruct
protected void initialize_resources() throws IllegalStateException {
this.currentUser = null;
String accessToken = this.request.getHeader(OAuth.OAUTH_ACCESS_TOKEN);
AccessToken accessToken = this.memcachedResources.getMemcachedAccessTokenRepository()
.get(accessToken);
if (accessToken != null && StringUtils.isNotEmpty(accessToken.getUser_id())) {
this.currentUser = this.em.find(User.class, accessToken.getUser_id());
this.currentClient = accessToken.getClientId();
}
}
Run Code Online (Sandbox Code Playgroud)
所以,this.request.getHeader(OAuth.OAUTH_ACCESS_TOKEN)是的null.
我怎么解决这个问题?
我有一个流程,在CXF客户端上我安装了拦截器,提供程序和异常映射器。就我而言,我正在通过拦截器捕获来自客户端的不良响应,然后我想中止cxf总线链并引发故障。不幸的是我做不到,因为在任何情况下都只记录从拦截器抛出的异常,但是主要错误(错误的json格式)会传播到异常映射器。我想避免使用异常映射器,但是我不知道怎么做。我正在使用WebClient来实现这样的拦截器:
@Component
public class MyInterceptor extends AbstractPhaseInterceptor<Message> {
public MyInterceptor() {
super(POST_STREAM);
}
@Override
public void handleMessage(Message message) throws Fault {
if (message != null) {
//message.getExchange().setOneWay(true);
//message.getExchange().put(Exception.class, new MyException());
//message.getInterceptorChain().abort();
//message.setContent(Exception.class, new MyException());
//Endpoint ep = message.getExchange().get(Endpoint.class);
//message.getInterceptorChain().abort();
//if (ep.getInFaultObserver() != null) {
// ep.getInFaultObserver().onMessage(message);
//}
//throw new WebApplicationException( new MyException());
//message.setContent(Response.class, response);
throw new Fault(new MyException());
}
}
Run Code Online (Sandbox Code Playgroud)
我读到我应该实现jaxrs-filter,因为拦截器抛出的异常不会传播到异常映射器。由于WebClient的实现,在Java中有什么方法可以做到吗?
S client = create(url, clazz, list(jsonProvider(), providers));
WebClient.getConfig(client).getInInterceptors().add(new MyInterceptor());
Run Code Online (Sandbox Code Playgroud)
我也尝试过在拦截器上使用不同的阶段,但是也没有用。
当多个用户从服务类请求相同的资源方法时,如何在服务器上处理请求?
如何为每个请求执行休息服务?休息服务的执行生命周期与servlet执行有何不同?
例如,如果下面是资源,它将如何在以下场景中实例化和执行:
案例1:两个用户一次调用两种不同的方法
情况2:两个用户一次调用相同的方法
@Path("greet")
public class GreetingResource {
@GET
@Path("welcome/{username}")
@Produces(MediaType.TEXT_PLAIN)
public String sayWelcome(@PathParam("username") String User) {
return "Welcome!" + User;
}
@GET
@Path("hello/{username}")
@Produces(MediaType.TEXT_PLAIN)
public String sayHello(@PathParam("username") String User) {
return "Hello " + User;
}
}
Run Code Online (Sandbox Code Playgroud) jax-rs ×10
java ×9
rest ×3
java-ee ×2
jersey ×2
json ×2
cxf ×1
dropwizard ×1
ejb ×1
filestream ×1
generics ×1
glassfish ×1
httpresponse ×1
interceptor ×1
jackson ×1
jakarta-ee ×1
java-ee-7 ×1
jaxb ×1
lifecycle ×1
outputstream ×1
resteasy ×1
servlets ×1
web-services ×1