No mapping found for HTTP request with URI - in spring 3.2.4 - spring

I have this controller:
...
#RequestMapping(value = "/accounts/manageaccount.do", method = RequestMethod.GET)
public String initForm(HttpServletRequest request, Model model) {
model.addAllAttributes(getModel(request));
return "registerAccountView";
}
#RequestMapping(value = "/accounts/saveaccount.do", method = RequestMethod.POST)
public String saveaccount(HttpServletRequest request, Model model) {
model.addAllAttributes(getModel(request));
return "registerAccountView";
}
...
The controller its mapping well when I put this URL in the browser
http://127.0.0.1:7001/devices/accounts/manageaccount.do
Then I have this jsp
<form method="post" action="saveaccount.do">
</form>
But when I submit I got this strange error
URL: /devices/accounts/saveaccount.do
???error404.error???

Make sure the servlet mapping in your web-xml is configured to handle the .do requests :
<servlet-mapping>
<servlet-name>yourServletName</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>

Related

Cross origin blocked between Ajax and Spring Controller

I want a Javascript function to send data to a Spring controller and get a response. However, due to the strict-origin-when-cross-origin Referrer policy, the request does not go through.
Spring Controller :
#Controller
public class EventController {
#ResponseBody
#RequestMapping(value = "/event", method = RequestMethod.POST)
public String handleAjax(#RequestParam Integer id, HttpServletRequest request, HttpServletResponse response) {
response.setHeader("Access-Control-Allow-Origin", "*");
return "OK";
}
}
Javascript functions :
function getContextPath() {
return window.location.pathname.substring(0, window.location.pathname.indexOf("/",2));
}
function move(moveDir,velocity){
$.ajax({
type : "POST",
url : getContextPath() + "/event",
success: function(data){
console.log(data)
}
});
}
I know that I have to allow cross-origin for these files. So far, the things I tried didn't work.
List of what I tried :
-> Adding #CrossOrigin(origins = "http://localhost:8081", maxAge = 3600) to the controller
-> Adding response.setHeader("Access-Control-Allow-Origin", "*"); to the controller
-> Adding crossorigin="anonymous" to the Javascript <script> tag
Your code won't work because you specify to support POST method only
#RequestMapping(value = "/event", method = RequestMethod.POST)
OPTIONS method is required as Preflighted requests in CORS.
So you must support POST and OPTIONS also to make it work.
#RequestMapping(value = "/event")
#RequestMapping(value = "/event", method = { RequestMethod.POST, RequestMethod.OPTIONS })
https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS
I finally got it. There were two problems.
The first was that I had to add that header to the ajax request, to allow the request to be handled by the server: headers: { 'Access-Control-Allow-Origin': '/path_to_request_target' },. Putting '*' instead of '/path_to_request_target' would also work.
The second was with my dispatcher servlet. I had to put .html at the end of the URL : url : getContextPath() + "/event.html",. This is due of the mapping of my dispatcher servlet :
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/index.jsp</url-pattern>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
Adding .html to the URL worked because of <url-pattern>*.html</url-pattern>. Adding a <url-pattern> that satisfied the format of the inital URL would also work.

Spring WebFlux + thymeleaf: Post request redirect Get page returns the 303 see other status

I just used SpringBoot + WebFlux + thymeleaf to write the controller.
#RequestMapping(value = "/create", method = RequestMethod.GET)
public String createCityForm(Model model) {
model.addAttribute("city", new City());
model.addAttribute("action", "create");
return CITY_FORM_PATH_NAME;
}
#RequestMapping(value = "/create", method = RequestMethod.POST)
public String postCity(#ModelAttribute City city) {
cityService.saveCity(city);
return REDIRECT_TO_CITY_URL;
}
I witre thymeleaf page to receive the form, and redirect/return the get method page, But the browser give the 303 see other status.
Also, the delete resources also doesn't work.
The SEE_OTHER status is actually the default status of the RedirectView when invoked without explicitly specifying the HTTP code (like the ThymeleafReactiveViewResolver does).
If you want to override this status, return the RedirectView directly instead of letting Thymeleaf do it when it matches the redirect: pattern in the view name:
#RequestMapping(value = "/create", method = RequestMethod.GET)
public RedirectView createCityForm(Model model) {
model.addAttribute("city", new City());
model.addAttribute("action", "create");
return new RedirectView("/target_url", HttpStatus.MOVED_PERMANENTLY);
}

