CookieParam in RESTEasy Singleton - java

I'm injecting my cookie param in that way (using javax.ws.rs.CookieParam)
#CookieParam("parameterCookie")
private String parameterCookie;
i have a problem to inject that parameter using Resteasy
ERROR
It is illegal to inject a #CookieParam into a singleton
That is a BaseResource and i can't modify all resources to accept that paramenter on all methods (it costs a lot). How could i inject that CookieParam in Resteasy without modify all resources?

You can work around this by injecting HttpHeaders instead:
import org.jboss.resteasy.core.Dispatcher;
import org.jboss.resteasy.mock.MockDispatcherFactory;
import org.jboss.resteasy.mock.MockHttpRequest;
import org.jboss.resteasy.mock.MockHttpResponse;
import org.junit.Before;
import org.junit.Test;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
public class CookieTest {
static final String COOKIE_NAME = "parameterCookie";
Dispatcher dispatcher;
#Before
public void setUp() throws Exception {
dispatcher = MockDispatcherFactory.createDispatcher();
dispatcher.getRegistry().addSingletonResource(new Resource());
}
#Test
public void name_StateUnderTest_ExpectedBehavior() throws Exception {
String cookieValue = String.valueOf(System.currentTimeMillis());
MockHttpResponse response = new MockHttpResponse();
MockHttpRequest request = MockHttpRequest.get("/")
.cookie(COOKIE_NAME, cookieValue);
dispatcher.invoke(request, response);
assertThat(response.getContentAsString(), is(COOKIE_NAME + "=" + cookieValue));
}
#Path("/")
public static class Resource {
#Context HttpHeaders headers;
#GET #Path("/")
public String getCookie(){
return headers.getCookies().get(COOKIE_NAME).toString();
}
}
}

Related

Spring #Autowired restTemplate is null [duplicate]

