I am maintaining a Spring MVC Web apps written in spring 2.5. Now I want to add some enhancement into it but
currently encountering some problem.
I created a select box and set the multiple option to true and disabled it also.
The only way to populate the the select is thru making some ajax call.
<form:select path="dataFiles" multiple="true" disabled="true">
</form:select>
publiv class MyData{
private List<String> dataFiles = new ArrayList<String>();
//getters
//setters
}
After the ajax call returns, I automatically select each options. I dont want user to edit this anymore.
But my problem is, during form submit they dont get binded into my commandbean. Is there any workaround for this?
I tried removing the disabled attribute and everything work well, but my problem is, it violates my requirements.
Any hints about this?
Using InitBinder annotation and CustomerCollection utilty provided by Spring framework.
I would write something like below in my controller.
#InitBinder()
public void initBinder(WebDataBinder binder) throws Exception
{
binder.registerCustomEditor(Collection.class, new CustomCollectionEditor());
}
Refer Spring documentation about binders here
http://static.springsource.org/spring/docs/2.5.x/reference/validation.html#beans-beans-conversion
Related
How can I keep links in my UI templates (e.g. Thymeleaf templates) in sync with the corresponding request mappings in my Spring application?
I've seen that e.g. the Play framework uses the #router-Object within its templates. How is it solved by Spring?
One example:
Spring Controller - simple
#Controller
public class UserController {
#GetMapping("/users/{username}")
public String getUser(#PathParam String username) {
// do some stuff....
return "user";
}
}
HTML-Page
<body>
User details
</body>
Now I want to change "/users" to "/accounts". I'm pretty sure that I've got to update every html page by hand to update the link. Is there an easier solution for this?
As far as I know, there is no simple way to do this with built-in tools from Spring. However, I don't think that this would be too hard to build. You would need the following:
A YAML file with all of your URL templates defined
A Properties Spring bean that contains your URL mappings (read from the YAML file)
All of your #RequestMapping annotations would have to be prop values; i.e.
#GetMapping("${urls.users.byUsername}")
A custom tag that knows about the Properties bean and can create URLs from the templates that were defined in your YAML file.
Since REST based controller methods only return objects ( not views ) to the client based on the request, how can I show view to my user ? Or maybe better question what is a good way to combine spring-mvc web app with REST, so my user always get the answer, not in just ( for example ) JSON format, but also with the view ?
So far as I understood, REST based controller would be perfectly fitting to the mobile app ( for example twitter ), where views are handled inside the app and the only thing server has to worry about is to pass the right object to the right request. But what about the web app ?
I might be wrong in several things ( correct me if I am ), since I am trying to understand REST and I am still learning.
To simplify things - you basically have two options:
1) Build Spring MVC application.
2) Build REST backend application.
In case of first option - within your application you will have both backend and frontend (MVC part).
In case of second option you build only backend application and expose it through REST API. In most cases, you will need to build another application - REST client for your application. This is more flexible application because it gives you opportunity to access your backend application from various clients - for example, you can have Android, IOS applications, you can have web application implemented using Angular etc...
Please note, that thins are not so simple, you can within one application have both REST backend and REST client etc... This is just very very simplified in order that you get some general picture. Hope this clarified a little things.
There is some additional clarification related to REST and views worth learning. From your question, I can see that you mean "view" in a sense of UI(user interface) and typical MVC usage. But "view" can mean different things in a different contexts.
So:
JSON can be considered as a view for data
JSON is a representation of the resource, just like HTML is
JSON doesn't have style (unless you are not using a browser
extension, which most the users are not using)
The browser is recognizing HTML as a markup language and applying a
style to it
Both are media types
Both JSON and HTML are data formats
Both can be transferred over the wire
This method returns a view
#RequestMapping("/home")
String home(Model model) {
return "home"; // resources\templates\home.html
}
This method Returns String
#RequestMapping(value = "/home")
#ResponseBody
public String home() {
return "Success";
}
If you annotate a method with #ResponseBody, Spring will use a json mapper to generate the response. Instead of annotating every method with #ResponseBody you can annotate your class with #RestController.
If you want to return a view, you need to annotate the class with #Controller instead of #RestController and configure a viewresolver. Bij default spring will use thymeleaf as a viewresolver if you have spring-web as a dependency on the classpath. The return type of the method is a String that references the template to be rendered. The templates are stored in src/main/resources/templates.
You can find a guide on the spring website: https://spring.io/guides/gs/serving-web-content/
I am using a spring boot application and have configured using Swagger UI.
I want to know whether we could pre-populate the example value with sample value so we can hit the "Try it out!" button without having to type in some sample values to get a response.
It must be present there.
Is there a way we can do this using annotations or a separate file which Swagger uses?
I am using a spring boot project with springfox-swagger2:2.7.0 and springfox-swagger-ui:2.7.0 with dependencies added using gradle.
Since the #ApiParam properties example and examples are not working (see this issue on GitHub), support for adding examples is limited/non existing.
What you can do for simple parameters (#RequestParam) is to add the #ApiParam annotation with the defaultValue property, like this:
#GetMapping
public List<Foo> findAll(
#RequestParam(required = false)
#ApiParam(defaultValue = "foo") // Put the default value here
String input) {
// ...
}
However, there is no support yet for doing this with #RequestBody parameters.
A possible workaround for #RequestBody parameters is by clicking on the code box at the right side of the Swagger tester, where it says Example value. If you click on it, it will insert that example into the field itself.
Here is a workaround for providing an example:
Inject html into swagger
#ApiParam(
name="whatever",
value="whatever",
defaultValue="none</p><p>Example: xyz</p>"
)
They don't protect against it in the latest version 2.9.2.
I've been looking into using Spring Security for the authentication/authorization of my web application (this will be JDBC based).
However, a core component seems to be left out from my perspective. How do I register/create new users? Is there an out of the box API for that?
Do i need to write user registration and management from scratch?
Things i need to do include:
- Registering a new user
- Resetting passwords
- Emailing a user to activate their account
- Emailing a user to reset their account.
Thank you in advance.
I use Spring Security on my project. The framework does not have an API for user creation or registration as you asked. For Spring Security to be generic and usable across multiple frameworks, it can only take you so far before you have to write custom code. You can't really get a more specific answer about a framework or tool to use because at this point you will just use the frameworks you are already using anyway.
If you've set it up to use users and roles in your database, from your data access layer you would create a record in the user table or update a password (preferably stored as a hash) in that record. And as Aravind said, Spring does provide email support.
If you really want to see one way to do it: I'm using Spring MVC, JSP, and Hibernate. I use Spring's form tags in a JSP to bind a new user form to a Person object, and my controller method passes that Person object to my Dao to persist it.
The controller method signature looks like this...
#RequestMapping(value = "/newUser", method = RequestMethod.POST)
public ModelAndView createNewUser(final #Valid #ModelAttribute Person user,
final BindingResult result,
final SessionStatus status,
final #RequestParam(value = "unencodedPassword", required = true) String password) {
...
user.getRoles().add(new Role(user, Role.APPLICATION_ROLE.ROLE_USER));
userDao.createNewUser(user);
...
}
and my PersonDao would use Hibernate to persist the user like so
#Transactional
public void createNewUser(Person user)
{
Session session = sessionFactory.getCurrentSession();
session.save(user);
session.flush();
}
Have a look at my answer here.
"I have implemented a JAVA project for this use case. It is open
source, based on Spring-Security. A release version is on
Maven-Central, so you do not need to compile it, but instead you can
fetch it as maven-dependency to your project!"
<dependency>
<groupId>com.ohadr</groupId>
<artifactId>authentication-flows</artifactId>
<version>1.5.0-RELEASE</version>
</dependency>
As far as I know, Spring Security does not have built in support for new user creation and registration. You will have to manage this yourself. However it does have emailing support. Check here for more on this.
I have a JIRA plugin that I'm developing that has a REST service. That service should be able to accept POSTed requests, unmarshall some data and store it. The seemingly suggested way to do this in JIRA is to make use of the Bandana persistence framework. According to this page, I should be able to simply define a setter that Spring should call to give me my Bandana manager.
#Path("/path")
public class SCMService {
private BandanaManager bandanaManager;
// setter called by Spring
public void setBandanaManager(BandanaManager bandanaManager) {
this.bandanaManager = bandanaManager;
}
//...More methods...
}
However, when I test this, the setter is never being called and my manager is null. I'm guessing this should be as simple as registering this service with Spring for injection somehow but I can't seem to find anything like that.
How would I get my setter called? Is there a better way to do this?
Er, I'm not sure that JIRA uses Bandana in that way, though Confluence does. You can certainly post data to a JIRA rest resource and then store it using properties tables
Something like this:
#POST
#Consumes (MediaType.APPLICATION_XML)
public Response createComponentAndIssues(#Context HttpServletRequest request, ...