I have faced with a problem that I can't get my object on server side.
I am getting this error:
128870 [http-apr-8080-exec-1] WARN org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver - Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing: public com.webserverconfig.user.entity.User com.webserverconfig.user.controller.UserController.login(com.webserverconfig.user.entity.User)
I am trying to send object on server side using GET request. I want to use this object just to verify fields on it. (I am doing simple user login method and i want to check userName and userPassword).
Here is my code on server side:
Request:
#RequestMapping(value = "/login", method = RequestMethod.GET)
#ResponseStatus(value = HttpStatus.ACCEPTED)
public User login(#RequestBody User user) {
userValidator.validateUserLogin(user);
securityService.autoLogin(user.getUserName(), user.getUserPassword());
return user;
}
Entity user:
#Entity
#Table(name = "Users")
public class User {
public User() {
}
#Id
#GeneratedValue(generator = "increment")
#GenericGenerator(name = "increment", strategy = "increment")
#Column(name = "Id", unique = true, nullable = false)
private long id;
#Column(name = "userName", nullable = false)
private String userName;
#Column(name = "userPassword", nullable = false)
private String userPassword;
#Transient
private String confirmPassword;
public long getId() {
return id;
}
public String getUserName() {
return userName;
}
public String getUserPassword() {
return userPassword;
}
public String getConfirmPassword() {
return confirmPassword;
}
public void setId(long id) {
this.id = id;
}
public void setUserName(String userName) {
this.userName = userName;
}
public void setUserPassword(String userPassword) {
this.userPassword = userPassword;
}
public void setConfirmPassword(String confirmPassword) {
this.confirmPassword = confirmPassword;
}
}
Client side code:
private class LoginUserTask extends AsyncTask<Void, Void, User> {
#Override
protected User doInBackground(Void... voids) {
restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
User user = new User(userName, userPassword);
return restTemplate.getForObject(URL.getUserLogin(), User.class, user);
}
#Override
protected void onPostExecute(User user) {
responseEntity = restTemplate.getForEntity(URL.getUserLogin(), String.class);
HttpStatus responseStatus = responseEntity.getStatusCode();
if(responseStatus.equals(HttpStatus.ACCEPTED)){
view.makeToast("User login completed " + user.getUserName());
} else {
view.makeToast("User login or password is not correct");
}
}
}
Am I missing something? Can anybody help with this please ?
You have set a #RequestBody annotation with a User object as an input parameter.
In this case, you have to use POST method along with a User object in the body of the request.
Related
I have two entities: UserEntity and LoginEntity and crudrepositories for each. The entities have a relationship of OneToOne where one user will have one login account. I also created a controller and I can get all the data from the database i.e when call getalluser I get all users with their relationship to login. and when I call getAllLogins I get all logins accounts. I also managed to insert the user and the login using API each individually and it's working fine but this will omit the foreign-key user_id.
Now since am knew am stack on how to insert the user and login each respectively with their relationships through one json body
#Entity#Table(name="user_table")public class UserEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long uid;
private String fname;
private String lname;
#OneToOne( cascade = CascadeType.ALL, mappedBy = "userEntityFk")
private LoginEntity logins;
public UserEntity() {
super();
}
public Long getUid() {
return uid;
}
public void setUid(Long uid) {
this.uid = uid;
}
public String getFname() {
return fname;
}
public void setFname(String fname) {
this.fname = fname;
}
public String getLname() {
return lname;
}
public void setLname(String lname) {
this.lname = lname;
}
public LoginEntity getLogins() {
return logins;
}
public void setLogins(LoginEntity logins) {
this.logins = logins;
}
public UserEntity(Long uid, String fname, String lname, LoginEntity logins) {
super();
this.uid = uid;
this.fname = fname;
this.lname = lname;
this.logins = logins;
}
#Entity #Table(name="login_table") public class LoginEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long lid;
private String username;
private String password;
#OneToOne(cascade = CascadeType.ALL )
private UserEntity userEntityFk;
public LoginEntity() {
super();
}
public LoginEntity(Long lid, String username, String password, UserEntity userEntityFk) {
super();
this.lid = lid;
this.username = username;
this.password = password;
this.userEntityFk = userEntityFk;
}
public Long getLid() {
return lid;
}
public void setLid(Long lid) {
this.lid = lid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public UserEntity getUserEntityFk() {
return userEntityFk;
}
public void setUserEntityFk(UserEntity userEntityFk) {
this.userEntityFk = userEntityFk;
}
}
#Repository
public interface LoginRepo extends CrudRepository<LoginEntity, Integer> {
}
#Repository
public interface UserRepo extends CrudRepository<UserEntity, Integer> {
}
#RestController
#RequestMapping(path="/api")
public class MainController {
#Autowired
private UserRepo userRepository;
#Autowired
private LoginRepo loginRepository;
//===this works fine i can get all the users after insert
#GetMapping(path="/user_acc")
public #ResponseBody Iterable<UserEntity> getAllUsers() {
// This returns a JSON or XML with the users
return userRepository.findAll();
}
//================this too works fine after insert
#GetMapping(path="/login_acc")
public #ResponseBody Iterable<LoginEntity> getAlllogins() {
// This returns a JSON or XML with the users
return loginRepository.findAll();
}
//===adding single user works fine. and it returns user_id
#PostMapping("/user_acc")
public Long addNewUser(#RequestBody UserEntity userz){
UserEntity ue = userRepository.save(userz);
return ue.getUid();
}
//===this works but the foreign key not inserted and thats where my problem is
#PostMapping("/login_acc")
public LoginEntity addNewLogin(#RequestBody LoginEntity loginz){
return loginRepository.save(loginz);
}
}
class UserLogin{
UserEntity myuser;
LoginEntity mylogin;
public UserEntity getMyuser() {
return myuser;
}
public void setMyuser(UserEntity myuser) {
this.myuser = myuser;
}
public LoginEntity getMylogin() {
return mylogin;
}
public void setMylogin(LoginEntity mylogin) {
this.mylogin = mylogin;
}
}
result on post http://localhost:8080/api/login_acc. account created but no foreign key
result on post http://localhost:8080/api/login_acc. account created but no foreign key
{
"lid": 1,
"username": "admin1",
"password": "11111",
"userEntityFk": null
}
result on geting all users on get method http://localhost:8080/api/user_acc
{
"uid": 1,
"fname": "hassan",
"lname": "zahor",
"logins": null
}
what i want to post is this body below to multiple tables
{
"fname":"hassan",
"lname":"zahor",
"username": "admin5",
"password": "55555"
}
This one should works better :
{
"fname":"hassan",
"lname":"zahor",
"userEntityFk" : {
"username": "admin5",
"password": "55555"
}
}
However, you will get an error if your endpoint returns an object that contains a loop inclusion : spring will try to map it into json indefinitely.
You can correct this issue to map your result into another object before returning it from your controller, or just remove the property "logins" from UserEntity.
Controller:
#RestController
#RequestMapping(path = "api/v1/users")
public class UserController {
#Autowired
UserService userService;
#PostMapping("/register")
public ResponseEntity<Map<String, String>> registerUser(#RequestBody Map<String, Object> userMap){
Map<String, String> map = new HashMap<>();
try {
String first_name = (String) userMap.get("first_name");
String last_name = (String) userMap.get("last_name");
Users user = userService.registerUser(first_name, last_name);
map.put("message:","User registered successfully");
}catch(Exception e) {
map.put("message:",e.getMessage());
return new ResponseEntity<>(map, HttpStatus.UNAUTHORIZED);
}
return new ResponseEntity<>(map, HttpStatus.OK);
}
}
Service Layer:
#Service
#Transactional
public class UserServicesImpl implements UserService{
#Autowired
UserRepository userRepository;
#Override
public Users registerUser(String first_name, String last_name) throws EtAuthException {
String username = first_name+99;
Integer userId = userRepository.create(first_namea, last_name);
return userRepository.findById(userId);
}
}
Repository:
#Repository
public class UserRepositoryImpl implements UserRepository {
private final UserRepositoryBasic userRepositoryBasic;
public UserRepositoryImpl(UserRepositoryBasic userRepositoryBasic) {
this.userRepositoryBasic = userRepositoryBasic;
}
#Override
public Integer create(String first_name, String last_name) throws EtAuthException {
try{
Users insertData = userRepositoryBasic.save(new Users(first_name, last_name));
return insertData.getId();
}catch (Exception e){
throw new EtAuthException(e.getMessage());
}
}
}
Model/Entity:
#Entity
#Table(name="users")
public class Users {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", updatable = false, nullable = false)
private Integer id;
#NotBlank(message="First name can not be empty")
#Column(nullable = false, length = 40)
private String first_name;
#NotBlank(message="Last name can not be empty")
#Column(nullable = false, length = 40)
private String last_name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getFirst_name() {
return first_name;
}
public void setFirst_name(String first_name) {
this.first_name = first_name;
}
public String getLast_name() {
return last_name;
}
public void setLast_name(String last_name) {
this.last_name = last_name;
}
public Users(String first_name, String last_name) {
this.first_name = first_name;
this.last_name = last_name;
}
public Users() {
}
}
The response I am getting is:
I want to do the validation at Service Layer but unable to do so. Validation works for my code implementation but the problem is that the validation message is shown with the package and class names which I do not want to show. I am trying to get only the validation error message if validation fail.
I tried adding #Valid annotation but unable to get the response I am looking for.
I am looking for a response below if validation fails.
"message": ["First name can not be empty","Last name can not be empty"]
Can anyone help me out with this problem. Thank you in advance.
Add a global exception handler to parse your error and return error message in the format you need.
#ExceptionHandler({ ConstraintViolationException.class })
public ResponseEntity<Object> handleConstraintViolation(
ConstraintViolationException ex, WebRequest request) {
List<String> errors = new ArrayList<String>();
for (ConstraintViolation<?> violation : ex.getConstraintViolations()) {
errors.add(violation.getRootBeanClass().getName() + " " +
violation.getPropertyPath() + ": " + violation.getMessage());
}
ApiError apiError =
new ApiError(HttpStatus.BAD_REQUEST, ex.getLocalizedMessage(), errors);
return new ResponseEntity<Object>(
apiError, new HttpHeaders(), apiError.getStatus());
}
Source
You must to change your userMap object for your validated User class in your controller:
public ResponseEntity<Users> registerUser(#RequestBody #Valid Users){
Users createdUser = userService.registerUser(user.firstName, user.lastName);
return ResponseEntity.ok().body(createdUser).build();
}
This should returns the error messages for not valid fields only in a JSON structure.
A good practice is the use of DTOs instead Entities clases for Controllers requests and responses, you can read more about that here:
https://www.amitph.com/spring-entity-to-dto/
In this way you can choose those fields from your Entities that you want to show.
For some strange reason a field of my entity has been changed to NULL in my resource.
User Entity
The User entity contains: userName, firstName, lastName, email. The JerseyTest instantiates a new User object:
newUser = new User();
newUser.setEmail(getEmail());
newUser.setFirstName("Erwin");
newUser.setLastName("Eberhard");
newUser.setUserName("abc");
Send entity in test
Before sending the data, the log in the test tells me:
[main] INFO feature.AccountStepDefinition - Erwin Eberhard erwin
erwineberhard#gmail.com
Everthing seems to be OK, so the test sends the data to the resource:
logger.info(newUser.toString());
responseUser = target("auth/register").request().post(Entity.json(newUser), User.class);
AccountResource
The AccountResource retrieves the user, and the log tells us:
[qtp1533672820-20] INFO nl.bolt.ffinschrijven.controllers.AccountsController
- Erwin Eberhard null erwineberhard#gmail.com
For some reason the username has been changed in NULL.
Method in AccountResource
#POST
#Path("/register")
#ApiOperation(value = "Register user.", notes = "After registration a JWT token has been added as header value.")
#ApiResponse(code = 200, message = "", response = User.class, responseHeaders = #ResponseHeader(name = "X-FFI-AUTH", description = "Token generated after authentication", response = String.class) )
#Consumes("application/json")
public Response callback(User user) {
logger.info(user.toString());
ServiceResult serviceResult = accountService.register(user);
if (serviceResult.serviceState == ServiceState.success) {
String jwt = "Bearer " + JwtHelper.createJWT(UUID.randomUUID().toString(), ApiConfiguration.issuer,
user.getEmail(), Long.valueOf(ApiConfiguration.token_ttl));
return Response.status(201).entity(serviceResult.content).header("Authorization", jwt).build();
}
if (serviceResult.serviceState == ServiceState.invalid) {
return Response.status(400).entity(serviceResult.responseMessages.toString()).build();
}
return Response.status(500).build();
}
Postman
When I send the data with POSTMAN, there is no problem:
Headers
Content-Type application/json
Raw content
{
"firstName": "Erwin",
"lastName" : "Eberhard",
"email" : "erwin#gmail.com",
"userName": "erwineberhard"
}
How to get the beloved 201 with my JerseyTest?
UPDATE 1
User.class
The User class extends from a generic User class:
#Entity
#Table
public class User extends GenericUser {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private Long id;
#OneToMany(mappedBy="user", cascade=CascadeType.ALL)
private List<Eventcomponent> eventcomponents =
new ArrayList<Eventcomponent>();
public Long getId() {
return id;
}
#Override
public String toString(){
return this.getFirstName() + " " + this.getLastName() + " " + this.getUserName()
+ " " + this.getEmail();
}
}
GenericUser.class
#MappedSuperclass
public abstract class GenericUser implements IEmail{
#NotNull(message="Gebruikersnaam niet meegegeven.")
#Column(name="userName", nullable = false)
protected String userName;
#NotNull(message="Email niet meegegeven.")
#Column(name="email", nullable = false)
protected String email;
#NotNull(message="Voornaam niet meegegeven.")
#Column(name="firstName", nullable = false)
protected String firstName;
#NotNull(message="Achternaam niet meegegeven.")
#Column(name="lastName", nullable = false)
protected String lastName;
#Column(name="locked", nullable = false)
protected Boolean locked;
protected String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Boolean getLocked() {
return locked;
}
public void setLocked(Boolean locked) {
this.locked = locked;
}
}
Looks like the protected getUserName() is the problem. The serializer can't find the userName property when serializing, so there is no field in the JSON of that property name, when it goes out. When the server gets the JSON there is no "userName" field, so it stays null in the server side object. To fix it, just make the method public.
I'm getting json response from my controller even though I added the xml annotations to my model. I get the list of users in json with no problems. Can I use #Entity and #XmlRootElement in the same class?
User.java
#Entity
#Table(name = "usr")
#XmlRootElement
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "ID", nullable = false, unique = true, length = 11)
private int id;
#Column(nullable = false)
private String username;
#Column(nullable = false)
private String password;
#Column(nullable = false)
private String firstName;
#Column(nullable = false)
private String lastName;
#Column(nullable = false)
private String email;
#OneToMany(mappedBy = "user")
private List<Post> post;
#OneToMany(mappedBy = "user")
private List<Friend> friends;
public List<Friend> getFriends() {
return friends;
}
public void setFriends(List<Friend> friends) {
this.friends = friends;
}
public List<Post> getPost() {
return post;
}
public void setPost(List<Post> post) {
this.post = post;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#XmlElement
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
#XmlElement
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
#XmlElement
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
#XmlElement
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
getAllUsers
#Override
public List<User> getAllUsers() {
List<User> users = new ArrayList<User>();
Session session = HibernateUtil.getSessionAnnotationFactory().openSession();
Transaction trns = null;
try {
trns = session.beginTransaction();
users = session.createQuery("select firstName, lastName, email, username as name from User").list();
trns.commit();
} catch (RuntimeException e) {
if (trns != null) {
trns.rollback();
}
e.printStackTrace();
} finally {
session.flush();
session.close();
}
return users;
}
and in the controller
#RequestMapping(value="/api/users", method = RequestMethod.GET)
public List<User> getAllUsers() {
//List<User> users = new ArrayList<User>();
UserDao userdao = new UserDaoImpl();
List<User> users = userdao.getAllUsers();
return users;
}
What am I missing here?
There is a nice blog entry from Spring about this. From there is this about content negotiation:
Enabling Content Negotiation in Spring MVC
Spring supports a couple of conventions for selecting the format
required: URL suffixes and/or a URL parameter. These work alongside
the use of Accept headers. As a result, the content-type can be
requested in any of three ways. By default they are checked in this
order:
Add a path extension (suffix) in the URL. So, if the incoming URL is
something like http://myserver/myapp/accounts/list.html then HTML is
required. For a spreadsheet the URL should be
http://myserver/myapp/accounts/list.xls. The suffix to media-type
mapping is automatically defined via the JavaBeans Activation
Framework or JAF (so activation.jar must be on the class path).
A URL parameter like this: http://myserver/myapp/accounts/list?format=xls.
The name of the parameter is format by default, but this may be
changed. Using a parameter is disabled by default, but when enabled,
it is checked second.
Finally the Accept HTTP header property is
checked. This is how HTTP is actually defined to work, but, as
previously mentioned, it can be problematic to use.
But if you just want to fix the return type I'd add the annotation #RequestMapping(value="/api/users", produces={"application/xml"}) to your controller method.
First, try to change
#RequestMapping(value="/api/users", method = RequestMethod.GET)
to
#ResponseBody
#RequestMapping(value="/api/users", method = RequestMethod.GET, produces = MediaType.APPLICATION_XML_VALUE)
Second, check out if client code ( I assume it is javascript ) is sending correct accept-type, because Jackson - the default serialization engine would derive format of response body from HTTP header.
Third, ensure that you have JAXB present in your classpath.
I'm trying to add a global form to where a user can post. I get that error for some reason, been working on this for a while, it must be something with my controller but not sure
in home.jsp
<form:form modelAttribute= "tweets">
<form:input path="tweet" />
<input id="user" name="user" type="hidden" value="${user}"/>
<input type="submit" value="send" />
</form:form>
in TweetsController
public class TweetsController {
private TweetsService tweetsService;
#ModelAttribute("tweets")
// name for tweet form in home public Tweets
public Tweets construct() {
return new Tweets();
}
// //----------------------------------------------------------------------
#RequestMapping(value = "/")
public String newTweet(Model model) {
model.addAttribute("tweets", new Tweets());
return "/home";
}
#RequestMapping(method = RequestMethod.GET)
public String tweet(Model model) throws MessagingException {
// key value - attribute and the value of the attribute
// if key isn't passed, it will default to camelCased class name
model.addAttribute("tweets", new CreateTweet());
return "home";
}
#RequestMapping(method = RequestMethod.POST)
public String tweet(#ModelAttribute("tweets") CreateTweet tweet, BindingResult result,
RedirectAttributes redirectAttributes) {
if (result.hasErrors()) {
return "redirect:/";
}
tweetsService.createTweet(tweet);
return "redirect:/";
}
}
TweetsServiceImpl
#Service
#Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public class TweetsServiceImpl implements TweetsService {
private TweetsRepository tweetsRepo;
#Autowired
private UserRepository userRepo;
#Autowired
public TweetsServiceImpl(UserRepository userRepo, TweetsRepository tweetsRepo) {
this.userRepo = userRepo;
this.tweetsRepo = tweetsRepo;
}
public TweetsRepository getTweetsRepo() {
return tweetsRepo;
}
public void setTweetsRepo(TweetsRepository tweetsRepo) {
this.tweetsRepo = tweetsRepo;
}
public UserRepository getUserRepo() {
return userRepo;
}
public void setUserRepo(UserRepository userRepo) {
this.userRepo = userRepo;
}
public List<Tweets> findAll() {
return tweetsRepo.findAll();
}
#Override
#Transactional(propagation = Propagation.REQUIRED, readOnly = false)
public void createTweet(CreateTweet createTweet) {
Tweets tweet = new Tweets();
tweet.setTweet(createTweet.getTweet());
tweet.setUser(createTweet.getUser());
tweetsRepo.save(tweet);
}
}
CreateTweet
public class CreateTweet {
#NotNull
#Size(min=1, max=500)
private String tweet;
#NotNull
private User user;
public String getTweet() {
return tweet;
}
public void setTweet(String tweet) {
this.tweet = tweet;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
User class
#Entity
#Table(name = "usr", indexes = { #Index(columnList = "email", unique = true) })
// using usr because in may conflict with the name of the class
public class User {
public static final int EMAIL_MAX = 250;
public static final int NAME_MAX = 50;
/*
* public static enum Role {
*
* UNVERIFIED, BLOCKED, ADMINISTRATOR
*
* }
*/
// primary key long, needs to be annotated with #Id
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
// add columns
#Column(nullable = false, length = EMAIL_MAX)
private String email;
#Column(nullable = false, length = NAME_MAX)
private String name;
// no length, the password will be encrypted to some longer value than the
// user enters
#Column(nullable = false)
private String password;
#OneToMany(mappedBy="user")
List<Tweets> tweets;
public List<Tweets> getTweets() {
return tweets;
}
public void setTweets(List<Tweets> tweets) {
this.tweets = tweets;
}
public void setUsername(String username) {
this.username = username;
}
#Column(nullable = false)
private String username;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public boolean isEditable() {
User loggedIn = MyTools.getSessionUser();
if (loggedIn == null) {
return false;
}
return loggedIn.getId() == id;
}
public String getUsername() {
return username;
}
}
How can I get the form to show on the page and users can post?
Your TweetsController has mistakes. The way you wroted it your #ModelAttribute construct method will be called before every request, always making a new instance.
To fix this, you should annotate your controller with #SessionAttributes("tweets"). This way when your construct method is called it will store the model attribute in the model but also in the session store as well. Also, whenever the "tweets" model attribute is accessed it will be looked up in the session. For this reason your construct method will be called only initially.
#SessionAttributes("tweets") will also ensure that the model variable always exists in the request and your error will be resolved.
A confusing bit is that sometimes you store a class Tweets and sometimes CreateTweet as a "tweets" model attribute. Anyways, the following controller should work for you
#SessionAttributes("tweets")
public class TweetsController {
private TweetsService tweetsService;
#ModelAttribute("tweets")
// name for tweet form in home public Tweets
public Tweets construct() {
return new Tweets();
}
// //----------------------------------------------------------------------
#RequestMapping(value = "/")
public String newTweet(Model model) {
model.addAttribute("tweets", new CreateTweet());
return "/home";
}
#RequestMapping(method = RequestMethod.POST)
public String tweet(#ModelAttribute("tweets") CreateTweet tweet, BindingResult result,
RedirectAttributes redirectAttributes) {
if (result.hasErrors()) {
return "redirect:/";
}
tweetsService.createTweet(tweet);
return "redirect:/";
}
}