why redirect not work in springmvc - spring-mvc

I want to redirect after a upload, and want to redirect "files" page. but after submit successfully, the url in browser doesn't redirect, I also use firebug to check if there is any redirect, but not happen.
I change the "redirect:/files" to "redirect:/files.jsp" also not help.
is there any mistake?
Here is my code:
#Controller
#RequestMapping({ "/files", "/files/" })
public class FileAdminController {
#RequestMapping(value = { "/upload/index", "/upload", "/upload/" }, method = RequestMethod.GET)
public String showUplaod() {
return "upload";
}
#RequestMapping(value = { "/index", "/index/", "/" }, method = RequestMethod.GET)
public String showFilePage() {
return "files";
}
#RequestMapping(value = "/upload", method = RequestMethod.POST)
public #ResponseBody String handleFileUpload(
#RequestParam("jarName") String jarName,
#RequestParam("manifestName") String manifestName,
#RequestParam("files") MultipartFile file) {
try {
File file1 = new File("c:/uploads/");
file1.getParentFile().mkdirs();
file1.createNewFile();
BufferedOutputStream stream = new
BufferedOutputStream(
new FileOutputStream(file1));
stream.write(bytes);
stream.close();
return "redirect:/files";
} catch (Exception e) {
return "You failed to upload " + jarName + " => " + e.getMessage();
}
}
}

redirect: is a view name which gets resolved by the UrlBasedViewResolver. But with #ResponseBody you tell spring that this controller is not returning a view name. I.e. you will have to take care about the redirect by yourself, by injecting the HttpServletResponse.

Related

backoffice macro returns 404

