Retrofit: Request from full url, return error - retrofit

I build the project with retrofit-2.2.0. I wanted to request a full url, but that is failed
public interface FileRetrofitServer {
#Streaming
#GET
Call<ResponseBody> downloadFileAsync(#Url String fileUrl);
}
it return the message as the below:
java.lang.IllegalStateException: Base URL required.

I have got the answer. Base url must not be empty, you can set a default value, and then the full url will replace the Base url.

Related

Access Denied when trying to forward the request in CQ

All, I'm trying to upload a file in dam in CQ using assestManager and then trying to set values in metadata. Then I'm retrieving all the data one by one and storing in a list, and set it to request object and pass it to new jsp page using 'rd.forward(request, response);' but I'm getting error as:
javax.jcr.AccessDeniedException: Access denied.
even though all the access are given.
Code:-
String redirect = request.getParameter(":redirect"); //content/nextgen/marine/podupload.html
RequestDispatcher rd = request.getRequestDispatcher(redirect);
rd.forward(request, response); // throws me error as access denied
I'm assuming your initial request is a POST?
If so, try the following:
SlingHttpServletRequest newRequest = new SlingHttpServletRequestWrapper(request) {
public String getMethod() {
return "GET";
}
};
newRequest.getRequestDispatcher("/content/nextgen/marine/podupload.html")
.forward(newRequest, response);
If this is a GET request that you are trying to forward then it's a permission issue. If this is a POS or PUT request then you will need a SlingHttpServletRequestWrapper to wrap and modify your request as a GET request forward.
This is simply because sling cannot forward POST requests.

Passing in a date to WebAPI - No HTTP resource was found that matches the request URI

I have a GET request that I make in Chrome Postman. It looks like the following:
http://localhost/WCAPI/Lookup/WCClassDesc/State/AL/Class/7230/DescCode/00/EffDate/2016-04-13
Can anybody see why I would get this response in Postman?
{
"Message": "No HTTP resource was found that matches the request URI 'http://localhost/WCAPI/Lookup/WCClassDesc/State/AL/Class/7230/DescCode/00/EffDate/2016-04-13'.",
"MessageDetail": "No action was found on the controller 'WCClassDesc' that matches the request."
}
My code is:
using System;
using System.Web.Http;
/// <summary>
/// API for loading WCClassDescription which is shown on the PremByClass page.
namespace WCAPI.Controllers.Lookup {
[RoutePrefix("Lookup/WCClassDesc")]
public class WCClassDescController : ApiController {
[Route("State/{State}/Class/{Class}/DescCode/{DescCode}/EffDate/{EffDate}")]
public Models.Lookup.WCClassDesc Get(string ClassState, string ClassCode, string DescCode, DateTime EffDate) {
var desc = (new Premium.BLL.WCClassDesc()).GetCurrentWCClassDesc(ClassState, ClassCode, DescCode, EffDate);
var WC = AutoMapper.Mapper.Map<Models.Lookup.WCClassDesc>(desc);
return WC;
}
}
}
Any help or direction would be greatly appreciated.
Jason
There are multiple problems with your code, let's start from the URI:
Assuming you are testing your application using the root path of your host (localhost) and following your definition of RoutePrefix and Route attributes, the correct URI for your resource is the following:
http://localhost/Lookup/WCClassDesc/State/AL/Class/7230/DescCode/00/EffDate/2016-04-13
That's because there is no WCAPI defined in your RoutePrefix attribute.
The other problem is related to the route parameter mapping, you defined you parameters as {State} and {Class}, but then you are asking for ClassState and ClassCode inside your method.
Rename those parameters to match the ones defined in your route, or else Web API will not map them to your method parameters.

Image Url validation in asp.net

i have images url , i need to check url is responding or not .
For Example :Below i i have written three image url, first two url is not valid only third url is valid .but second and fourth url is responding as valid image
and but there is no image.
http://media.expedia.com/hotels/1000000/90000/84900/84853/84853_744_b.jpg
http://www.iceportal.com/brochures/media/show.aspx?brochureid=ICE19044&did=3073&mtype=3073&type=pic&lang=en&publicid=4175749&resizing=X
http://images.trvl-media.com/hotels/1000000/30000/20400/20313/20313_166_b.jpg
http://www.iceportal.com/brochures/ice/ErrorPages/404.htm?aspxerrorpath=/brochures/media/show_A.aspx
here is my code:
public static bool CheckUrlExists(string url)
{
try
{
Uri u = new Uri(url);
WebRequest w = WebRequest.Create(u);
w.Method = WebRequestMethods.Http.Head;
using (StreamReader s = new StreamReader(w.GetResponse().GetResponseStream()))
{
return (s.ReadToEnd().Length >= 0);
}
}
catch
{
return false;
}
}
with this code i am validating only those url which is showing 404 error,but not those url which showing 'Sorry, requested brochure is temporarily un-published 'or any other type of message.
You will need a more complex logic to validate if the URL points to an image. If a resource is missing from the server or it is otherwise unavailable, you may get a HTTP error like the infamous 404, which will trigger a WebException. However, that is only part of the story.
Your second URL returns HTTP 200, confirming that the resource is there when in fact the resource is missing. What you really get there is a HTML document explaining the resource is not available. This is bad practice, but not without example.
At very least, you should examine the MIME type (Content-Type header, see WebResponse.ContentType) of the resource you test. A content type of image/* suggests an image-type resource. Failing to detect a known MIME type (e.g. if you receive application/octet-stream) you can actually HTTP GET get resource and run image type detection on the downloaded content.
I would suggest using HttpWebRequest and HttpWebResponse to do this, they are sub classes of WebRequest and WebResponse and as such are more granular for what you're trying to achive. The following code works with the example URIs provided
public static bool CheckUrlExists(string url)
{
try
{
Uri u = new Uri(url);
HttpWebRequest w = (HttpWebRequest)WebRequest.Create(u);
w.AllowAutoRedirect = false;
w.Method = WebRequestMethods.Http.Head;
HttpWebResponse response = (HttpWebResponse)w.GetResponse();
return response.StatusCode == HttpStatusCode.OK; //Check http status code
}
catch(WebException ex)
{
return false;
}
}
What's important here is that I'm checking the HttpStatus code. You're catch will already catch the 404s but the problem URIs ultimately lead to a 200 (OK). By setting AllowAutoRedirect to false the HttpWebRequest instance returns a 302 (redirect) status code, instead of following the redirect through to the "Sorry, requested brochure is temporarily un-published." page which is returning 200 (OK). This should serve your purpose.
Also: Catching a WebException will allow you to examine the status code (400+,500+, etc).
Be aware however, that you may be redirected to a new location for the image you're requesting. Taking that you might want to use PeterK's mime type check.

Spring MVC binding request parameters

I wrote a spring-mvc controller method to get an array of values in the request parameter.The method looks like below
/**
Trying to get the value for request param foo which passes multiple values
**/
#RequestMapping(method=RequestMethod.GET)
public void performActionXX(HttpServletRequest request,
HttpServletResponse response,
#RequestParam("foo") String[] foo) {
......
......
}
The above method works fine when the request url is in below format
...?foo=1234&foo=0987&foo=5674.
However when the request url is in below format the server returns 400 error
...?foo[0]=1234&foo[1]=0987&foo[2]=5674
Any idea how to fix the method to cater to the second format request url?
This is not possible with #RequestParam. What you can do is implement and register your own HandlerMethodArgumentResolver to perform to resolve request parameters like
...?foo[0]=1234&foo[1]=0987&foo[2]=5674
into an array. You can always checkout the code of RequestParamMethodArgumentResolver to see how Spring does it.
Note that I recommend you change how the client creates the URL.
The server is supposed to define an API and the client is meant to follow it, that's why we have the 400 Bad Request status code.
I resolved this issue using the request.getParameterMap().Below is code.
Map<String,String> parameterMap= request.getParameterMap();
for(String key :parameterMap.keySet()){
if(key.startsWith("nameEntry")){
nameEntryLst.add(request.getParameter(key));
}
}

Get Root/Base Url In Spring MVC

What is the best way to get the root/base url of a web application in Spring MVC?
Base Url = http://www.example.com or http://www.example.com/VirtualDirectory
I prefer to use
final String baseUrl =
ServletUriComponentsBuilder.fromCurrentContextPath().build().toUriString();
It returns a completely built URL, scheme, server name and server port, rather than concatenating and replacing strings which is error prone.
If base url is "http://www.example.com", then use the following to get the "www.example.com" part, without the "http://":
From a Controller:
#RequestMapping(value = "/someURL", method = RequestMethod.GET)
public ModelAndView doSomething(HttpServletRequest request) throws IOException{
//Try this:
request.getLocalName();
// or this
request.getLocalAddr();
}
From JSP:
Declare this on top of your document:
<c:set var="baseURL" value="${pageContext.request.localName}"/> //or ".localAddr"
Then, to use it, reference the variable:
Go Home
You can also create your own method to get it:
public String getURLBase(HttpServletRequest request) throws MalformedURLException {
URL requestURL = new URL(request.getRequestURL().toString());
String port = requestURL.getPort() == -1 ? "" : ":" + requestURL.getPort();
return requestURL.getProtocol() + "://" + requestURL.getHost() + port;
}
Explanation
I know this question is quite old but it's the only one I found about this topic, so I'd like to share my approach for future visitors.
If you want to get the base URL from a WebRequest you can do the following:
ServletUriComponentsBuilder.fromRequestUri(HttpServletRequest request);
This will give you the scheme ("http" or "https"), host ("example.com"), port ("8080") and the path ("/some/path"), while fromRequest(request) would give you the query parameters as well. But as we want to get the base URL only (scheme, host, port) we don't need the query params.
Now you can just delete the path with the following line:
ServletUriComponentsBuilder.fromRequestUri(HttpServletRequest request).replacePath(null);
TLDR
Finally our one-liner to get the base URL would look like this:
//request URL: "http://example.com:8080/some/path?someParam=42"
String baseUrl = ServletUriComponentsBuilder.fromRequestUri(HttpServletRequest request)
.replacePath(null)
.build()
.toUriString();
//baseUrl: "http://example.com:8080"
Addition
If you want to use this outside a controller or somewhere, where you don't have the HttpServletRequest present, you can just replace
ServletUriComponentsBuilder.fromRequestUri(HttpServletRequest request).replacePath(null)
with
ServletUriComponentsBuilder.fromCurrentContextPath()
This will obtain the HttpServletRequest through spring's RequestContextHolder. You also won't need the replacePath(null) as it's already only the scheme, host and port.
request.getRequestURL().toString().replace(request.getRequestURI(), request.getContextPath())
Simply :
/*
* Returns the base URL from a request.
*
* #example: http://myhost:80/myapp
* #example: https://mysecuredhost:443/
*/
String getBaseUrl(HttpServletRequest req) {
return ""
+ req.getScheme() + "://"
+ req.getServerName()
+ ":" + req.getServerPort()
+ req.getContextPath();
}
In controller, use HttpServletRequest.getContextPath().
In JSP use Spring's tag library: or jstl
Either inject a UriCompoenentsBuilder:
#RequestMapping(yaddie yadda)
public void doit(UriComponentBuilder b) {
//b is pre-populated with context URI here
}
. Or make it yourself (similar to Salims answer):
// Get full URL (http://user:pwd#www.example.com/root/some?k=v#hey)
URI requestUri = new URI(req.getRequestURL().toString());
// and strip last parts (http://user:pwd#www.example.com/root)
URI contextUri = new URI(requestUri.getScheme(),
requestUri.getAuthority(),
req.getContextPath(),
null,
null);
You can then use UriComponentsBuilder from that URI:
// http://user:pwd#www.example.com/root/some/other/14
URI complete = UriComponentsBuilder.fromUri(contextUri)
.path("/some/other/{id}")
.buildAndExpand(14)
.toUri();
In JSP
<c:set var="scheme" value="${pageContext.request.scheme}"/>
<c:set var="serverPort" value="${pageContext.request.serverPort}"/>
<c:set var="port" value=":${serverPort}"/>
base url
reference https://github.com/spring-projects/greenhouse/blob/master/src/main/webapp/WEB-INF/tags/urls/absoluteUrl.tag
#RequestMapping(value="/myMapping",method = RequestMethod.POST)
public ModelandView myAction(HttpServletRequest request){
//then follow this answer to get your Root url
}
Root URl of the servlet
If you need it in jsp then get in in controller and add it as object in ModelAndView.
Alternatively, if you need it in client side use javascript to retrieve it:
http://www.gotknowhow.com/articles/how-to-get-the-base-url-with-javascript
I think the answer to this question: Finding your application's URL with only a ServletContext shows why you should use relative url's instead, unless you have a very specific reason for wanting the root url.
If you just interested in the host part of the url in the browser then directly from request.getHeader("host")) -
import javax.servlet.http.HttpServletRequest;
#GetMapping("/host")
public String getHostName(HttpServletRequest request) {
request.getLocalName() ; // it will return the hostname of the machine where server is running.
request.getLocalName() ; // it will return the ip address of the machine where server is running.
return request.getHeader("host"));
}
If the request url is https://localhost:8082/host
localhost:8082
Here:
In your .jsp file inside the [body tag]
<input type="hidden" id="baseurl" name="baseurl" value=" " />
In your .js file
var baseUrl = windowurl.split('://')[1].split('/')[0]; //as to split function
var xhr = new XMLHttpRequest();
var url='http://'+baseUrl+'/your url in your controller';
xhr.open("POST", url); //using "POST" request coz that's what i was tryna do
xhr.send(); //object use to send```

Resources