This question already has answers here:
Why is my Spring #Autowired field null?
(21 answers)
Closed 4 years ago.
I am new to Spring. I develop Service that Consuming RESTful service with certficate using Java
Here is my Config class:
package configuration;
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.util.ResourceUtils;
import org.springframework.web.client.RestTemplate;
import javax.net.ssl.SSLContext;
import java.util.function.Supplier;
#Configuration
public class RestClientCertConfig {
private char[] allPassword = "allpassword".toCharArray();
#Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) throws Exception {
SSLContext sslContext = SSLContextBuilder
.create()
.loadKeyMaterial(ResourceUtils.getFile("classpath:keystore.jks"), allPassword, allPassword)
.loadTrustMaterial(ResourceUtils.getFile("classpath:truststore.jks"), allPassword)
.build();
HttpClient client = HttpClients.custom()
.setSSLContext(sslContext)
.build();
return builder
.requestFactory((Supplier<ClientHttpRequestFactory>)new HttpComponentsClientHttpRequestFactory(client))
.build();
}
}
And here is the class where I consume Restful EndPoint:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import java.net.URISyntaxException;
import java.util.Collections;
public class ECSConfigGet {
private static final String ECS_API_URI = "<RestEndPointToConsume";
#Autowired
private static RestTemplate restTemplate;
public static void main(String[] args) {
try {
makeECSCall("myTestHeaderValue");
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
private static void makeECSCall(String entityCode) throws RestClientException, URISyntaxException {
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
headers.set("entityCode", entityCode);
HttpEntity<String> entity = new HttpEntity<>("parameters", headers);
ResponseEntity responseEntity = restTemplate.exchange(ECS_API_URI, HttpMethod.GET, entity, String.class);
}
}
Did I completely misunderstood the concept? I would expect restTemplate would not be null with all the Annotations I use. Thank for any help!
NullPointerException is fixed. ECSConfigGet looks like:
package main;
import configuration.RestClientCertConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import services.modelsdto.ExpenseConfigDTO;
import java.util.Collections;
#SpringBootApplication
#Component
public class ECSConfigGet implements CommandLineRunner{
//API to call
private static final String ECS_API_URI = "<API_TO_CONSUME>";
#Autowired
private RestTemplate restTemplate;
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(RestClientCertConfig.class);
applicationContext.getBean(RestTemplate.class);
SpringApplication.run(ECSConfigGet.class, args);
}
private void makeECSCall(String entityCode) throws RestClientException {
ExpenseConfigDTO expenseConfigDTO = new ExpenseConfigDTO();
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
headers.set("entityCode", entityCode);
HttpEntity<String> entity = new HttpEntity<>("parameters", headers);
ResponseEntity responseEntity = restTemplate.exchange(ECS_API_URI, HttpMethod.GET, entity, String.class);
}
#Override
public void run(String... args) {
for (int i = 0; i < args.length; ++i) {
makeECSCall("myTestHeaderValue");
}
}
}
You're missing a bit of Spring boilerplate that you need to make #Autowired work. If you're using Spring Boot, you're close, but #Patrick is right generally: ECSConfigGet needs to be a bean by annotating it correctly, but you also need to run your application within an application context in order for any of the Spring magic to happen. I suggest checking out this tutorial on how to use Spring Boot in a command line application.
The high level is ECSConfigGet needs to be annotated with #SpringBootApplication and then have it implement CommandLineRunner and then from the run method, you will have access to the #Autowired component. Spring will instantiate ECSConfigGet and populate the properties. Also as #Roddy pointed out, RestTemplate cannot be static, either.
The ECSConfigGet class is not a bean so it can not autowire a component.
Add #Component as class annotation to ECSConfigGet

Java JAX-RS Name Binding Not working

I am working on an authentication filter for my REST service.
Can some one please explain why this name binding not works.
When I make a post request, I can receive the String "Tokenized", but log does not print "Inside the filter".
import java.io.IOException;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.FormParam;
import javax.ws.rs.NameBinding;
import javax.ws.rs.Produces;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import java.lang.annotation.Target;
import javax.annotation.Priority;
import javax.ws.rs.NotAuthorizedException;
import javax.ws.rs.Priorities;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.ext.Provider;
import org.apache.log4j.Logger;
#Path("/authentication")
public class AuthenticationHandler {
final static Logger log = Logger.getLogger(AuthenticationHandler.class);
#NameBinding
#Retention(RUNTIME)
#Target({TYPE, METHOD})
public #interface Secured {
}
#Secured
#Provider
#Priority(Priorities.AUTHENTICATION)
public class AuthenticationFilter implements ContainerRequestFilter {
#Override
public void filter(ContainerRequestContext requestContext) throws IOException {
log.info("Inside the filter");
// Get the HTTP Authorization header from the request
String authorizationHeader
= requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);
// Check if the HTTP Authorization header is present and formatted correctly
if (authorizationHeader == null || !authorizationHeader.startsWith("Bearer ")) {
throw new NotAuthorizedException("Authorization header must be provided");
}
// Extract the token from the HTTP Authorization header
String token = authorizationHeader.substring("Bearer".length()).trim();
try {
// Validate the token
validateToken(token);
} catch (Exception e) {
requestContext.abortWith(
Response.status(Response.Status.UNAUTHORIZED).build());
}
}
private void validateToken(String token) throws Exception {
// Check if it was issued by the server and if it's not expired
// Throw an Exception if the token is invalid
}
}
#POST
#Secured
#Path("/request_token")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response authenticateUser(#FormParam("username") String username,
#FormParam("password") String password) {
try {
// Authenticate the user using the credentials provided
authenticate(username, password);
// Issue a token for the user
String token = issueToken(username);
// Return the token on the response
return Response.ok(token).build();
} catch (Exception e) {
return Response.status(Response.Status.UNAUTHORIZED).build();
}
}
private boolean authenticate(String username, String password) throws Exception {
return true;
}
private String issueToken(String username) {
return "Tokenized";
}
}
Thanks for the tip peeskillet.
It is now working fine after creating separate classes for Name Bind and Filter. I'm posting the solution below if anyone required.
My problem now is, is there a way to keep this two classes in a separate package, because I tried by putting it on my Util package and it didn't work properly.
peeskillet : Thanks for the tip again.
AuthenticationFilter.java
import com.binosaurs.sf.backend.handler.Secured;
import com.binosaurs.sf.backend.util.*;
import java.io.IOException;
import javax.annotation.Priority;
import javax.ws.rs.NotAuthorizedException;
import javax.ws.rs.Priorities;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;
import org.apache.log4j.Logger;
#Secured
#Provider
#Priority(Priorities.AUTHENTICATION)
public class AuthenticationFilter implements ContainerRequestFilter {
// Get Log4j Logger
final static Logger log = Logger.getLogger(AuthenticationFilter.class);
#Override
public void filter(ContainerRequestContext requestContext) throws IOException {
log.info("Inside the filter");
// Get the HTTP Authorization header from the request
String authorizationHeader
= requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);
// Check if the HTTP Authorization header is present and formatted correctly
if (authorizationHeader == null || !authorizationHeader.startsWith("Bearer ")) {
throw new NotAuthorizedException("Authorization header must be provided");
}
// Extract the token from the HTTP Authorization header
String token = authorizationHeader.substring("Bearer".length()).trim();
try {
// Validate the token
validateToken(token);
} catch (Exception e) {
requestContext.abortWith(
Response.status(Response.Status.UNAUTHORIZED).build());
}
}
private void validateToken(String token) throws Exception {
// Check if it was issued by the server and if it's not expired
// Throw an Exception if the token is invalid
}
}
Secured.java
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.binosaurs.sf.backend.handler;
import com.binosaurs.sf.backend.util.*;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Target;
import javax.ws.rs.NameBinding;
#NameBinding
#Retention(RUNTIME)
#Target({TYPE, METHOD})
public #interface Secured {
}
AuthenticationHandler.java
package com.binosaurs.sf.backend.handler;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.FormParam;
import javax.ws.rs.Produces;
import org.apache.log4j.Logger;
#Path("/authentication")
public class AuthenticationHandler {
final static Logger log = Logger.getLogger(AuthenticationHandler.class);
#POST
#Secured
#Path("/request_token")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response authenticateUser(#FormParam("username") String username,
#FormParam("password") String password) {
try {
// Authenticate the user using the credentials provided
authenticate(username, password);
// Issue a token for the user
String token = issueToken(username);
// Return the token on the response
return Response.ok(token).build();
} catch (Exception e) {
return Response.status(Response.Status.UNAUTHORIZED).build();
}
}
private boolean authenticate(String username, String password) throws Exception {
return true;
}
private String issueToken(String username) {
return "Tokenized";
}
}

