Can I insert some includes in a spring mvc controller to point to various html files to assemble them as one page, kind of like (for example):
#RequestMapping(value = QUESTION_GROUP_CREATE_URL, method = RequestMethod.POST)
public
#ResponseBody
String createQuestionGroup(#RequestBody JsonQuestionGroup questionGroup, HttpServletResponse response) {
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
return "<div></div>";
}
but where I'm returning "<div></div>" can I use includes to link to head.html, header.html, nav.html, view.html, footer.html? Example?
Thank you!
You can use apache tiles instead of that ,It is very easy You can find many tutorial in web this is an example
http://www.codingpedia.org/ama/spring-mvc-and-apache-tiles-integration-example/
another one
https://bikashshaw.wordpress.com/2013/05/13/spring-mvc-create-jspjstl-composite-view-header-body-and-footer/
Related
I am building a URL Shorter app (like Bitly). It is an SPA using Spring Boot & ReactJS. All web content is served off of index.html. All other routes are presumed to be shortLink redirect requests which should trigger a clickShortUrl() function to fetch the corresponding originalLink and redirect the user to that web address.
Therefore, I want the following routes to redirect to index.html:
#GetMapping(value = {"/", "/home", "/dashboard"})
public String redirect() {
return "forward:/index.html";
}
and all other/unknown routes to trigger a wildcard function:
#RequestMapping(value = "/{shortUrl}", method = RequestMethod.GET)
public Object clickShortUrl(#PathVariable("shortUrl") String shortUrl, #RequestBody ClickDTO request) {
// internalLogicHere
};
Individually, the mappings and functions are working. But combined, the /{shortUrl} wildcard route always takes precedence. I've googled around looking for ways to override this behavior. It seems to be possible a few ways, but all of my attempts have failed.
I read several posts like this suggesting to extend WebMvcConfigurerAdapter and override addViewControllers(ViewControllerRegistry registry) to define view controllers for specific routes. I don't really understand this. Is this the right path? If so, can someone help me understand what ViewControllerRegistry is all about and set me on the right path?
Thank you!
Answered my own question. Ended up using RegEx in the wildcard route to exclude the static paths used on the front end.
/** Redirect all '/' and '/dashboard/ requests to index.html. */
#GetMapping(value = {"path:/", "path:/dashboard"})
public String redirect() {
return "forward:/index.html";
}
and the fallback route:
/**
* Treat all routes as /{shortUrl} clicks except: '/', '/index.html, '/dashboard''
*/
#RequestMapping(value = "{_:^(?!index\\.html|dashboard).*$}")
public Object clickShortUrl(#PathVariable("shortUrl") String shortUrl, #RequestBody ClickDTO request) {
// internalLogicHere;
}
First of all, I know that there are similar questions regarding "Preserving model state with Post/Redirect/Get pattern", but none of these have my very specific problem:
background:
My Code is working in an enterprise CMS software which does a lot of things. One of them is URL rewriting: Whenever I generate Links to my controller, dependending on the environment, the links are shortened - That's a SEO thing and can't be discussed.
I.e. if my Controller URL is /webapp/servlet/myController/doSomething, the generated URL will be /myController/doSomething. There's some LinkProcessing functionality that we have to use.
An apache rewrite rule will then expand this short url to /webapp/servlet/myController/doSomething when the apache uses mod_rewrite to call the corresponsing code on the tomcat:
RewriteCond %{REQUEST_URI} ^/myController/(.*)
RewriteRule ^/myController/(.*) /webapp/servlet/myController/$1 [PT,L]
Problem:
I'm trying to implement the Post/Redirect/Get pattern using Spring 3.1.2. I'm generating a form and POST it to the Controller, which validated and makes a redirect to either the success or error page using GET (Post/Redirect/Get pattern).
(highly simplified) Code:
#RequestMapping()
public class MyController {
#RequestMapping(value = "/doDispatch", method = RequestMethod.POST)
public RedirectView handleDispatch(RedirectAttributes redirectAttributes,
#Validated #ModelAttribute FormBean formBean,
BindingResult binding) {
if (binding.hasErrors()) {
redirectAttributes.addFlashAttribute(formBean);
redirectAttributes.addFlashAttribute(BindingResult.MODEL_KEY_PREFIX+"formBean", binding);
return new RedirectView(generateLink("/error"));
} else {
redirectAttributes.addFlashAttribute(formBean);
redirectAttributes.addFlashAttribute(BindingResult.MODEL_KEY_PREFIX+"formBean", binding);
return new RedirectView(generateLink("/success"));
}
}
#RequestMapping(value = "/success")
public ModelAndView handleSuccess(#ModelAttribute FormBean formBean) {
// do stuff (save things in the DB)
// ...
final ModelAndView modelAndView = createModelAndView(formBean);
modelAndView.addObject("success", true);
return modelAndView;
}
#RequestMapping(value = "/error")
public ModelAndView handleError(#Validated #ModelAttribute FormBean formBean,
BindingResult binding) {
final ModelAndView modelAndView = createModelAndView(formBean);
modelAndView.addObject("binding", binding);
modelAndView.addObject("formBean", formBean);
return modelAndView;
}
}
The problem ist that this generateLink() method will either generate links starting with /webapp/servlet or not - depending on the environment/success. And that's how this whole Enterprice CMS thing works. (that's the part which cannot be discussed)
Spring Flash-Attributes on the other hand work hand in hand with the URLs that are returned and store the URL as part of the FlashMap:
Quote from http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-flash-attributes :
To reduce the possibility of such issues, RedirectView automatically "stamps" FlashMap instances with the path and query parameters of the target redirect URL. In turn the default FlashMapManager matches that information to incoming requests when looking up the "input" FlashMap.
Since the next request (let's say I've had an error and returned "/myController/error") will be expanded to /webapp/servlet/myController/error, the FlashMap will not apply to this request, since the URLs do not match.
The code that is responsible is this here (AbstractFlashMapManager.java:157 ff):
protected boolean isFlashMapForRequest(FlashMap flashMap, HttpServletRequest request) {
if (flashMap.getTargetRequestPath() != null) {
String requestUri = this.urlPathHelper.getOriginatingRequestUri(request);
if (!requestUri.equals(flashMap.getTargetRequestPath())
&& !requestUri.equals(flashMap.getTargetRequestPath() + "/")) {
return false;
}
}
// ...
}
Question:
Do you know a way how I can still generate short URLs on the one hand, but pass the FlashAttributes to the following GET request?
Best regards and thanks for your help in advance,
Alexander
The best solution I've found so far is using an Interceptor that updates the targetRequestPath by prefixing /<webappPath>/<servletPath> to those FlashMaps from RequestContextUtils.getOutputFlashMap(request) that are missing this information. BTW: this can only be done in the afterCompletion method, because otherwise the targetRequestPath won't be set at all, when using a RedirectView.
Any other, better solutions?
Im new to java based web service development.
I need to create a web service which accepts multipart data(ex: zip file).
Please help me out how to mention that in the function.
below is my current web service code which is accepting data in the form of json.
#RequestMapping(value="/workitems/updateData", method=RequestMethod.POST)
#ResponseBody
public Object updateData(#RequestHeader String deviceToken, #RequestBody FormFields[]
formFields,HttpServletResponse response) throws Exception {
//some code
}
please guide me to how to accept the multipart data in the web service method.
thanks in advance.
#RequestMapping(
value ="/workitems/updateData",method=RequestMethod.POST ,headers="Accept=application/xml, application/json")
public #ResponseBody
Object updateData(HttpServletResponse response,#RequestHeader String deviceToken,
#RequestParam ("file") MultipartFile file) throws Exception {
}
You can support it as above.
You can use normal Upload technique which you use in Servlet - commons-fileupload.jar way.
The same code placed in a method inside your controller will work fine. Make sure you pass HttpServletRequest object to your method.
I have a spring action that I am rendering some json from the controller, at the minute its returning the content type 'text/plain;charset=ISO-8859-1'.
How can I change this to be 'application/json'?
Pass the HttpServletResponse to your action method and set the content type there:
public String yourAction(HttpServletResponse response) {
response.setContentType("application/json");
}
Did you try using the MappingJacksonJsonView?
Spring-MVC View that renders JSON content by serializing the model for the current request using Jackson's ObjectMapper.
It sets the content-type to: application/json.
#RequestMapping(value = "jsonDemoDude", method = RequestMethod.GET)
public void getCssForElasticSearchConfiguration(HttpServletResponse response) throws IOException {
String jsonContent= ...;
HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper(response);
wrapper.setContentType("application/json;charset=UTF-8");
wrapper.setHeader("Content-length", "" + jsonContent.getBytes().length);
response.getWriter().print(jsonContent);
}
You can also add the aditional X bytes or whatever for "callback" part in case you want JSONP ( cross site json request ) .
Yes, but this only works if one is grabbing the HttpServletResponse in the controller.
In Spring 3 we're being encouraged to avoid references to anything in the servlet domain, keeping things solely to our POJOs and annotations. Is there a way to do this without referencing the HttpServletResponse? I.e., keeping ourselves pure?
I'd like to use memcached to cache the response produced by my controllers. The controllers themselves are Grails controllers, but there's nothing really Grails-specific about the problem. If I could figure out how to solve this problem in a Spring MVC, Struts (or similar) application, I should easily be able to migrate the solution to Grails.
Ideally, I'd like to identify the controller methods that are eligible for caching using Java annotations. Is anyone aware of an existing solution for this problem? I should emphasise that I'm not interested in using any caching technology other than memcached.
Thanks,
Don
The Simple Spring Memcached library the previous poster linked to would actually accomplish what you need to do. It doesn't limit itself to just DAO methods. You could annotate a controller method to cache it's response just as easily as annotating a DAO method.
So, if you have a Controller named SimpleController and you wanted to cache the response of that controller, you could do the following
public class SimpleController implements Controller {
#ReadThroughSingleCache(namespace = "SimpleController", keyIndex = 0, expiration = 3600)
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) {
return new ModelAndView("index")
}
This will cache the response of the controller in Memcached for an hour and any request that comes in that matches the same request will return the cached response.
Aaron, braveterry,
Thanks for suggesting my project: http://code.google.com/p/simple-spring-memcached/
Don, Aaron is correct that SSM is not limited to DAO methods, however there are a few caveats for his example:
I don't think HttpServletRequest's toString() method would produce a good key
You would need to make sure that ModelAndView is Serializable
That being said, there's no reason you can't delegate to another bean that has an appropriate signature
Here's some code as an example:
public class SimpleController implements Controller {
private BeanWithAnnotatedMethod bean; // Injected resource
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) {
Object keyObject = Helper.generateAppropriateKey(request);
String result = bean.annotatedMethod(keyObject);
return new ModelAndView(result)
}
Would something like this do the trick? http://code.google.com/p/simple-spring-memcached/