angularjs rest API Spring - angularjs

i have a problem with rest API in angularjs.
web.xml
<servlet>
<servlet-name>SpringServlet</servlet-name>
<servlet-class>com.mycompany.xxxx.userInterface.servlet.SpringServlet</servlet-class>
<load-on-startup>3</load-on-startup>
</servlet>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet-mapping>
<servlet-name>SpringServlet</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
SpringServlet.class
#Override
public void init() throws ServletException
{
super.init();
ApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
SpringBeanReader.getInstance().setApplicationContext(applicationContext);
//SpringBeanReader.getInstance().getApplicationContext().getBean(")
}
I have problems when I call api.
controller.js
.service('ApiCall', ['$http', function ($http){
//Get All Employees
this.getEmployees = function () {
console.log('dentro service.js');
return $http.get("/utenti/all");
}
}])
.controller("DataTable",['$scope','ApiCall',
function($scope,ApiCall){
$scope.persons = ApiCall.getEmployees();
}])
Controller.class
#Path("/utenti")
public class UtentiController {
#Path("/all")
#GET
#Produces("application/json")
public JSONArray getAll() {
/**** code for JSON array ***/
}
The code "$http.get("/utenti/all");" return error
HTTP Status [404] – [Not Found]
Type Status Report
Message /foodplan/utenti/all
Description The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.
Thanks to all.

Related

How to remove # from URL , SpringBoot & AngularJs application?

This is my TuckeyRewriteFilter filter class
public class TuckeyRewriteFilter extends org.tuckey.web.filters.urlrewrite.UrlRewriteFilter {
#Override
protected void loadUrlRewriter(FilterConfig filterConfig) throws ServletException {
String confPath = filterConfig.getInitParameter("confPath");
ServletContext context = filterConfig.getServletContext();
try {
final URL confUrl = getClass().getClassLoader().getResource(confPath);
final InputStream config = getClass().getClassLoader().getResourceAsStream(confPath);
Conf conf = new Conf(context, config, confPath, confUrl.toString(), false);
checkConf(conf);
} catch (Throwable e) {
throw new ServletException(e);
}
}
}
This is my springboot main class
public class AdminWebApplication {
public static final String REWRITE_FILTER_NAME = "rewriteFilter";
public static final String REWRITE_FILTER_CONF_PATH = "urlrewrite.xml";
#Autowired
ApplicationContext applicationContext;
public static void main(String[] args) {
SpringApplication.run(AdminWebApplication.class, args);
}
#Bean
public ObjectMapper createObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
applicationContext.getAutowireCapableBeanFactory().autowireBean(objectMapper);
return objectMapper;
}
#Bean
public FilterRegistrationBean rewriteFilterConfig() {
FilterRegistrationBean reg = new FilterRegistrationBean();
reg.setName(REWRITE_FILTER_NAME);
reg.setFilter(new TuckeyRewriteFilter());
reg.addInitParameter("confPath", REWRITE_FILTER_CONF_PATH);
reg.addInitParameter("confReloadCheckInterval", "-1");
reg.addInitParameter("statusPath", "/redirect");
reg.addInitParameter("statusEnabledOnHosts", "*");
reg.addInitParameter("logLevel", "WARN");
return reg;
}
}
This is my urlrewrite.xml
this file is from resources folder
configuration is works fine, loading login page, but still I have to pass /#login, then it redirect to /login URL, but on browser refresh I ma getting 404 error.
index.html, I have added , I don't want extra domain name after my port id.
<urlrewrite default-match-type="wildcard">
<rule>
<from>/login</from>
<to>/login.html</to>//As of now only configured for login page.
</rule>
<rule>
<from>/contact</from>
<to>/index.html</to>
</rule>
</urlrewrite>
In your js router file (config phase) you need to add:
$locationProvider.hashPrefix('');
$locationProvider.html5Mode(true);
and in your index.html file, you need to add:
<base href="/">
Update 1
After implementing above on client side, you need to configure url mapping on server side as well. With # , the server ignores whatever is followed after it.
http://localhost:8080/#i_will_be_ignored/and_so_do_i
So, when you configure angularjs to remove # from URLs, your above request
http://localhost:8080/i_will_be_ignored/and_so_do_i
will now hit server with #path('i_will_be_ignored') . Now, that will give you 404 because you never mapped any API for it. Thats the reason, you are getting 404 on page refresh.
You need to map all the URLs that doesn't match to index.html followed by the unmatched url. Once that's done, angularjs will take it from there and redirects to appropriate route . I hope this will help you.
Something like this will help you out here