Access springbeans in JerseyTest with Jersey2.0

I have jersey project with spring. Now My test is deriverd from JerseyTest. When I try to do
#AutoWired
RestTemplate restTemplate;
It looks like spring is not working in jersey test. I did some research and found some links like
spring_jersey
but it did not work ,since I am using jersey2.0.
My code looks like
//AbstractTest
package com.test;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Application;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.filter.LoggingFilter;
import org.glassfish.jersey.jackson.JacksonFeature;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.glassfish.jersey.server.ServerProperties;
import org.glassfish.jersey.server.validation.ValidationFeature;
public abstract class AbstractTest extends JerseyTest
{
protected WebTarget getRootTarget(final String rootResource)
{
return client().target(getBaseUri()).path(rootResource);
}
#Override
protected final Application configure()
{
final ResourceConfig application = configureApplication();
// needed for json serialization
application.register(JacksonFeature.class);
// bean validation
application.register(ValidationFeature.class);
// configure spring context
application.property("contextConfigLocation", "classpath:/META-INF/applicationContext.xml");
// disable bean validation for tests
application.property(ServerProperties.BV_FEATURE_DISABLE, "true");
return application;
}
protected abstract ResourceConfig configureApplication();
#Override
protected void configureClient(final ClientConfig config)
{
// needed for json serialization
config.register(JacksonFeature.class);
config.register(new LoggingFilter(java.util.logging.Logger.getLogger(AbstractResourceTest.class.getName()), false));
super.configureClient(config);
}
}
package com.test;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.content;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;
import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
//MyTest
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;
import org.apache.commons.io.IOUtils;
import org.glassfish.jersey.server.ResourceConfig;
import org.junit.Before;
import org.junit.Test;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.test.web.client.MockRestServiceServer;
import org.springframework.test.web.client.match.MockRestRequestMatchers;
import org.springframework.web.client.RestTemplate;
import junit.framework.Assert;
public final class MyTest extends AbstractTest
{
private static final String ROOT_RESOURCE_PATH = "/testUrl";
#AutoWired
private RestTemplate restTemplate;
private MockRestServiceServer mockServer;
#Before
public void setup(){
this.restTemplate = new RestTemplate();
this.mockServer = MockRestServiceServer.createServer(restTemplate);
}
#Test
public void testPostWithString() {
WebTarget target = getRootTarget(ROOT_RESOURCE_PATH).path("");
String entityBody = new String();
entityBody = " My test data";
final javax.ws.rs.client.Entity<String> entity = javax.ws.rs.client.Entity.entity(entityBody, "text/plain");
mockServer.expect(MockRestRequestMatchers.requestTo(ROOT_RESOURCE_PATH)).andExpect(method(HttpMethod.POST)).andExpect(content().string(entityBody))
.andRespond(withSuccess("resultSuccess", MediaType.TEXT_PLAIN));
final Response response = target.request().post(entity);
Assert.assertNotNull("Response must not be null", response.getEntity());
Assert.assertEquals("Response does not have expected response code", 200, response.getStatus());
System.out.println("Response = " + response.getEntity());
String data = response.readEntity(String.class);
System.out.println("Response = " + data);
if(response.ok() != null)
{
System.out.println("Ok");
}
}
}
Update:
public class SimpleJerseyTest extends ApplicationContextAwareJerseyTest {
private static final String ROOT_RESOURCE_PATH = "/test";
#Override
public void configureApplication(ResourceConfig config) {
config.register(MyApp.class);
config.register(new LoggingFilter(Logger.getAnonymousLogger(), true));
}
#Before
public void setUp() {
try{
((ConfigurableApplicationContext)this.applicationContext).refresh();
super.setUp();
}catch(Exception e){
}
this.mockServer = MockRestServiceServer.createServer(restTemplate);
}
#Autowired
private RestTemplate restTemplate;
private MockRestServiceServer mockServer;
#Test
public void doitOnce() {
WebTarget target = target(ROOT_RESOURCE_PATH);
String entityBody = new String();
final javax.ws.rs.client.Entity<String> entity = javax.ws.rs.client.Entity.entity(entityBody, "text/plain");
mockServer.expect(MockRestRequestMatchers.requestTo(ROOT_RESOURCE_PATH)).andExpect(method(HttpMethod.POST)).andExpect(content().string(entityBody))
.andRespond(withSuccess("resultSuccess", MediaType.TEXT_PLAIN));
final Response response = target.request().post(entity);
System.out.println("Response = " + response.getEntity());
String data = response.readEntity(String.class);
System.out.println("Response = " + data);
if(response.ok() != null)
{
System.out.println("Ok");
}
}
}
I have added bean in
src/test/resources/META-INF/applicationContext.xml
<!-- Our REST Web Service client -->
<bean id="restTemplate" class="org.springframework.web.client.RestTemplate"/>
Same bean I have added in
src/main/resources/META-INF/applicationContext.xml
!-- Our REST Web Service client -->
<bean id="restTemplate" class="org.springframework.web.client.RestTemplate"/>
Instead of configuring Spring like this
application.property("contextConfigLocation", "classpath:/META-INF/applicationContext.xml");
You can instead use
application.property("contextConfig", <ApplicationContext>);
This way you can have an instance of the ApplicationContext, where you can get the AutowireCapableBeanFactory. With this, you can just call acbf.autowireBean(this) to inject the test class.
Here's what I mean. I tested it, and it works find for simple cases. Won't work well though if the beans you are trying to inject aren't singletons, as new one will be create for the test and where ever else you try to inject to in your application code
public abstract class ApplicationContextAwareJerseyTest extends JerseyTest {
protected ApplicationContext applicationContext;
#Override
protected final ResourceConfig configure() {
final ResourceConfig config = new ResourceConfig();
configureApplication(config);
this.applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
config.property("contextConfig", this.applicationContext);
final AutowireCapableBeanFactory bf = this.applicationContext.getAutowireCapableBeanFactory();
bf.autowireBean(this);
return config;
}
public final ApplicationContext getApplicationContext() {
return this.applicationContext;
}
protected void configureApplication(ResourceConfig resourceConfig) {};
}
One thing I am not sure about though is how the resetting would work. I tried to add
#Before
public void setUp() throws Exception {
((ConfigurableApplicationContext)this.applicationContext).refresh();
super.setUp();
}
into the abstract class, but that doesn't seem to work as expected. The test I used is as follows
public class SimpleJerseyTest extends ApplicationContextAwareJerseyTest {
#Path("test")
public static class SimpleResource {
#Autowired
private MessageService service;
#GET
public String getMessage() {
return this.service.getMessage();
}
}
#Override
public void configureApplication(ResourceConfig config) {
config.register(SimpleResource.class);
config.register(new LoggingFilter(Logger.getAnonymousLogger(), true));
}
#Before
public void before() {
assertEquals("Hello World", messageService.getMessage());
}
#Autowired
private MessageService messageService;
#Test
public void doitOnce() {
messageService.setMessage("BOOYAH");
final Response response = target("test").request().get();
assertEquals("BOOYAH", response.readEntity(String.class));
}
#Test
public void doitTwice() {
messageService.setMessage("BOOYAH");
final Response response = target("test").request().get();
assertEquals("BOOYAH", response.readEntity(String.class));
}
}
The result I would get for the second test is that the value of the service message was the default message "Hello World", even though I set the message to "BOOYAH". This tells me that there is a stale service in the application, which is not the same one being injected into the test. The first test works fine though. Without resetting, the second test would work fine also, but you are left with modified services in each test, which makes the test not self-contained.