i am getting the url 404 not found when loading in a macro.
But then i get in the console a
No HTTP resource was found that matches the request URI 'https://localhost:44351/umbraco/api/prisinformation/produktlista?typ=1&version=0'.No action was found on the controller 'PrisInformation' that matches the name 'produktlista'.
and a
No HTTP resource was found that matches the request URI 'https://localhost:44351/umbraco/api/prisinformation/produktlista?typ=0'.No action was found on the controller 'PrisInformation' that matches the name 'produktlista'.
the code i try to call is this one. no mather how much i try i get this error when calling the macro.
public class PrisInformationController : UmbracoApiController
{
private ILoginService _userService;
private MembershipHelper _membershipHelper;
public PrisInformationController(MembershipHelper membershipHelper, ILoginService userService)
{
_userService = userService;
_membershipHelper = membershipHelper;
}
public void Authorize()
{
if (!_membershipHelper.IsLoggedIn())
{
if (_userService.AddAndOrLoginMember())
{
return;
}
}
throw new HttpException(Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Page not found").ToString());
}
[HttpGet, HttpPost]
[Route("produktlista/{typ}")]
public HttpResponseMessage Produktlista(int typ = 0, int version = 0)
{
Authorize();
string result = string.Empty;
string apiUrl = ConfigurationManager.AppSettings["ApiUrl"];
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(apiUrl + "/databoken/get/produktlista/" + typ + "/" + version);
request.Method = WebRequestMethods.Http.Get;
request.Accept = "application/json";
var response = request.GetResponse();
string s = string.Empty;
using (var sr = new StreamReader(response.GetResponseStream()))
{
result = sr.ReadToEnd();
}
}
I read it as your Produktlista method has a route defined that requires you to do /umbraco/api/prisinformation/produktlista/1 where 1 is typ, instead of ?typ=1. I could totally be wrong though, but maybe try removing the custom Route definition and see if that helps?
https://our.umbraco.com/Documentation/Reference/Routing/Umbraco-API-Controllers/index-v8
On another note you can change your controller to be of type UmbracoAuthorizedApiController which will do the backoffice auth check for you. Just note that it will change the standard route to be /umbraco/backoffice/api/... instead.

Spring: How to return custom 404 instead of Resource

I have a rest endpoint to deliver a file from the file system to the user through a FileSystemResource. If the file wasn't found it should display my custom 404 error page. But how can I achieve this? If I simply return a ResponseEntity with the status 404 the default error page is shown and not mine. I have other MVC controllers where if I enter an invalid URL my custom error page is returned. I tried to return a ModelAndView object and other things, but none seem to work.
Here an example for the download endpoint (just the important parts):
#GetMapping("/download/{fileName}")
public ResponseEntity<FileSystemResource> downloadFile(#PathVariable("fileName") String fileName) {
FileSystemResource fileResource= new FileSystemResource(STORAGE_LOCATION + fileName);
if (fileResource.exists()) {
HttpHeaders headers = new HttpHeaders();
headers.setContentDisposition(ContentDisposition.parse("attachment; filename=" + fileName));
headers.setContentLength(fileResource.contentLength());
return new ResponseEntity<>(fileResource, headers, HttpStatus.OK);
} else {
//what to return here
}
}
The MVC part is covered by a custom error controller, taken from some examples I found:
#Controller
public class CustomErrorController implements ErrorController {
#RequestMapping("/error")
public String handleError(HttpServletRequest request) {
Object status = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
if (status != null) {
Integer statusCode = Integer.valueOf(status.toString());
if (statusCode == HttpStatus.FORBIDDEN.value()) {
return "error/403";
} else if (statusCode == HttpStatus.NOT_FOUND.value()) {
return "error/404";
} else if (statusCode == HttpStatus.INTERNAL_SERVER_ERROR.value()) {
return "error/500";
}
}
return "error/default";
}
#Override
public String getErrorPath() {
return "/error";
}
}
I didn't find this yesterday (searched and tried stuff the whole afternoon), but here is the quick and easy solution since spring 5, just:
throw new ResponseStatusException(HttpStatus.NOT_FOUND);

How to send file in a "PUT" method when HTML has no "PUT"?

I have a Controller like this:
#RequestMapping(value = "/user/", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE)
public #ResponseBody UserLesserDTO createUser(#RequestParam("profileImage") MultipartFile file, #RequestBody UserDTO user) {
System.out.println("Creating User " + user.getName() );
try {
UserDTO userTest = userService.getUserByUsername( user.getName() );
return new UserLesserDTO( userTest );
} catch ( NoResultException e ) {
//
}
return new UserLesserDTO( userService.addUser(user) );
}
and a form to create the user.
This form have a input type file named profileImage.
My question is: As I can't send a PUT method in HTML, I MUST send it as an Ajax request converting all form attributes to a JSON object and send it as PUT. But I need to send a file too and I don't know how to proceed.

ModelandView doesnt work

I created registration Controller. Everything works fine, user is create in database but then end service program doesnt go to successRegister view. I dont know why. If I return like String successRegister everything is ok.
#RequestMapping(value = "/add", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
public ModelAndView registerUserAccount(#RequestBody #Valid User accountDto,
BindingResult result, WebRequest request, Errors errors) {
if (result.hasErrors()) {
return new ModelAndView("successRegister", "User", accountDto);
}
User registered = userService.register(accountDto);
if (registered == null) {
result.rejectValue("email", "message.regError");
}
try {
String appUrl = request.getContextPath();
eventPublisher.publishEvent(new OnRegistrationCompleteEvent
(registered, request.getLocale(), appUrl));
} catch (Exception me) {
return new ModelAndView("successRegister", "User", accountDto);
}
return new ModelAndView("successRegister");
}
Problem was with AJAX. I changed location after success and then ModelAndView was not return.
Your problem is with this
produces = MediaType.APPLICATION_JSON_VALUE
You says produces a JSON response but thats not true, you want to return a ModelAndView, so try to remove that attribute

How to get Json Post Values with asp.net webapi

i'm making a request do a asp.net webapi Post Method, and i'm not beeing able to get a request variable.
Request
jQuery.ajax({ url: sURL, type: 'POST', data: {var1:"mytext"}, async: false, dataType: 'json', contentType: 'application/x-www-form-urlencoded; charset=UTF-8' })
.done(function (data) {
...
});
WEB API Fnx
[AcceptVerbs("POST")]
[ActionName("myActionName")]
public void DoSomeStuff([FromBody]dynamic value)
{
//first way
var x = value.var1;
//Second way
var y = Request("var1");
}
i Cannot obtain the var1 content in both ways... (unless i create a class for that)
how should i do that?
First way:
public void Post([FromBody]dynamic value)
{
var x = value.var1.Value; // JToken
}
Note that value.Property actually returns a JToken instance so to get it's value you need to call value.Property.Value.
Second way:
public async Task Post()
{
dynamic obj = await Request.Content.ReadAsAsync<JObject>();
var y = obj.var1;
}
Both of the above work using Fiddler. If the first option isn't working for you, try setting the content type to application/json to ensure that the JsonMediaTypeFormatter is used to deserialize the content.
After banging my head around for a while on this and trying many different things I ended up putting some breakpoints on the API server and found the key value pairs stuffed down in the request. After I knew where they were, it was easy to access them. However, I have only found this method to work with WebClient.UploadString. However, it does work easily enough and allows you to load up as many parameters as you like and very easily access them server side. Note that I am targeting .net 4.5.
CLIENT SIDE
// Client request to POST the parameters and capture the response
public string webClientPostQuery(string user, string pass, string controller)
{
string response = "";
string parameters = "u=" + user + "&p=" + pass; // Add all parameters here.
// POST parameters could also easily be passed as a string through the method.
Uri uri = new Uri("http://localhost:50000/api/" + controller);
// This was written to work for many authorized controllers.
using (WebClient wc = new WebClient())
{
try
{
wc.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
response = wc.UploadString(uri, login);
}
catch (WebException myexp)
{
// Do something with this exception.
// I wrote a specific error handler that runs on the response elsewhere so,
// I just swallow it, not best practice, but I didn't think of a better way
}
}
return response;
}
SERVER SIDE
// In the Controller method which handles the POST request, call this helper:
string someKeyValue = getFormKeyValue("someKey");
// This value can now be used anywhere in the Controller.
// Do note that it could be blank or whitespace.
// This method just gets the first value that matches the key.
// Most key's you are sending only have one value. This checks that assumption.
// More logic could be added to deal with multiple values easily enough.
public string getFormKeyValue(string key)
{
string[] values;
string value = "";
try
{
values = HttpContext.Current.Request.Form.GetValues(key);
if (values.Length >= 1)
value = values[0];
}
catch (Exception exp) { /* do something with this */ }
return value;
}
For more info on how to handle multi-value Request.Form Key/Value pairs, see:
http://msdn.microsoft.com/en-us/library/6c3yckfw(v=vs.110).aspx
I searched all morning to find an answer that depicted both client and server code, then finally figured it out.
Brief intro - The UI is an MVC 4.5 project that implements a standard view. The server side is an MVC 4.5 WebApi. The objective was to POST the model as JSON and subsequently update a database. It was my responsibility to code both the UI and backend. Below is the code. This worked for me.
Model
public class Team
{
public int Ident { get; set; }
public string Tricode { get; set; }
public string TeamName { get; set; }
public string DisplayName { get; set; }
public string Division { get; set; }
public string LogoPath { get; set; }
}
Client Side (UI Controller)
private string UpdateTeam(Team team)
{
dynamic json = JsonConvert.SerializeObject(team);
string uri = #"http://localhost/MyWebApi/api/PlayerChart/PostUpdateTeam";
try
{
WebRequest request = WebRequest.Create(uri);
request.Method = "POST";
request.ContentType = "application/json; charset=utf-8";
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
}
WebResponse response = (HttpWebResponse)request.GetResponse();
using (var streamReader = new StreamReader(response.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
}
}
catch (Exception e)
{
msg = e.Message;
}
}
Server Side (WebApi Controller)
[Route("api/PlayerChart/PostUpdateTeam")]
[HttpPost]
public string PostUpdateTeam(HttpRequestMessage context)
{
var contentResult = context.Content.ReadAsStringAsync();
string result = contentResult.Result;
Team team = JsonConvert.DeserializeObject<Team>(result);
//(proceed and update database)
}
WebApiConfig (route)
config.Routes.MapHttpRoute(
name: "PostUpdateTeam",
routeTemplate: "api/PlayerChart/PostUpdateTeam/{context}",
defaults: new { context = RouteParameter.Optional }
);
Try this.
public string Post(FormDataCollection form) {
string par1 = form.Get("par1");
// ...
}
try using following way
[AcceptVerbs("POST")]
[ActionName("myActionName")]
public static void DoSomeStuff(var value)
{
//first way
var x = value;
}

Resources