AJAX returns 404 in Spring MVC

ViewResolver (my jsp is in the right folder as specified on prefix value):
<!-- Resolves views selected for rendering by #Controllers -->
<!-- to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
Servlet mapping:
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>*.fst</url-pattern>
</servlet-mapping>
Controller:
#Controller
public class HomeController {
private static final Logger logger =
LoggerFactory.getLogger(HomeController.class);
#RequestMapping("/home")
public ModelAndView home(String user, HttpServletRequest request) {
logger.info("Home controller has been executed");
ModelAndView mv = new ModelAndView();
mv.addObject("userName", user);
mv.addObject("controllerName", request.getRequestURI());
mv.setViewName("home");
return mv;
}
#RequestMapping(value = "/testAjax", method = RequestMethod.POST)
public String testAjax(#RequestParam("memberId") String id,
HttpServletRequest request, HttpServletResponse response,
Locale locale, Model model) {
logger.info("Text Ajax action has been executed. My Parameter is " + id);
return id;
}
}
After turning on Tomcat 8 server on STS IDE, accessing this web with this url http://localhost:8080/home.fst works okay.
But on the page, calling AJAX like below throws a 404 error:
$.ajax({
type: "POST",
url: "/testAjax.fst",
data: {"memberId" : "test"},
success: function (result) {
console.log(result)
}
});
This is console error log:
POST http://localhost:8080/testAjax.fst 404 (Not Found)
k.cors.a.crossDomain.send jquery-2.1.3.min.js:4
n.extend.ajaxhome.fst:11 (anonymous function) jquery-2.1.3.min.js:3
n.event.dispatch jquery-2.1.3.min.js:3
r.handle
Strange thing is that it calls testAjax controller just fine and there's no error log on server.
logger.info("Text Ajax action has been executed. My Parameter is " + id);
When textAjax action is invoked by my AJAX, the log is printed as well. I checked it out with debug point too (it broke alright).
What seems to be the matter??
Everything's good just Add #ResponseBody annotation in your method and also I suggest you to change your request method POST to GET
Spring
#RequestMapping(value = "/testAjax", method = RequestMethod.GET) //Made Change
#ResponseBody //added
public String testAjax(#RequestParam("memberId") String id, HttpServletRequest request, HttpServletResponse response, Locale locale, Model model) {
logger.info("Text Ajax action has been executed. My Parameter is " + id);
return id;
}
JQuery
$.ajax({
type: "GET", //Made Change
url:"/testAjax.fst",
data: {"memberId" : "test"},
success: function (result) {
console.log(result)
}
});

#RequestMapping not working for .jsp

here is the url-pattern in web.xml
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Here is my controller
#Controller
public class HelloController
{
#RequestMapping("/*.km")
public String handleKm()
{
System.out.println("km ext called");
return "aaa";
}
#RequestMapping("/*.jsp")
public String handleJsp()
{
System.out.println("jsp pages called");
return "bbb";
}
}
while accessing the url with /requestMapping/a.km , it is works, calls the handleKm() method.but with /requestMapping/a.jsp , it should call handleJsp().but it does not work. result : HTTP Status 404 - /requestMapping/a.jsp.
why ??
If I chane the url-pattern from "/" to "/*" , although both method are called , but dont get to the appropriate pages.
May be the "org.springframework.web.servlet.view.InternalResourceViewResolver" is not working .
Check out this related SO post (possibly a duplicate). I think the .jsp extension is confusing the dispatcher servlet. Try using an extension that isn't .jsp and see if that works.