How can to send request from RestyGWT part to another server project?

I have restyGWT+GXT project, that send request to server project (Spring Boot), so, my restyGWT+GXT part:
buiid.gradle:
...
compile 'org.fusesource.restygwt:restygwt:2.0.3'
compile 'javax.ws.rs:jsr311-api:1.1.1'
my rest service in restyGWT+GXT part:
import org.fusesource.restygwt.client.MethodCallback;
import org.fusesource.restygwt.client.RestService;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.List;
public interface LoadHelloService extends RestService {
#GET
#Path("/rest/loadHelloService")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public void loadHelloService(MethodCallback<List<Hello>> callback);
}
bean Hello.java:
public class Hello {
private final String id;
private final String name;
#JsonCreator
public Hello(#JsonProperty("id") String id, #JsonProperty("name") String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
}
in MainMenuPage (implements IsWidget):
on click menuButton1 send request to server project (Spring Boot):
#UiHandler("menuButton1")
void selectOnMenu1(SelectEvent event) {
...
restServerLoader.loadHelloListFromServer();
}
so, RestServerLoader class with method loadHelloListFromServer:
import com.google.gwt.core.client.GWT;
import com.sencha.gxt.widget.core.client.box.MessageBox;
import org.fusesource.restygwt.client.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class RestServerLoader {
public void loadHelloListFromServer() {
String pageBaseUrl = "http://127.0.0.1:8080/";
Defaults.setServiceRoot(pageBaseUrl);
Map<String, String> headers = new HashMap<>();
headers.put("Access-Control-Allow-Methods", "GET");
Resource resource = new Resource(Defaults.getServiceRoot(), headers);
LoadHelloService service = GWT.create(LoadHelloService.class);
((RestServiceProxy)service).setResource(resource);
service.loadHelloService(new MethodCallback<List<Hello>>() {
public void onSuccess(Method method, List<Hello> response) {
MessageBox messageBox = new MessageBox("response (list) = " + response.toString());
messageBox.show();
//code your stuff here
}
public void onFailure(Method method, Throwable exception) {
MessageBox messageBox = new MessageBox("exception = " + exception);
messageBox.show();
//code your stuff here
}
});
}
}
So, and when I send request loadHelloService I have: org.fusesource.restygwt.client.FailedStatusCodeException: status code 0.
:(((((((
my server part (Spring Boot) rest:
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.List;
#Path("/")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public class HelloResource {
#Context
private HttpServletResponse response;
#OPTIONS
#Path("loadHelloService") //The response for the preflight request made implicitly by the bowser
public Response loadHelloPreflight() {
Response response = Response.ok()
.header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Methods", "POST, GET, UPDATE, OPTIONS")
.header("Access-Control-Allow-Headers", "*")
.header("Access-Control-Max-Age", "18000").build();
return response;
}
#GET
#Path("loadHelloService")
public List<Hello> loadHelloList() {
response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Allow-Methods", "POST, GET, UPDATE, OPTIONS");
response.addHeader("Access-Control-Allow-Headers", "*");
List<Hello> list = new ArrayList<>();
list.add(new Hello("1", "ronan"));
list.add(new Hello("2", "john"));
return list;
}
}
so, When I send request, I input method loadHelloPreflight, but when send request to loadHelloList I have: org.fusesource.restygwt.client.FailedStatusCodeException: status code 0., Why??? :((, When I send request to server part (Spring Boot) from browser Postman Client - all good!, I get list of hellos, but I want do it from restyGWT+GXT part :((( Help me, please.
Did you forget some cors headers like below ?
.header("Access-Control-Allow-Headers", "x-http-method-override");

Test Spring-Rest Service with embedded Jetty

i want to create an embedded jetty server (not maven, gradle etc.) to test a spring rest service.
Therefor i created an EmbeddedServer class. But unfortunately invocation of the rest service leads always to an http 404 error. What doing wrong?
The rest service works fine with tomcat (not embedded).
Im using the following dependencies:
"org.eclipse.jetty:jetty-server:8.1.17.v20150415"
"org.eclipse.jetty:jetty-webapp:8.1.17.v20150415"
Here is the EmbededServer class:
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.webapp.WebAppContext;
public class EmbeddedServer {
private Server server;
public void start() throws Exception {
this.server = createServer();
this.server.start();
}
public void stop() throws Exception {
this.server.stop();
this.server.join();
this.server.destroy();
}
private Server createServer() {
final Server server = new Server(8080);
final WebAppContext context = new WebAppContext();
context.setContextPath("/");
context.setResourceBase("src/main/webapp");
context.setDescriptor("src/main/webapp/WEB-INF/web.xml");
context.setParentLoaderPriority(true);
context.setServer(server);
server.setHandler(context);
return server;
}
}
And the test class:
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.net.URI;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertThat;
public class SimpleTest {
private HttpClient client;
private EmbeddedServer server;
#Before
public void before() throws Exception {
this.client = new DefaultHttpClient();
this.server = new EmbeddedServer();
this.server.start();
}
#After
public void after() throws Exception {
this.server.stop();
}
#Test
public void invokeHello() throws Exception {
final HttpResponse response = invokeGetRequest("http://localhost:8080/hello");
verifyResponse(response, 200, "hello");
}
private HttpResponse invokeGetRequest(final String path) throws Exception {
final URI wsAddress = new URI(path);
final HttpGet method = new HttpGet(wsAddress);
return this.client.execute(method);
}
private void verifyResponse(final HttpResponse actualHttpResponse, final int expectedHttpCode, final String expectedResponse) throws IOException {
assertThat(actualHttpResponse.getStatusLine().getStatusCode(), equalTo(expectedHttpCode));
final String actualResponse = EntityUtils.toString(actualHttpResponse.getEntity(), "UTF-8");
assertThat(actualResponse, equalTo(expectedResponse));
}
}
This test fails with:
java.lang.AssertionError:
Expected: <200>
but: was <404>
Path of ResourceBase and Descriptor must be absolute.
context.setResourceBase("c:/myapp/src/main/webapp");
context.setDescriptor("c:/myapp/src/main/webapp/WEB-INF/web.xml");

Categories