In my Netbeans java web application I have an ajax GET request to the controller.
suddenly, the server started sending 404 Response Messages to every Ajax Request.
What's even weirder is this:
In the controller, the following code is supposed to handle GET requests:
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
processRequest1(request, response);
} catch (JsonException ex) {
Logger.getLogger(controller.class.getName()).log(Level.SEVERE, null, ex);
}
}
So I set a breakpoint next to this "doGet"method. Then I initiated the GET-request. (Purpose: being able to step through the code step by step in debugging mode).
The thing is: The ajax-request doesn't even arrive at this method. This also means that the server doesn't actually send a response.
However, google chrome is telling me that there was a 404 response:
What the hell is going on here ??!!
UPDATE:
Here's how I mapped the url used by the ajax-GET-eequest to the controller:
#WebServlet(
name = "controller",
urlPatterns = {"/controller"}
)
public class controller extends HttpServlet {
//
(i.e. I used annotations)
Here's the beginning of the ajax-request:
var url = "http://localhost:8081/CourseProject/controller";
$.ajax({
url: url,
type: "get",
//etc.
Related
Am doing the JAVA code found below, to call the servlet doGet() method from JSP page through AJAX call.
Here is my AJAX call..
Am sending the clicked text captured by ng-click of Angular js as a querystring to Servlet's doGet() method .
In my JSP file,
$scope.requestFunc = function (clickData) {
var urlquerystring = clickData;
jQuery.ajax({
type: 'GET',
url: "/Charts/testExecution/"+"?"+ urlquerystring,
dataType: 'html',
success: function(respnsedata)
{
window.location.assign(respnsedata);
}
});
}
In my Servlet's doGet() method,
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.err.println("In TestExecutionESO servlet..");
String teamnametextfield= req.getParameter("teamnametextfield");
System.out.println("Teamname is.."+teamnametextfield);
try {
dcmanager = DataCollectorManager.getInstance();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String selectedteam= req.getQueryString();
String testexeclistofobjectsjson = null;
if(selectedteam!=null)
{
String release=selectedteam.replace("%20"," ").toString();
testexecutionobjlist = dcmanager.getRallyDcMgr().gettestExecutionobjlist(release);
}
Gson gson = new Gson();
testexeclistofobjectsjson = gson.toJson(testexecutionobjlist);
System.out.println(testexecutionobjlist);
System.out.println(testexeclistofobjectsjson);
req.getSession().setAttribute("testexeclistofobjectsjson", testexeclistofobjectsjson);
resp.sendRedirect("TestExecutionESO.jsp");
}
Am getting the querystring perfectly..After the processing, I will do SetAttribute() and redirect to next JSP page..
Redirect is not working..
Here is my error code,
Failed to load resource: net::ERR_TOO_MANY_REDIRECTS..
http://10.112.81.95:9000/Charts/testExecution/TestExecutionESO.jsp.... Failed to load resource: net::ERR_TOO_MANY_REDIRECTS
Please help me resolve the problem..
how to redirect to next JSP page by doing the setAttribute() .??
resp.sendRedirect("TestExecutionESO.jsp");
This is the culprit in your code. when you call sendRedirect(), it will issue a 302 response containing the location-header, URI of the new resource. When the browser sees this header, it will issue a new request for that new URI.
All of this works well for a synchronous request but in case of AJAX calls, we use an XMLHttpRequest, which will not handle redirects so well.
I'd suggest you to use a RequestDispatcher instead to forward to the JSP like this
RequestDispatcher rd = req.getRequestDispatcher("path-to-ur-jsp");
rd.forward(req,res);
My Jersey CORS request is not functioning for POST, but works for GET requests. The headers are being mapped to Jersey requests as shown in the below screenshot of a GET request to the same resource.
However, doing a POST to the below method makes me end up with XMLHttpRequest cannot load http://production.local/api/workstation. Origin http://workstation.local:81 is not allowed by Access-Control-Allow-Origin.
Here's a screenshot of network activity:
Details on failed POST request:
Here's my resource:
#Path("/workstation")
#Consumes({MediaType.APPLICATION_JSON})
#Produces({MediaType.APPLICATION_JSON})
public class WorkstationResource {
#InjectParam
WorkstationService workstationService;
#POST
public WorkstationEntity save (WorkstationEntity workstationEntity) {
workstationService.save(workstationEntity);
return workstationEntity;
}
#GET
#Path("/getAllActive")
public Collection<WorkflowEntity> getActive () {
List<WorkflowEntity> workflowEntities = new ArrayList<WorkflowEntity>();
for(Workflow workflow : Production.getWorkflowList()) {
workflowEntities.add(workflow.getEntity());
}
return workflowEntities;
}
}
My CORS filter:
public class ResponseCorsFilter implements ContainerResponseFilter {
#Override
public ContainerResponse filter(ContainerRequest request, ContainerResponse response) {
Response.ResponseBuilder responseBuilder = Response.fromResponse(response.getResponse());
responseBuilder
.header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, HEAD");
String reqHead = request.getHeaderValue("Access-Control-Request-Headers");
if(null != reqHead && !reqHead.equals(null)){
responseBuilder.header("Access-Control-Allow-Headers", reqHead);
}
response.setResponse(responseBuilder.build());
return response;
}
}
My Jersey configuration in my Main class:
//add jersey servlet support
ServletRegistration jerseyServletRegistration = ctx.addServlet("JerseyServlet", new SpringServlet());
jerseyServletRegistration.setInitParameter("com.sun.jersey.config.property.packages", "com.production.resource");
jerseyServletRegistration.setInitParameter("com.sun.jersey.spi.container.ContainerResponseFilters", "com.production.resource.ResponseCorsFilter");
jerseyServletRegistration.setInitParameter("com.sun.jersey.api.json.POJOMappingFeature", Boolean.TRUE.toString());
jerseyServletRegistration.setInitParameter("com.sun.jersey.config.feature.DisableWADL", Boolean.TRUE.toString());
jerseyServletRegistration.setLoadOnStartup(1);
jerseyServletRegistration.addMapping("/api/*");
While I thought this was a CORS issue, turns out it was a Jersey issue...
org.glassfish.grizzly.servlet.ServletHandler on line 256 handles an exception...
FilterChainInvoker filterChain = getFilterChain(request);
if (filterChain != null) {
filterChain.invokeFilterChain(servletRequest, servletResponse);
} else {
servletInstance.service(servletRequest, servletResponse);
}
} catch (Throwable ex) {
LOGGER.log(Level.SEVERE, "service exception:", ex);
customizeErrorPage(response, "Internal Error", 500);
}
In my log, all I see is service exception: with nothing after it. When I debug this line, I end up seeing the error javax.servlet.ServletException: org.codehaus.jackson.map.JsonMappingException: Conflicting setter definitions for property "workflowProcess": com.production.model.entity.WorkstationEntity#setWorkflowProcess(1 params) vs com.production.model.entity.WorkstationEntity#setWorkflowProcess(1 params) which gives me something I can actually work with.
It's hard to tell and hard to debug since it's the browser that produces that error upon inspecting the response (header).
Even upon very close inspection your code looks fine and sane except that Access-Control-Allow-Headers is or may be set twice in filter(). While RFC 2616 (HTTP 1.1) Section 4.2 does basically permit it given certain conditions are met I wouldn't gamble here. You have no control over how browser X version N handles this.
Instead of setting the same header twice with different values rather append the 2nd set of values to the existing header.
I am using GWT 2.4 to build an application that runs entirely client-side and uses a web service that I control but is hosted on a different server. On this Java Servlet web service, I have implemented doOptions like so:
protected void doOptions(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Allow-Methods", "POST, GET");
}
And client-side in GWT I submit a request the standard way, e.g.
public static void makeHttpGetRequest(String query, RequestCallback callback) {
String url = "http://example.webservice.com/endpoint" + "?q=" + query;
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, URL.encode(url));
try {
builder.sendRequest(query, callback);
} catch (RequestException e) {
Window.alert("Server encountered an error: \n" + e.getMessage());
e.printStackTrace();
}
}
And then my callback implements onResponseReceived like this:
#Override
public void onResponseReceived(Request request, Response response) {
if (response.getStatusCode() == 200) {
System.out.println("HTTP request successful, received "
+ response.getText());
processResponse(response.getText());
} else {
System.out.println("HTTP error code " +
response.getStatusCode() + ":" +
response.getStatusText());
}
}
Whenever I run the application in late versions of Chrome or Firefox and send a request, onResponseReceived is called but the response code is 0 and there is no error message. Research indicates that most other instances of this problem arise from SOP restrictions. However, when looking at the HTTP traffic in Fiddler I see that when this is executed, the browser is indeed sending the expected HTTP request, and the web service is indeed returning the expected response, with a 200 response code. Somehow, the browser just isn't handling it properly.
Update: when I look at the traffic in Fiddler, it indicates that the request is sent and a response is received, but when I look at the same request in Chrome's developer console it shows that the request is 'canceled'. If the request is actually happening, what does that mean in this context?
Has anyone run across this problem? Any suggestions on what may be going on?
Error code 0 means that the CORS has been aborted, check that your servlet implementation is all right, I think you have to send Allow instead of Access-Control-Allow-Methods, and also you have to add the Access-Control-Allow-Headers since GWT adds extra headers to ajax requests.
Try this implementation from the gwt-query example which works fine:
private static final String ALLOWED_DOMAINS_REGEXP = ".*";
HttpServletRequest req = (HttpServletRequest) servletRequest;
HttpServletResponse resp = (HttpServletResponse) servletResponse;
String origin = req.getHeader("Origin");
if (origin != null && origin.matches(ALLOWED_DOMAINS_REGEXP)) {
resp.addHeader("Access-Control-Allow-Origin", origin);
resp.setHeader("Allow", "GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS");
if (origin != null) {
String headers = req.getHeader("Access-Control-Request-Headers");
String method = req.getHeader("Access-Control-Request-Method");
resp.addHeader("Access-Control-Allow-Methods", method);
resp.addHeader("Access-Control-Allow-Headers", headers);
resp.setContentType("text/plain");
}
}
I would rather a filter instead a servlet, like in the link above is explained, though.
In the blog-edit.html, JQuery was used to send the post request to the sever side(java servlet).
$("#btn").click(function() {
$.post("/blog/handler",{"content":$('#textarea').val()},
function(data){
alert("Data Loaded: " + data);
if(data.toString().length>1){
alert("Saved!")
}else{
alert("Failed!")
}
})
In the server side:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String content = request.getParameter("content");
System.out.println(content);
response.sendRedirect("/blog/list");
return;
}
What I saw is the server side is printing the content from the html, and the alert window pops up to say "Saved!". But the redirect function doesn't work
After searching I have no choice but to use jquery to redirect:
if(data.toString().length>1){
alert("Saved!")
window.location.replace("/blog/list")
}
it works, but it's not what i want
please help
While using ajax. you can not execute server side redirect.
However, there are better way how to redirect on client in such a scenario.
See Here
From my client side code, I am making an AJAX call to my servlet. If I use GET as request method. Everything works and I get response back. But when I send request as POST, servlet fails to send the response. From log I found out that in servlet "request" object is null when made ajax call with POST. According to this post:
Servlet response to AJAX request is empty , I'm setting headers for same-origin policy.
Below is my code for reference:
function aimslc_ajaxCall(url,callback, postParams){
var xmlhttp = null
if (window.XMLHttpRequest){
xmlhttp=new XMLHttpRequest();
}
xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState==4 && xmlhttp.status==200){
eval( callback+"("+xmlhttp.responseText+")" );
}
}
if(postParams!=null && typeof postParams!="undefined" ){
xmlhttp.open("POST",url,true);
xmlhttp.send(postParams);
}else{
xmlhttp.open("GET",url,true);
xmlhttp.send();
}
}
Servlet Code:
public void doProcess (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
logger.info("doProcess::start..."+request.getQueryString());
response.setHeader("P3P","CP='NOI ADM DEV PSAi COM NAV OUR OTR STP IND DEM'");
response.setHeader("Access-Control-Allow-Origin","*");
response.setHeader("Access-Control-Allow-Credentials","true");
response.setHeader("Access-Control-Allow-Methods","POST, GET");
}
Throws a null exception on request.getQueryString()
if you do a post all the data is in the request body, not on the url. From here you see that getQueryString only gets the stuff on the url.
See here for how to get the request body.
Also, if your data is name/value pairs, you might want to use getParameter and associated methods.
If the request is null, I ask do you implement doPost on your servlet?