Smartgwt with RestDataSource and SpringController

I have been stuck at this for a while. I have a smartgwt widget listgrid tied to a restdatasource. I have mapped its URLs to my spring services. However I cannot figure out how to retrieve the JSON dsrequest on spring server side. Even my dispatcher servlet does not contain the params.
My restdatasource is as follows:
RestDataSource myDS = new RestDataSource() {
#Override
protected Object transformRequest(DSRequest dsRequest) {
dsRequest.setContentType("application/json");
JavaScriptObject jso = dsRequest.getData();
String s1 = JSON.encode(jso);
return s1;
// return super.transformRequest(dsRequest);
}
#Override
protected void transformResponse(DSResponse response, DSRequest request, Object data) {
super.transformResponse(response, request, data);
}
};
Then on this datasource set the operations as follows:
// set the operation on the datasource
OperationBinding fetch = new OperationBinding();
fetch.setOperationType(DSOperationType.FETCH);
fetch.setDataProtocol(DSProtocol.POSTMESSAGE);
OperationBinding add = new OperationBinding();
add.setOperationType(DSOperationType.ADD);
add.setDataProtocol(DSProtocol.POSTMESSAGE);
OperationBinding update = new OperationBinding();
update.setOperationType(DSOperationType.UPDATE);
update.setDataProtocol(DSProtocol.POSTPARAMS);
OperationBinding remove = new OperationBinding();
remove.setOperationType(DSOperationType.REMOVE);
remove.setDataProtocol(DSProtocol.POSTMESSAGE);
myDS.setOperationBindings(fetch, add, update, remove);
myDS.setDataFormat(DSDataFormat.JSON);
// myDS.setDataProtocol(DSProtocol.POSTMESSAGE);
Set some fields in the datasource:
// set the values for the datasource
DataSourceTextField Id = new DataSourceTextField("Id", "Id");
Id.setPrimaryKey(true);
Id.setCanEdit(false);
DataSourceTextField name= new DataSourceTextField("name", "Name");
name.setCanEdit(false);
DataSourceTextField employeeType= new DataSourceTextField("employeeType", "employeeType");
employeeType.setCanEdit(true);
employeeType.setValueMap("Manager", "Associate", "Contractor");
Set these fields to the datasource:
myDS.setFields(Id, name,employeeType);
myDS.setFetchDataURL("/rest/myservice/fetch");
myDS.setAddDataURL("/rest/myservice/add");
myDS.setUpdateDataURL("/rest/myservice/update");
myDS.setRemoveDataURL("/rest/myservice/remove");
So in the case that the user changes the employeeType (because it's a dropdown), an update request is sent. I send the JSON string to the server configured as below:
#Controller
#RequestMapping("/myservice")
public class MyService {
...fetch
...update
#RequestMapping(value="/update", method=RequestMethod.POST)
#ResponseBody
public String update()
{
}
I am failing to understand how to retrieve the (JSON) dsrequest because even my DispatcherServlet does not have the parameters (even if I use POSTPARAMS). The developer console shows the request made correctly but I don't receive anything on the server side.
My spring servlet is configured as below in 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>/rest/*</url-pattern>
</servlet-mapping>
I think I am missing something obvious but I can't locate it. Do I use #PathVariable or RequestParams?
Found my own answer. Hope this helps someone.
update.setDataProtocol(DSProtocol.POSTPARAMS);
to
update.setDataProtocol(DSProtocol.POSTMESSAGE);
#Override
protected Object transformRequest(DSRequest dsRequest) {
JavaScriptObject jso = dsRequest.getData();
String s1 = JSON.encode(jso);
return s1;
}
#RequestMapping(value="/update", method=RequestMethod.POST)
#ResponseBody public String update(#RequestBody String json) { }

Resources