i have some problems with angularJS and REST requests / responses. Since three weeks i playing with AngularJS and now i would like do some cool stuff.
First i created a simple jersey REST service, that returns a simple list.
#Path("/hello")
public class Hello {
#GET
#Produces(MediaType.APPLICATION_JSON)
public List<Medication> sayJsonHello() {
List<Object1> objs = new ArrayList<Object1>();
objs.add(new Object1("1", "HUHU"));
objs.add(new Object1("2", "HUHU 2"));
return objs;
}
}
as you can see, there is no big magic.
Here my web.xml file, to configure Jersey:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>Jersey REST Example</display-name>
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>examples</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.feature.DisableWADL</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
After some tests, the service will return a simple JSON list:
[
{
"id": "1",
"name": "HUHU"
},
{
"id": "2",
"name": "HUHU 2"
}
]
I deploying the webservice into a Tomcat7 instance. Now i would like to get this data into my webapplication. After reading some tutorials and example i starting to create few implementations.
After starting create my first service, i and this code-snipped into my app.js:
app.config(['$httpProvider', function ($httpProvider) {
delete $httpProvider.defaults.headers.common["X-Requested-With"];
}]);
this will remove X-Request-With request-header from the header defauls.
1. Request via Service and ngResource
angular.module('helloService', ['ngResource']).
factory('hService', function ($resource) {
return $resource('http://localhost\\:8180/rest/hello',
{callback: 'JSON_CALLBACK'}, {
get: {method: 'GET', headers: [
{'Content-Type': 'application/json'},
{'Accept': 'application/json'}
]}
});
});
MyController:
function MyController($scope, hService) {
hService.get(function(result){
alert(" Result of helloService");
}, function error(response){
alert(" Error during helloService "+response.status);
});
}
if i try to load data, the get functin will always return an error and the status is always 0.
2. Trying with Restangular
After get how to use Restangular i starting to configured Restangular:
app.config(function (RestangularProvider) {
RestangularProvider.setBaseUrl('http://localhost\\:8180/rest');
});
and also add the RestangularProvider to my angular.module:
var app = angular.module("html5App", ['helloService', 'restangular', 'ngResource']);
MyController:
function MyRestangularCtr($scope, Restangular){
var all = Restangular.all('hello');
$scope.allObjects = all.getList();
all.getList().then(function (hellos) {
console.log("Result "+ hellos);
}, function errorCallback(response) {
alert("Oops error from server :( status" + response.status);
console.log("status: "+response);
});
}
Here the same: No Data, Status 0. I have no idea, why i dont get any data from my service. Additional i getting sometimes this error: "Error: $digest already in progress". Im not sure, where the problem is. If the jersey service i wrong or bad or my beginner JavaScript is wrong.
First Solution
Client Side
The Angular request should look like this:
$scope.myData = $resource('http://localhost\\:8180/rest/:action',
{action: 'hello', callback:'JSON_CALLBACK'},
{get: {method: 'JSONP'}});
$scope.datas = $scope.myData.get();
The method need to JSONP (GET will still not working ( no repsonse data because CORPS?)
Service Side
Important here is, that the server also response with a JSONP fomat and can handle callback requests.
#GET
#Produces("application/x-javascript")
public JSONWithPadding sayJsonHello(#QueryParam("callback") String callback) {
MyObjectList obList= new MyObjectList ();
obList.getObjs().add(new MyObject(1, "HUHU"));
obList.getObjs().add(new MyObject(2, "HUHU 2"));
return new JSONWithPadding(obList, callback);
}
Still unclear
Is there any way to return normal json object from server to client?
Shouldn't be the first parameter of you controller be $scope? Maybe this is the issue?
function MyController($scope, hService) {
Related
I have a jetty servlet set of pages all set up and working.
to get to the landing page, you have to enter the full url http://127.0.0.1/console/console.jsp
everything is fine for my context "console".
I wanted to add a handler for the root url, so I could just put in a host and it would redirect to the above url.
I got that working, except it seems that every request comes through my root path handler as well and it messes up all the other requests to the real jsp pages.
How do I keep it from doing that, or what do I do differently?
my web.xml...
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<servlet>
<description></description>
<servlet-name>console</servlet-name>
<servlet-class>net.console.Consoleservlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>console</servlet-name>
<url-pattern>/console</url-pattern>
</servlet-mapping>
<servlet>
<description></description>
<servlet-name>redirect</servlet-name>
<servlet-class>net.console.Redirectservlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>redirect</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
slimmed down version of my redirect servlet...
public class Redirectservlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet
{
static final long serialVersionUID = 1L;
public Redirectservlet()
{
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
try
{
String redirect_path = "http://127.0.0.1/console/console.jsp";
response.sendRedirect(redirect_path);
}
catch (Exception e)
{
}
}
Try using welcome-files instead of your RedirectServlet, in your WEB-INF/web.xml...
<web-app ...>
<welcome-file-list>
<welcome-file>console/console.jsp</welcome-file>
</welcome-file-list>
... other entries
</web-app>
If that doesn't work, consider making that a RedirectFilter instead, and only sending a redirect if the request.getRequestURI() is only in a list of exact request URI string matches that should redirect.
I am trying to integrate Jersey 2.22.1 with IBM WAS 8.5.4.I have a couple of JAX-RS resources under a certain package (com.innovation.postdata.integration.rest.test.jersey.resources).One of the JAX-RS resource is shown below:
import javax.ws.rs.Consumes;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
#Path("/service")
public class FileSubmissionTestRestService
{
#PUT
#Consumes({ "text/csv" })
#Path("/file")
public Response submitBordereaux (#QueryParam("forceResponse") String forceResponse)
{
if (forceResponse != null && !"".equals (forceResponse))
{
switch (forceResponse)
{
case "404":
return Response.status (Response.Status.NOT_FOUND).entity ("Resource Not Found!").build ();
case "401":
return Response.status (Response.Status.UNAUTHORIZED).entity ("Unauthorized user!").build ();
case "403":
return Response.status (Response.Status.FORBIDDEN).entity ("User not allowed!").build ();
case "405":
return Response.status (Response.Status.METHOD_NOT_ALLOWED).entity ("Unsupported HTTP method!").build ();
case "415":
return Response.status (Response.Status.UNSUPPORTED_MEDIA_TYPE)
.entity ("Media type not supported.It should be TEXT/CSV or APPLICATION/JSON!").build ();
case "500":
return Response.status (Response.Status.INTERNAL_SERVER_ERROR).entity ("Error occured on server!").build ();
default:
return Response.status (Response.Status.NO_CONTENT).build ();
}
}
return Response.status (Response.Status.INTERNAL_SERVER_ERROR).entity ("Error occured on server!").build ();
}
}
and I added a entry in web.xml as shown below
<servlet>
<servlet-name>JAX-RS REST Servlet</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.innovation.postdata.integration.rest.test.jersey.resources</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>JAX-RS REST Servlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
I also added a custom run time property(com.ibm.websphere.jaxrs.server.DisableIBMJAXRSEngine) and set it to true in WAS to disable default WAS JAX-RS implementation.The JAX-RS resources (under com.innovation.postdata.integration.rest.test.jersey.resources) are packaged in a separate jar that is added to the main EAR WEB-INF/lib when packaging the EAR. When I start WAS I get to see only this in the start up logs:
[1/5/16 0:27:24:106 GMT-05:00] 00000070 ServletWrappe I
com.ibm.ws.webcontainer.servlet.ServletWrapper init SRVE0242I:
[InnovationInsurer] [/Jasper] [JAX-RS REST Servlet]: Initialization
successful.
No where it says that it tried to scan the resource packages or anything like this.Just this.The jars I am using are:
hk2-api-2.4.0-b31.jar
hk2-locator-2.4.0-b31.jar
hk2-utils-2.4.0-b31.jar
javax.annotation-api-1.2.jar
javax.inject-2.4.0-b31.jar
javax.ws.rs-api-2.0.1.jar
jersey-client-2.22.1.jar
jersey-common-2.22.1.jar
jersey-container-servlet-core-2.22.1.jar
jersey-guava-2.22.1.jar
jersey-media-jaxb-2.22.1.jar
jersey-server-2.22.1.jar
osgi-resource-locator-1.0.1.jar
javassist-3.12.0.GA.jar
aopalliance-1.0.jar
I am using Postman Rest Client to access the JAX-RS at http://10.2.64.3:9080/Jasper/rest/service/file?forceResponse=403 but I am always getting 200 OK which is wrong.Can anybody please help me out as to what could be the reason for this? Why is not even trying to scan the package and only saying servlet successfully initialized.
As far as I know, there is a bug in Websphere that prevent package scanning to work correctly (it works only if the classes are under WEB-INF/classes, not from WEB-INF/lib).
Some informations here: https://developer.ibm.com/answers/questions/169221/packagesresourceconfig.html
I've workarounded that issue using:
public class MyRestApplication extends ResourceConfig {
public MyRestApplication() {
register(DefaultExceptionMapper.class);
register(ConstraintViolationExceptionExceptionMapper.class);
register(JacksonJsonProvider.class);
// does not work in IBM WAS 8.5.5 full profile: see it here
// https://developer.ibm.com/answers/questions/169221/packagesresourceconfig.html
// and
// http://www-01.ibm.com/support/docview.wss?rs=180&uid=swg1PM99378
// packages(getClass().getPackage().getName(), LookupEndpoint.class.getPackage().getName());
// Works under WAS 8.5
registerClasses(LookupEndpoint.class, XEndpoint.class, YEndpoint.class);
}
}
and
<servlet>
<servlet-name>jersey_v2-servlet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>x.y.z.MyRestApplication</param-value>
</init-param>
<init-param>
<param-name>jersey.config.beanValidation.enableOutputValidationErrorEntity.server</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
That is obviously not optimal (you must maintain yourself the list of endpoints to be used) but at least it works.
I had written a very small rest service. When I am trying through the rest cilent, I am getting the error as "method not supported". Can anybody, please suggest me on this.
**controller class**
#Controller
#RequestMapping("/movie")
public class MovieController {
#RequestMapping(value="/{name}", method = RequestMethod.PUT, consumes="application/json")
public #ResponseBody Student getMovie(#PathVariable String name, ModelMap model, #RequestBody Student student, HttpSession session) {
Map<Integer, Student> empData = new HashMap<Integer, Student>();
empData.put(1, student);
return student;
}
}
**Request I am sending throught Rest DHC Client**
URL: http://localhost:8081/SpringMVC/movie/test
method selected: PUT
Headers: Content-Type:application/json
Body: {
"userId":"21",
"firstName":"srinu",
"lastName":"nivas"
}
I use only Jersey to do what you want.
My web.xml file is:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.0" 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">
<display-name>appName</display-name>
<filter>
<filter-name>jersey</filter-name>
<filter-class>com.sun.jersey.spi.container.servlet.ServletContainer</filter-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.appName.rest</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.property.JSPTemplatesBasePath</param-name>
<param-value>/Pages/</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.property.WebPageContentRegex</param-name>
<param-value>/(resources|(Pages))/.*</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>jersey</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
And in the rest class i return a Viewable:
My rest class:
#GET
#Path("/PathToAccessPage")
#Produces(MediaType.TEXT_HTML)
public Viewable GetMyClassPage(#Context HttpServletRequest request, #Context UriInfo ui, #Context HttpHeaders hh) {
try {
MyClass myClass = getMyClass();
return new Viewable("/page", myClass);
}
catch (Exception ex) {
return new Viewable("/error", "Error processing request: " + ex.getMessage());
}
}
Hope you help!
Finally, I got the solution. I didn't import the below two jars.
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
As I am using spring MVC and as you can see in the above code, I am giving as consumes=application/json, I thought springMVC will take care of that. It's my mistake and also, I think the error which was renedered by spring, should be something specific to this. Anyway, got the solution. Thanks all for the help.
I am just trying out a sample rest service example. My rest service class is :
#Path("oauth")
public class OauthClass {
private static Map<String, OauthBean> oAuthBeanMap = new HashMap<String, OauthBean>();
static {
OauthBean oAuthBean = new OauthBean();
oAuthBean.setAccess_token(String.valueOf(Math.random()));
oAuthBean.setToken_type("bearer");
oAuthBean.setRefresh_token(String.valueOf(Math.random()));
oAuthBean.setExpires_in("44517");
oAuthBeanMap.put(oAuthBean.getToken_type(), oAuthBean);
}
#GET
#Path("/token?client_id={clntID}")
#Produces("application/json")
public OauthBean getOAuthJSON(#PathParam("clntID") String clientID) {
System.out.println(clientID + " Secret ");
System.out.println("oAuthBeanMap.get(\"bearer\") :P " + oAuthBeanMap.get("bearer"));
return oAuthBeanMap.get("bearer");
}
}
Now when i trry to invoke this url :
http://localhost:7070/RESTfulWS/rest/oauth/token?client_id=clnt001
I get a 405 error.Method not allowed
Below is my web.xml :
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>RESTfulWS</display-name>
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.eviac.blog.restws</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
I am using jersey 1.18.
What am i doing wrong? Looking forward tyo your solutions.
Reading through your code, I think you should write #Path("/token") instead of #Path("/token?client_id={clntID}").
Besides, as you yourself noted, you should use QueryParam instead of PathParam
We have a gwt app that uses jcifs to pull the user name from our NT domain. Here is a clip of our web.xml:
<filter>
<filter-name>NtlmHttpFilter</filter-name>
<filter-class>com.xxx.gwt.server.MyNTLMFilter</filter-class>
<init-param>
<param-name>jcifs.netbios.wins</param-name>
<param-value>192.168.109.20</param-value>
</init-param>
<init-param>
<param-name>jcifs.smb.client.domain</param-name>
<param-value>its</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>NtlmHttpFilter</filter-name>
<url-pattern>/trunkui/greet</url-pattern>
</filter-mapping>
<!-- Servlets -->
<servlet>
<servlet-name>greetServlet</servlet-name>
<servlet-class>com.xxx.gwt.server.GreetingServiceImpl</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>greetServlet</servlet-name>
<url-pattern>/trunkui/greet</url-pattern>
</servlet-mapping>
So currently when the user goes to our site they get about 2 or 3 repeated prompts asking them to log onto the domain even though they already are (you have to be on the domain to get to our app). I would like to at least reduce the prompting to only happen once. So I was going to make a dummy servlet off of "/trunkui/dummy" and let that get called only when I ask for the name. The remote servlet has this method that we call asynchronously:
public String getUser() {
String userAgent = "";
try {
userAgent = getThreadLocalRequest().getUserPrincipal().getName();
int slashIdx = -1;
if ((slashIdx = userAgent.indexOf('\\')) >= 0)
userAgent = userAgent.substring(slashIdx + 1);
} catch (Exception npe) {
npe.printStackTrace();
}
return userAgent;
}
So I wanted to do some sort of call to the dummy servlet to do the domain prompting, but I am unsure on how to do this from the gwt remote service. Or if there is a better way to do this?
I figured it out. I built the dummy servlet and then used a RequestBuilder on the client side to do a get on that servlet. That servlet then gets the userprincipal. Here is the client side:
RequestBuilder getNameRB = new RequestBuilder(RequestBuilder.GET, "naming");
getNameRB.setCallback( new RequestCallback() {
#Override
public void onResponseReceived(Request request, Response response) {
loadUserName(response.getText());
}
#Override
public void onError(Request request, Throwable exception) {
Window.alert("Unable to authenticate user\n"+exception.getMessage());
Window.Location.replace("http://ccc");
}
});
try {
getNameRB.send();
} catch (RequestException e) {
Window.alert(e.getMessage());
}