Angularjs Unexpected token JSON

I have a problem with angularjs and JSON.
This is my code.
list_user.jsp (this is the page where I print the table)
<tr ng-repeat="per in persons">
<td>{{ per.user }}</td>
<td>{{ per.password }}</td>
<td>{{ per.profile }}</td>
</tr>
controller.js
$http({
method : 'POST',
url : 'views/user/user.json'
}).success(function(data){
$scope.persons = data;
});
user.json
[
{
"user": "Quarterback",
"password": 5,
"profile": "ppp"
},
{
"user": "Wide Receiver",
"password": 89,
"profile": "oooo"
}
]
This way the table is generated correctly, but the json is fixed.
Now I'll paste the code with which I want to print the data by taking them from a query
controller.js
$http({
method : 'POST',
url : 'views/user/user.jsp'
}).success(function(data){
/*
var jsonStr="your json string";
var json=JSON.stringify(data);
json=JSON.parse(json)
console.log(json);
*/
console.log(data);
$scope.persons = data;
});
The code between / * .. * / left them to show that I also tried that road without success.
user.jsp
JSONArray jdata = new JSONArray();
UserRest as = new UserRest();
jdata = as.getAll();
logger.info("jdata in user.jsp "+jdata);
UserRest.class (just paste the code where I create the JSON)
while (iter.hasNext()) {
User ut = (User) iter.next();
JSONObject jtemp = new JSONObject();
jtemp.put("user", ut.getUserName());
jtemp.put("password", ut.getPassword());
jtemp.put("profilo", ut.getProfilo());
jarray.put(jtemp);
}
return jarray;
the result of logger.info("jdata in user.jsp "+jdata) in user.jsp
jdata in user.jsp [{"user":"aaaaaaa","password":"1111111","profile":"0"},{"user":"bbbbbbbb","password":"222222222","profile":"1"}]
As you can see the json looks the same, but when in the browser I call the list_user.jsp page in the console the value "data" in controller.js returns me
<? Xml version = "1.0" encoding = "utf-8"?>
I also tried with JSON.parse or JSON.stringify but it does not work.
I also added "track by $ index" here:
<tr ng-repeat = "for people track by $ index">
in list_user.jsp but it does not work.
Please help me because I do not know how to do it anymore.
Well, your problem appears to be that you should call a SERVICE, not a jsp.
A JSP builds a new web page for you and so it will put that:
< ? Xml version = "1.0" encoding = "utf-8"? >
Try doing, instead a jsp, a servlet (or use JAX-RS, as you prefer) and putting you logic inside the 'doGet' method (again, or use JAX-RS).
Do a simple thing, like
protected void doGet(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException {
response.getWriter().append(your working JSON properly hardcoded);
}
This way should work. Then put your service logic there.
Thank you very much #inigoD, I solved my problem.
Following the new code.
controller.js (UserRest is the servlet)
$http({
method : 'POST',
url : 'UserRest'
}).success(function(data){
$scope.persons = data;
});
web.xml
<servlet>
<servlet-name>UserRest</servlet-name>
<servlet-class>"path application".UserRest</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UserRest</servlet-name>
<url-pattern>/UserRest</url-pattern>
</servlet-mapping>
UserRest.class
#Override
protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
#Override
protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
try
{
JSONArray jdata = new JSONArray();
jdata = getAll();
logger.info("prima del response "+jdata);
response.setContentType("application/json");
response.getWriter().write(jdata.toString());
}
catch ( Exception ex )
{
ex.printStackTrace();
}
}
The function getAll() Is the same as I had pasted on, which contained this code.
while (iter.hasNext()) {
User ut = (User) iter.next();
JSONObject jtemp = new JSONObject();
jtemp.put("user", ut.getUserName());
jtemp.put("password", ut.getPassword());
jtemp.put("profilo", ut.getProfilo());
jarray.put(jtemp);
}
return jarray;
I resolve the problem with servlet, but I would like call a REST api.
I prefer don't use the servlet.
I change my code.
controller.js
angular.module('inspinia')
.controller("DataTable",['$scope','$http',function($scope,$http){
$http({
method : 'GET',
url : '/api/utenti'
}).success(function(data){
$scope.persons = data;
});
web.xml
<servlet>
<servlet-name>SpringServlet</servlet-name>
<servlet-class>com.xxx.yyy.userInterface.servlet.SpringServlet</servlet-class>
<load-on-startup>3</load-on-startup>
</servlet>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet-mapping>
<servlet-name>SpringServlet</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
UtentiController.class
#Path("/utenti")
#Component
#Scope("request")
public class UtentiController {
#GET
#Produces("application/json")
public JSONArray getAll() {
/* call the interface that return a json */
return jarray;
}
}
the error in the console is:
HTTP Status [404] – [Not Found]
Type Status Report
Message /api/utenti/
Description The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.
Thanks for your help

Proper way to post to a servlet on Google App Engine from a Java client application

I have deployed an to App Engine. I setup SSL, and associated it with a custom domain. When I was developing the app locally, sending to a servlet via http://localhost:8080/servlet, worked as expected, but when I deploy it to App Engine, I have yet to get the appropriate result. I've tried many things, and the response codes I keep getting are either 404 or 500.
I startied with a simple HTTPUrlConnection and DataOutputstream to send a JSON to the servlet, and get an appropriate response. Like so:
URL url;
HttpURLConnection connection = null;
try {
url = new URL(targetURL);
connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("custom-Header", "XYZ");
connection.setRequestProperty("Content-Length", Integer.toString(urlParameters.length));
connection.setRequestProperty("Content-Language", "en-US");
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(true);
//Send request
DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
wr.write(urlParameters);
wr.flush ();
wr.close ();
//Get Response
BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
StringBuffer response = new StringBuffer();
while((line = rd.readLine()) != null) {
response.append(line);
response.append('\r');
}
rd.close();
return response.toString();
}
finally {
if(connection != null) {
connection.disconnect();
}
}
This works locally.
I've now tried Apache Common's HttpAsyncClient, to check if it maybe a timing issue:
final ResponseObject responseObject = new ResponseObject(); //my simple POJO
try(CloseableHttpAsyncClient httpclient = HttpAsyncClients.custom()
.setSSLStrategy(sslSessionStrategy)
.build()) {
httpclient.start();
HttpPost post = new HttpPost(url);
post.setHeader("Content-Type", "application/json");
post.setHeader("custom-Header", "XYZ");
post.setHeader("Content-Language", "en-US");
HttpEntity entity = new ByteArrayEntity(urlParameters);
post.setEntity(entity);
final CountDownLatch latch1 = new CountDownLatch(1);
httpclient.execute(post, new FutureCallback<HttpResponse>() {
public void completed(final HttpResponse response) {
int status = response.getStatusLine().getStatusCode();
if (status >= 200 && status < 300) {
HttpEntity entity = response.getEntity();
try {
responseObject.message = entity != null ? EntityUtils.toString(entity) : null;
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
responseObject.exception = new ClientProtocolException("Unexpected response status: " + status);
}
latch1.countDown();
}
public void failed(final Exception ex) {
responseObject.exception = ex;
latch1.countDown();
}
public void cancelled() {
latch1.countDown();
}
});
latch1.await();
if(responseObject.exception != null) {
throw responseObject.exception;
} else {
return responseObject.message;
}
}
This also works locally, but when trying to reach AppEngine, still no go.
Here's my simple web.xml:
<servlet>
<servlet-name>login</servlet-name>
<servlet-class>my.servlet.package.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>login</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
<security-constraint>
<web-resource-collection>
<web-resource-name>everything</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<welcome-file-list>
<welcome-file>home.jsp</welcome-file>
</welcome-file-list>
Locally, I post to http://localhost:8080/login. As for App Engine, I posted to the ff:
https://myapp.appspot.com/login
https://myapp.customdomain.com/login
I've tried changing up the url-pattern. I started with /login, then did login, then explicitly tried the both App Engine and custom domain urls (i.e. myapp.appspot.com/login and myapp.mydomain.com/login). I also tried having an actual jsp or html page to post to, after trying not having an actual page associated with the servlet i.e. login.jsp or login.html.
When I used HttpAsyncClient (my choice due to SSLContext), the best result I got was the HTML of the page associated with the servlet, but never the response I need from the Servlet.
Any ideas?
Found the answer on one of Google Cloud Platform's scattered docs:
https://cloud.google.com/appengine/docs/standard/java/how-requests-are-handled
https://cloud.google.com/appengine/docs/standard/java/how-requests-are-routed
Basically, you'll have to prepend your project's appspot url e.g. myapp.appspot.com, with the version ID of any actively serving instance of your app. You can find such IDs under the Versions page of your App Engine console. For example: https://versionId.myapp.appspot.com.

Spring REST call gives 302 redirect

I am using angularjs to make a REST call to my tomcat backend managed by Spring. But my server code never seems to get the call and the browser gets a 302 with "index.html" appended at the end of the url. For example, if my initial call was "localhost:8080/api/search/someString", browser receives a 302 redirect to "localhost:8080/api/search/someString/index.html", which then redirects to "localhost:8080/api/search/someString/index.html/index.html".
This keeps happening until a "Too many redirects" error occurs and it fails. Any ideas anyone?
Here is my web.xml:
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
<url-pattern>/api/*</url-pattern>
<url-pattern>/page/*</url-pattern>
</servlet-mapping>
Angular call:
search: function (searchStr) {
return $http.get("/api/search/"+searchStr);
}
Rest Controller:
#RestController
public class SearchResource {
#Autowired
private ItemService itemService;
#RequestMapping(value = "/api/search/{searchStr}", method = RequestMethod.GET)
public List<Item> getItemsBasedOnSearchString(#PathVariable String searchStr) {
return itemService.getAllItems();
}
public ItemService getItemService() {
return itemService;
}
public void setItemService(ItemService itemService) {
this.itemService = itemService;
}
}
Sometimes you can make the stupidest of mistakes! I changed the RequestMapping annotation from "/api/search" to "/search" and it works.
Thanks.

Tomcat displaying welcome-page before filter for jsp is executed

I am using Tomcat 6.0.36 and the welcome-page is /Login.jsp
I have a filter in place so that it can display a different login page for mobile devices.
It works with URL mywebsite.com/Login.jsp, but the filter is bypassed when the URL is just mywebsite.com.
Is there a way to force it to execute?
I have found this page but it doesn't work in my case:
How to map a filter for welcome-file in web.xml for Tomcat?
Thanks
My web.xml:
<welcome-file-list>
<welcome-file>/Login.jsp</welcome-file>
</welcome-file-list>
...
<filter>
<display-name>LoginPageFilter</display-name>
<filter-name>LoginPageFilter</filter-name>
<filter-class>filters.LoginPageFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LoginPageFilter</filter-name>
<url-pattern>/Login.jsp</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
The filter - I had deleted it and put one quickly back together
public class LoginPageFilter implements Filter
{
public LoginPageFilter() { }
public void init ( FilterConfig fConfig ) throws ServletException { }
public void doFilter ( ServletRequest request, ServletResponse response,
FilterChain chain ) throws IOException,
ServletException
{
System.out.println ( "Filter being executed" );
chain.doFilter(request, response);
}
public void destroy() { }
}
If the URL is
http://localhost:8080/gymfit/Login.jsp
then the message is printed to the console.
When the URL is
http://localhost:8080/gymfit/
the same page is displayed but the message is not printed out to the console
look at this line, this means only the request to '/Login.jsp' will the filter being executed
<url-pattern>/Login.jsp</url-pattern>
if you want to apply this filter to all the path, change the config to:
<url-pattern>/*</url-pattern>

Resources